diff --git a/contrib/db_pools/lib/src/database.rs b/contrib/db_pools/lib/src/database.rs index fc7ec870..4afbd1f3 100644 --- a/contrib/db_pools/lib/src/database.rs +++ b/contrib/db_pools/lib/src/database.rs @@ -122,10 +122,10 @@ pub trait Database: From + DerefMut + Send + Sy return Some(db); } - let dbtype = std::any::type_name::(); - let fairing = Paint::default(format!("{}::init()", dbtype)).bold(); - error!("Attempted to fetch unattached database `{}`.", Paint::default(dbtype).bold()); - info_!("`{}` fairing must be attached prior to using this database.", fairing); + let dbtype = std::any::type_name::().bold().primary(); + error!("Attempted to fetch unattached database `{}`.", dbtype); + info_!("`{}{}` fairing must be attached prior to using this database.", + dbtype.linger(), "::init()".clear()); None } } diff --git a/contrib/dyn_templates/src/fairing.rs b/contrib/dyn_templates/src/fairing.rs index 08e1c768..8d10fec1 100644 --- a/contrib/dyn_templates/src/fairing.rs +++ b/contrib/dyn_templates/src/fairing.rs @@ -59,9 +59,9 @@ impl Fairing for TemplateFairing { let cm = rocket.state::() .expect("Template ContextManager registered in on_ignite"); - info!("{}{}:", Paint::emoji("📐 "), Paint::magenta("Templating")); - info_!("directory: {}", Paint::white(Source::from(&*cm.context().root))); - info_!("engines: {:?}", Paint::white(Engines::ENABLED_EXTENSIONS)); + info!("{}{}:", "📐 ".emoji(), "Templating".magenta()); + info_!("directory: {}", Source::from(&*cm.context().root).primary()); + info_!("engines: {:?}", Engines::ENABLED_EXTENSIONS.primary()); } #[cfg(debug_assertions)] diff --git a/contrib/dyn_templates/src/lib.rs b/contrib/dyn_templates/src/lib.rs index 4f25e5c9..8ae1040a 100644 --- a/contrib/dyn_templates/src/lib.rs +++ b/contrib/dyn_templates/src/lib.rs @@ -181,6 +181,7 @@ use rocket::response::{self, Responder}; use rocket::http::{ContentType, Status}; use rocket::figment::{value::Value, error::Error}; use rocket::serde::Serialize; +use rocket::yansi::Paint; const DEFAULT_TEMPLATE_DIR: &str = "templates"; @@ -441,8 +442,8 @@ impl<'r> Responder<'r, 'static> for Template { impl Sentinel for Template { fn abort(rocket: &Rocket) -> bool { if rocket.state::().is_none() { - let template = rocket::yansi::Paint::default("Template").bold(); - let fairing = rocket::yansi::Paint::default("Template::fairing()").bold(); + let template = "Template".primary().bold(); + let fairing = "Template::fairing()".primary().bold(); error!("returning `{}` responder without attaching `{}`.", template, fairing); info_!("To use or query templates, you must attach `{}`.", fairing); info_!("See the `Template` documentation for more information."); diff --git a/contrib/dyn_templates/src/metadata.rs b/contrib/dyn_templates/src/metadata.rs index feceab36..06d722d2 100644 --- a/contrib/dyn_templates/src/metadata.rs +++ b/contrib/dyn_templates/src/metadata.rs @@ -4,6 +4,7 @@ use rocket::{Request, Rocket, Ignite, Sentinel}; use rocket::http::{Status, ContentType}; use rocket::request::{self, FromRequest}; use rocket::serde::Serialize; +use rocket::yansi::Paint; use crate::{Template, context::ContextManager}; @@ -126,8 +127,8 @@ impl Metadata<'_> { impl Sentinel for Metadata<'_> { fn abort(rocket: &Rocket) -> bool { if rocket.state::().is_none() { - let md = rocket::yansi::Paint::default("Metadata").bold(); - let fairing = rocket::yansi::Paint::default("Template::fairing()").bold(); + let md = "Metadata".primary().bold(); + let fairing = "Template::fairing()".primary().bold(); error!("requested `{}` guard without attaching `{}`.", md, fairing); info_!("To use or query templates, you must attach `{}`.", fairing); info_!("See the `Template` documentation for more information."); diff --git a/contrib/sync_db_pools/lib/src/connection.rs b/contrib/sync_db_pools/lib/src/connection.rs index 355a55d1..a52aae72 100644 --- a/contrib/sync_db_pools/lib/src/connection.rs +++ b/contrib/sync_db_pools/lib/src/connection.rs @@ -224,10 +224,13 @@ impl Sentinel for Connection { use rocket::yansi::Paint; if rocket.state::>().is_none() { - let conn = Paint::default(std::any::type_name::()).bold(); - let fairing = Paint::default(format!("{}::fairing()", conn)).wrap().bold(); - error!("requesting `{}` DB connection without attaching `{}`.", conn, fairing); - info_!("Attach `{}` to use database connection pooling.", fairing); + let conn = std::any::type_name::().primary().bold(); + error!("requesting `{}` DB connection without attaching `{}{}`.", + conn, conn.linger(), "::fairing()".clear()); + + info_!("Attach `{}{}` to use database connection pooling.", + conn.linger(), "::fairing()".clear()); + return true; } diff --git a/core/lib/Cargo.toml b/core/lib/Cargo.toml index 44de9448..bed0ec8b 100644 --- a/core/lib/Cargo.toml +++ b/core/lib/Cargo.toml @@ -37,13 +37,12 @@ uuid_ = { package = "uuid", version = "1", optional = true, features = ["serde"] # Non-optional, core dependencies from here on out. futures = { version = "0.3.0", default-features = false, features = ["std"] } -yansi = "0.5" +yansi = { version = "1.0.0-rc", features = ["detect-tty"] } log = { version = "0.4", features = ["std"] } num_cpus = "1.0" time = { version = "0.3", features = ["macros", "parsing"] } memchr = "2" # TODO: Use pear instead. binascii = "0.1" -is-terminal = "0.4.3" ref-cast = "1.0" atomic = "0.5" parking_lot = "0.12" diff --git a/core/lib/src/catcher/catcher.rs b/core/lib/src/catcher/catcher.rs index 9068ea19..faa54758 100644 --- a/core/lib/src/catcher/catcher.rs +++ b/core/lib/src/catcher/catcher.rs @@ -343,14 +343,14 @@ impl From for Catcher { impl fmt::Display for Catcher { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(ref n) = self.name { - write!(f, "{}{}{} ", Paint::cyan("("), Paint::white(n), Paint::cyan(")"))?; + write!(f, "{}{}{} ", "(".cyan(), n.primary(), ")".cyan())?; } - write!(f, "{} ", Paint::green(self.base.path()))?; + write!(f, "{} ", self.base.path().green())?; match self.code { - Some(code) => write!(f, "{}", Paint::blue(code)), - None => write!(f, "{}", Paint::blue("default")) + Some(code) => write!(f, "{}", code.blue()), + None => write!(f, "{}", "default".blue()), } } } diff --git a/core/lib/src/config/config.rs b/core/lib/src/config/config.rs index 993d7c00..61b25bff 100644 --- a/core/lib/src/config/config.rs +++ b/core/lib/src/config/config.rs @@ -4,7 +4,7 @@ use figment::{Figment, Profile, Provider, Metadata, error::Result}; use figment::providers::{Serialized, Env, Toml, Format}; use figment::value::{Map, Dict, magic::RelativePathBuf}; use serde::{Deserialize, Serialize}; -use yansi::Paint; +use yansi::{Paint, Style, Color::Primary}; use crate::log::PaintExt; use crate::config::{LogLevel, Shutdown, Ident}; @@ -383,7 +383,7 @@ impl Config { trace!("-- configuration trace information --"); for param in Self::PARAMETERS { if let Some(meta) = figment.find_metadata(param) { - let (param, name) = (Paint::blue(param), Paint::white(&meta.name)); + let (param, name) = (param.blue(), meta.name.primary()); if let Some(ref source) = meta.source { trace_!("{:?} parameter source: {} ({})", param, name, source); } else { @@ -394,52 +394,50 @@ impl Config { } pub(crate) fn pretty_print(&self, figment: &Figment) { - fn bold(val: T) -> Paint { - Paint::default(val).bold() - } + static VAL: Style = Primary.bold(); self.trace_print(figment); - launch_meta!("{}Configured for {}.", Paint::emoji("🔧 "), self.profile); - launch_meta_!("address: {}", bold(&self.address)); - launch_meta_!("port: {}", bold(&self.port)); - launch_meta_!("workers: {}", bold(self.workers)); - launch_meta_!("max blocking threads: {}", bold(self.max_blocking)); - launch_meta_!("ident: {}", bold(&self.ident)); + launch_meta!("{}Configured for {}.", "🔧 ".emoji(), self.profile.underline()); + launch_meta_!("address: {}", self.address.paint(VAL)); + launch_meta_!("port: {}", self.port.paint(VAL)); + launch_meta_!("workers: {}", self.workers.paint(VAL)); + launch_meta_!("max blocking threads: {}", self.max_blocking.paint(VAL)); + launch_meta_!("ident: {}", self.ident.paint(VAL)); match self.ip_header { - Some(ref name) => launch_meta_!("IP header: {}", bold(name)), - None => launch_meta_!("IP header: {}", bold("disabled")) + Some(ref name) => launch_meta_!("IP header: {}", name.paint(VAL)), + None => launch_meta_!("IP header: {}", "disabled".paint(VAL)) } - launch_meta_!("limits: {}", bold(&self.limits)); - launch_meta_!("temp dir: {}", bold(&self.temp_dir.relative().display())); - launch_meta_!("http/2: {}", bold(cfg!(feature = "http2"))); + launch_meta_!("limits: {}", (&self.limits).paint(VAL)); + launch_meta_!("temp dir: {}", self.temp_dir.relative().display().paint(VAL)); + launch_meta_!("http/2: {}", (cfg!(feature = "http2").paint(VAL))); match self.keep_alive { - 0 => launch_meta_!("keep-alive: {}", bold("disabled")), - ka => launch_meta_!("keep-alive: {}{}", bold(ka), bold("s")), + 0 => launch_meta_!("keep-alive: {}", "disabled".paint(VAL)), + ka => launch_meta_!("keep-alive: {}{}", ka.paint(VAL), "s".paint(VAL)), } match (self.tls_enabled(), self.mtls_enabled()) { - (true, true) => launch_meta_!("tls: {}", bold("enabled w/mtls")), - (true, false) => launch_meta_!("tls: {} w/o mtls", bold("enabled")), - (false, _) => launch_meta_!("tls: {}", bold("disabled")), + (true, true) => launch_meta_!("tls: {}", "enabled w/mtls".paint(VAL)), + (true, false) => launch_meta_!("tls: {} w/o mtls", "enabled".paint(VAL)), + (false, _) => launch_meta_!("tls: {}", "disabled".paint(VAL)), } - launch_meta_!("shutdown: {}", bold(&self.shutdown)); - launch_meta_!("log level: {}", bold(self.log_level)); - launch_meta_!("cli colors: {}", bold(&self.cli_colors)); + launch_meta_!("shutdown: {}", self.shutdown.paint(VAL)); + launch_meta_!("log level: {}", self.log_level.paint(VAL)); + launch_meta_!("cli colors: {}", self.cli_colors.paint(VAL)); // Check for now deprecated config values. for (key, replacement) in Self::DEPRECATED_KEYS { if let Some(md) = figment.find_metadata(key) { - warn!("found value for deprecated config key `{}`", Paint::white(key)); + warn!("found value for deprecated config key `{}`", key.paint(VAL)); if let Some(ref source) = md.source { - launch_meta_!("in {} {}", Paint::white(source), md.name); + launch_meta_!("in {} {}", source.paint(VAL), md.name); } if let Some(new_key) = replacement { - launch_meta_!("key has been by replaced by `{}`", Paint::white(new_key)); + launch_meta_!("key has been by replaced by `{}`", new_key.paint(VAL)); } else { launch_meta_!("key has no special meaning"); } @@ -449,10 +447,10 @@ impl Config { // Check for now removed config values. for (prefix, replacement) in Self::DEPRECATED_PROFILES { if let Some(profile) = figment.profiles().find(|p| p.starts_with(prefix)) { - warn!("found set deprecated profile `{}`", Paint::white(profile)); + warn!("found set deprecated profile `{}`", profile.paint(VAL)); if let Some(new_profile) = replacement { - launch_meta_!("profile was replaced by `{}`", Paint::white(new_profile)); + launch_meta_!("profile was replaced by `{}`", new_profile.paint(VAL)); } else { launch_meta_!("profile `{}` has no special meaning", profile); } @@ -460,11 +458,11 @@ impl Config { } #[cfg(feature = "secrets")] { - launch_meta_!("secret key: {}", bold(&self.secret_key)); + launch_meta_!("secret key: {}", self.secret_key.paint(VAL)); if !self.secret_key.is_provided() { warn!("secrets enabled without a stable `secret_key`"); launch_meta_!("disable `secrets` feature or configure a `secret_key`"); - launch_meta_!("this becomes an {} in non-debug profiles", Paint::red("error")); + launch_meta_!("this becomes an {} in non-debug profiles", "error".red()); } } } @@ -598,7 +596,7 @@ pub fn pretty_print_error(error: figment::Error) { crate::log::init_default(); error!("Failed to extract valid configuration."); for e in error { - fn w(v: T) -> Paint { Paint::white(v) } + fn w(v: T) -> yansi::Painted { Paint::new(v).primary() } match e.kind { Kind::Message(msg) => error_!("{}", msg), diff --git a/core/lib/src/config/tls.rs b/core/lib/src/config/tls.rs index 06755d7c..41e88082 100644 --- a/core/lib/src/config/tls.rs +++ b/core/lib/src/config/tls.rs @@ -644,8 +644,9 @@ mod with_tls_feature { Either::Left(path) => { let path = path.relative(); let file = fs::File::open(&path).map_err(move |e| { - Error::new(e.kind(), format!("error reading TLS file `{}`: {}", - Paint::white(figment::Source::File(path)), e)) + let source = figment::Source::File(path); + let msg = format!("error reading TLS file `{}`: {}", source.primary(), e); + Error::new(e.kind(), msg) })?; Ok(Box::new(io::BufReader::new(file))) diff --git a/core/lib/src/data/data_stream.rs b/core/lib/src/data/data_stream.rs index b3355476..a9a9e07a 100644 --- a/core/lib/src/data/data_stream.rs +++ b/core/lib/src/data/data_stream.rs @@ -7,6 +7,7 @@ use tokio::fs::File; use tokio::io::{AsyncRead, AsyncWrite, AsyncReadExt, ReadBuf, Take}; use futures::stream::Stream; use futures::ready; +use yansi::Paint; use crate::http::hyper; use crate::ext::{PollExt, Chain}; @@ -261,8 +262,7 @@ impl AsyncRead for DataStream<'_> { StreamKind::Multipart(_) => "a multipart form field", }; - let msg = yansi::Paint::default(kind).bold(); - warn_!("Data limit reached while reading {}.", msg); + warn_!("Data limit reached while reading {}.", kind.primary().bold()); } Pin::new(&mut self.chain).poll_read(cx, buf) diff --git a/core/lib/src/error.rs b/core/lib/src/error.rs index 2dc361cc..b68b255b 100644 --- a/core/lib/src/error.rs +++ b/core/lib/src/error.rs @@ -188,7 +188,7 @@ impl Error { error!("Rocket failed to launch due to the following {} collisions:", kind); for &(ref a, ref b) in collisions { - info_!("{} {} {}", a, Paint::red("collides with").italic(), b) + info_!("{} {} {}", a, "collides with".red().italic(), b) } } @@ -208,7 +208,7 @@ impl Error { } ErrorKind::InsecureSecretKey(profile) => { error!("secrets enabled in non-debug without `secret_key`"); - info_!("selected profile: {}", Paint::default(profile).bold()); + info_!("selected profile: {}", profile.primary().bold()); info_!("disable `secrets` feature or configure a `secret_key`"); "aborting due to insecure configuration" } @@ -219,7 +219,7 @@ impl Error { ErrorKind::SentinelAborts(ref failures) => { error!("Rocket failed to launch due to aborting sentinels:"); for sentry in failures { - let name = Paint::default(sentry.type_name).bold(); + let name = sentry.type_name.primary().bold(); let (file, line, col) = sentry.location; info_!("{} ({}:{}:{})", name, file, line, col); } diff --git a/core/lib/src/fairing/fairings.rs b/core/lib/src/fairing/fairings.rs index dbc78b70..12a99c08 100644 --- a/core/lib/src/fairing/fairings.rs +++ b/core/lib/src/fairing/fairings.rs @@ -173,11 +173,11 @@ impl Fairings { pub fn pretty_print(&self) { let active_fairings = self.active().collect::>(); if !active_fairings.is_empty() { - launch_meta!("{}{}:", Paint::emoji("📡 "), Paint::magenta("Fairings")); + launch_meta!("{}{}:", "📡 ".emoji(), "Fairings".magenta()); for (_, fairing) in iter!(self, active_fairings.into_iter()) { - launch_meta_!("{} ({})", Paint::default(fairing.info().name).bold(), - Paint::blue(fairing.info().kind).bold()); + let (name, kind) = (fairing.info().name, fairing.info().kind); + launch_meta_!("{} ({})", name.primary().bold(), kind.blue().bold()); } } } diff --git a/core/lib/src/fs/server.rs b/core/lib/src/fs/server.rs index 267c4191..da78ec33 100644 --- a/core/lib/src/fs/server.rs +++ b/core/lib/src/fs/server.rs @@ -147,12 +147,12 @@ impl FileServer { if !options.contains(Options::Missing) { if !options.contains(Options::IndexFile) && !path.is_dir() { let path = path.display(); - error!("FileServer path '{}' is not a directory.", Paint::white(path)); + error!("FileServer path '{}' is not a directory.", path.primary()); warn_!("Aborting early to prevent inevitable handler failure."); panic!("invalid directory: refusing to continue"); } else if !path.exists() { let path = path.display(); - error!("FileServer path '{}' is not a file.", Paint::white(path)); + error!("FileServer path '{}' is not a file.", path.primary()); warn_!("Aborting early to prevent inevitable handler failure."); panic!("invalid file: refusing to continue"); } diff --git a/core/lib/src/fs/temp_file.rs b/core/lib/src/fs/temp_file.rs index 6924b40c..0f0ca9f5 100644 --- a/core/lib/src/fs/temp_file.rs +++ b/core/lib/src/fs/temp_file.rs @@ -536,7 +536,7 @@ impl<'r> FromData<'r> for Capped> { let has_form = |ty: &ContentType| ty.is_form_data() || ty.is_form(); if req.content_type().map_or(false, has_form) { - let (tf, form) = (Paint::white("TempFile<'_>"), Paint::white("Form>")); + let (tf, form) = ("TempFile<'_>".primary(), "Form>".primary()); warn_!("Request contains a form that will not be processed."); info_!("Bare `{}` data guard writes raw, unprocessed streams to disk.", tf); info_!("Did you mean to use `{}` instead?", form); diff --git a/core/lib/src/log.rs b/core/lib/src/log.rs index f2064071..87f51189 100644 --- a/core/lib/src/log.rs +++ b/core/lib/src/log.rs @@ -4,9 +4,8 @@ use std::fmt; use std::str::FromStr; use std::sync::atomic::{AtomicBool, Ordering}; -use is_terminal::IsTerminal; use serde::{de, Serialize, Serializer, Deserialize, Deserializer}; -use yansi::Paint; +use yansi::{Paint, Painted, Condition}; /// Reexport the `log` crate as `private`. pub use log as private; @@ -81,8 +80,8 @@ pub enum LogLevel { Off, } -pub trait PaintExt { - fn emoji(item: &str) -> Paint<&str>; +pub trait PaintExt: Sized { + fn emoji(self) -> Painted; } // Whether a record is a special `launch_{meta,info}!` record. @@ -116,7 +115,7 @@ impl log::Log for RocketLogger { // In Rocket, we abuse targets with suffix "_" to indicate indentation. let indented = record.target().ends_with('_'); if indented { - write_out!(" {} ", Paint::default(">>").bold()); + write_out!(" {} ", ">>".bold()); } // Downgrade a physical launch `warn` to logical `info`. @@ -126,27 +125,23 @@ impl log::Log for RocketLogger { match level { log::Level::Error if !indented => { - write_out!("{} {}\n", - Paint::red("Error:").bold(), - Paint::red(record.args()).wrap()); + write_out!("{} {}\n", "Error:".red().bold(), record.args().red().wrap()); } log::Level::Warn if !indented => { - write_out!("{} {}\n", - Paint::yellow("Warning:").bold(), - Paint::yellow(record.args()).wrap()); + write_out!("{} {}\n", "Warning:".yellow().bold(), record.args().yellow().wrap()); } - log::Level::Info => write_out!("{}\n", Paint::blue(record.args()).wrap()), - log::Level::Trace => write_out!("{}\n", Paint::magenta(record.args()).wrap()), - log::Level::Warn => write_out!("{}\n", Paint::yellow(record.args()).wrap()), - log::Level::Error => write_out!("{}\n", Paint::red(record.args()).wrap()), + log::Level::Info => write_out!("{}\n", record.args().blue().wrap()), + log::Level::Trace => write_out!("{}\n", record.args().magenta().wrap()), + log::Level::Warn => write_out!("{}\n", record.args().yellow().wrap()), + log::Level::Error => write_out!("{}\n", &record.args().red().wrap()), log::Level::Debug => { - write_out!("\n{} ", Paint::blue("-->").bold()); + write_out!("\n{} ", "-->".blue().bold()); if let Some(file) = record.file() { - write_out!("{}", Paint::blue(file)); + write_out!("{}", file.blue()); } if let Some(line) = record.line() { - write_out!(":{}\n", Paint::blue(line)); + write_out!(":{}\n", line.blue()); } write_out!("\t{}\n", record.args()); @@ -171,18 +166,12 @@ pub(crate) fn init(config: &crate::Config) { ROCKET_LOGGER_SET.store(true, Ordering::Release); } - // Always disable colors if requested or if they won't work on Windows. - if !config.cli_colors || !Paint::enable_windows_ascii() { - Paint::disable(); - } + // Always disable colors if requested or if the stdout/err aren't TTYs. + let should_color = config.cli_colors && Condition::stdouterr_are_tty(); + yansi::whenever(Condition::cached(should_color)); // Set Rocket-logger specific settings only if Rocket's logger is set. if ROCKET_LOGGER_SET.load(Ordering::Acquire) { - // Rocket logs to stdout, so disable coloring if it's not a TTY. - if !std::io::stdout().is_terminal() { - Paint::disable(); - } - log::set_max_level(config.log_level.into()); } } @@ -247,10 +236,10 @@ impl<'de> Deserialize<'de> for LogLevel { } } -impl PaintExt for Paint<&str> { +impl PaintExt for &str { /// Paint::masked(), but hidden on Windows due to broken output. See #1122. - fn emoji(_item: &str) -> Paint<&str> { - #[cfg(windows)] { Paint::masked("") } - #[cfg(not(windows))] { Paint::masked(_item) } + fn emoji(self) -> Painted { + #[cfg(windows)] { Paint::new("").mask() } + #[cfg(not(windows))] { Paint::new(self).mask() } } } diff --git a/core/lib/src/outcome.rs b/core/lib/src/outcome.rs index df3dbc1a..44a38f89 100644 --- a/core/lib/src/outcome.rs +++ b/core/lib/src/outcome.rs @@ -765,6 +765,6 @@ impl fmt::Debug for Outcome { impl fmt::Display for Outcome { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (color, string) = self.formatting(); - write!(f, "{}", Paint::default(string).fg(color)) + write!(f, "{}", string.paint(color)) } } diff --git a/core/lib/src/request/request.rs b/core/lib/src/request/request.rs index 0b44d131..62a2bb1e 100644 --- a/core/lib/src/request/request.rs +++ b/core/lib/src/request/request.rs @@ -1110,15 +1110,12 @@ impl fmt::Debug for Request<'_> { impl fmt::Display for Request<'_> { /// Pretty prints a Request. Primarily used by Rocket's logging. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} {}", Paint::green(self.method()), Paint::blue(&self.uri))?; + write!(f, "{} {}", self.method().green(), self.uri.blue())?; // Print the requests media type when the route specifies a format. - if let Some(media_type) = self.format() { - if !media_type.is_any() { - write!(f, " {}{}{}", - Paint::yellow(media_type.top()), - Paint::yellow("/"), - Paint::yellow(media_type.sub()))?; + if let Some(mime) = self.format() { + if !mime.is_any() { + write!(f, " {}/{}", mime.top().yellow().linger(), mime.sub().clear())?; } } diff --git a/core/lib/src/response/debug.rs b/core/lib/src/response/debug.rs index 2c6e5c26..030b5370 100644 --- a/core/lib/src/response/debug.rs +++ b/core/lib/src/response/debug.rs @@ -78,8 +78,8 @@ impl From for Debug { impl<'r, E: std::fmt::Debug> Responder<'r, 'static> for Debug { fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { - warn_!("Debug: {:?}", Paint::default(self.0)); - warn_!("Debug always responds with {}.", Status::InternalServerError); + warn_!("Debug: {:?}", self.0.primary()); + warn_!("Debug always responds with {}.", Status::InternalServerError.primary()); Err(Status::InternalServerError) } } @@ -87,7 +87,7 @@ impl<'r, E: std::fmt::Debug> Responder<'r, 'static> for Debug { /// Prints a warning with the error and forwards to the `500` error catcher. impl<'r> Responder<'r, 'static> for std::io::Error { fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { - warn_!("I/O Error: {:?}", yansi::Paint::default(self)); + warn_!("I/O Error: {:?}", self.primary()); Err(Status::InternalServerError) } } diff --git a/core/lib/src/rocket.rs b/core/lib/src/rocket.rs index e3ceb17b..ef9fdfec 100644 --- a/core/lib/src/rocket.rs +++ b/core/lib/src/rocket.rs @@ -255,7 +255,7 @@ impl Rocket { Err(e) => { error!("invalid {} base: {}", kind, Paint::white(&base)); error_!("{}", e); - info_!("{} {}", Paint::white("in"), std::panic::Location::caller()); + info_!("{} {}", "in".primary(), std::panic::Location::caller()); panic!("aborting due to {} base error", kind); } }; @@ -600,7 +600,7 @@ fn log_items(e: &str, t: &str, items: I, base: B, origin: O) { let mut items: Vec<_> = items.collect(); if !items.is_empty() { - launch_meta!("{}{}:", Paint::emoji(e), Paint::magenta(t)); + launch_meta!("{}{}:", e.emoji(), t.magenta()); } items.sort_by_key(|i| origin(i).path().as_str().chars().count()); @@ -678,9 +678,7 @@ impl Rocket { async fn _local_launch(self) -> Rocket { let rocket = self.into_orbit(); rocket.fairings.handle_liftoff(&rocket).await; - launch_info!("{}{}", Paint::emoji("🚀 "), - Paint::default("Rocket has launched into local orbit").bold()); - + launch_info!("{}{}", "🚀 ".emoji(), "Rocket has launched locally".primary().bold()); rocket } @@ -693,9 +691,9 @@ impl Rocket { let socket_addr = SocketAddr::new(rkt.config.address, rkt.config.port); let addr = format!("{}://{}", proto, socket_addr); launch_info!("{}{} {}", - Paint::emoji("🚀 "), - Paint::default("Rocket has launched from").bold(), - Paint::default(addr).bold().underline()); + "🚀 ".emoji(), + "Rocket has launched from".bold().primary().linger(), + addr.underline()); })) .await .map(|rocket| rocket.into_ignite()) diff --git a/core/lib/src/route/route.rs b/core/lib/src/route/route.rs index 44ef2790..24853d95 100644 --- a/core/lib/src/route/route.rs +++ b/core/lib/src/route/route.rs @@ -346,18 +346,18 @@ impl Route { impl fmt::Display for Route { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(ref n) = self.name { - write!(f, "{}{}{} ", Paint::cyan("("), Paint::white(n), Paint::cyan(")"))?; + write!(f, "{}{}{} ", "(".cyan(), n.primary(), ")".cyan())?; } - write!(f, "{} ", Paint::green(&self.method))?; + write!(f, "{} ", self.method.green())?; self.uri.color_fmt(f)?; if self.rank > 1 { - write!(f, " [{}]", Paint::default(&self.rank).bold())?; + write!(f, " [{}]", self.rank.primary().bold())?; } if let Some(ref format) = self.format { - write!(f, " {}", Paint::yellow(format))?; + write!(f, " {}", format.yellow())?; } Ok(()) diff --git a/core/lib/src/route/uri.rs b/core/lib/src/route/uri.rs index e440270f..09072ccd 100644 --- a/core/lib/src/route/uri.rs +++ b/core/lib/src/route/uri.rs @@ -247,10 +247,9 @@ impl<'a> RouteUri<'a> { .map(|raw| raw.as_str()) .unwrap_or(unmounted.as_str()); - write!(f, "{}", Paint::blue(self.base()).underline())?; - write!(f, "{}", Paint::blue(unmounted_part))?; + write!(f, "{}{}", self.base().blue().underline(), unmounted_part.blue())?; if let Some(q) = self.unmounted().query() { - write!(f, "{}{}", Paint::yellow("?"), Paint::yellow(q))?; + write!(f, "{}{}", "?".yellow(), q.yellow())?; } Ok(()) diff --git a/core/lib/src/server.rs b/core/lib/src/server.rs index b0011135..e3836984 100644 --- a/core/lib/src/server.rs +++ b/core/lib/src/server.rs @@ -31,7 +31,7 @@ async fn handle(name: Option<&str>, run: F) -> Option macro_rules! panic_info { ($name:expr, $e:expr) => {{ match $name { - Some(name) => error_!("Handler {} panicked.", Paint::white(name)), + Some(name) => error_!("Handler {} panicked.", name.primary()), None => error_!("A handler panicked.") }; @@ -129,7 +129,7 @@ impl Rocket { }; match self._send_response(response, tx).await { - Ok(()) => info_!("{}", Paint::green("Response succeeded.")), + Ok(()) => info_!("{}", "Response succeeded.".green()), Err(e) if remote_hungup(&e) => warn_!("Remote left: {}.", e), Err(e) => warn_!("Failed to write response: {}.", e), } @@ -284,7 +284,7 @@ impl Rocket { let mut response = match self.route(request, data).await { Outcome::Success(response) => response, Outcome::Forward((data, _)) if request.method() == Method::Head => { - info_!("Autohandling {} request.", Paint::default("HEAD").bold()); + info_!("Autohandling {} request.", "HEAD".primary().bold()); // Dispatch the request again with Method `GET`. request._set_method(Method::Get); @@ -334,7 +334,7 @@ impl Rocket { // Check if the request processing completed (Some) or if the // request needs to be forwarded. If it does, continue the loop // (None) to try again. - info_!("{} {}", Paint::default("Outcome:").bold(), outcome); + info_!("{} {}", "Outcome:".primary().bold(), outcome); match outcome { o@Outcome::Success(_) | o@Outcome::Failure(_) => return o, Outcome::Forward(forwarded) => (data, status) = forwarded, @@ -372,7 +372,7 @@ impl Rocket { .map(|result| result.map_err(Some)) .unwrap_or_else(|| Err(None)) } else { - let code = Paint::blue(status.code).bold(); + let code = status.code.blue().bold(); warn_!("No {} catcher registered. Using Rocket default.", code); Ok(crate::catcher::default_handler(status, req)) } diff --git a/core/lib/src/shield/shield.rs b/core/lib/src/shield/shield.rs index 1e58175f..ea448144 100644 --- a/core/lib/src/shield/shield.rs +++ b/core/lib/src/shield/shield.rs @@ -207,10 +207,10 @@ impl Fairing for Shield { } if !self.headers().is_empty() { - info!("{}{}:", Paint::emoji("🛡️ "), Paint::magenta("Shield")); + info!("{}{}:", "🛡️ ".emoji(), "Shield".magenta()); for header in self.headers() { - info_!("{}: {}", header.name(), Paint::default(header.value())); + info_!("{}: {}", header.name(), header.value().primary()); } if force_hsts { diff --git a/core/lib/src/state.rs b/core/lib/src/state.rs index 577e873b..6b5edcdf 100644 --- a/core/lib/src/state.rs +++ b/core/lib/src/state.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use std::any::type_name; use ref_cast::RefCast; +use yansi::Paint; use crate::{Phase, Rocket, Ignite, Sentinel}; use crate::request::{self, FromRequest, Request}; @@ -210,8 +211,8 @@ impl<'r, T: Send + Sync + 'static> FromRequest<'r> for &'r State { impl Sentinel for &State { fn abort(rocket: &Rocket) -> bool { if rocket.state::().is_none() { - let type_name = yansi::Paint::default(type_name::()).bold(); - error!("launching with unmanaged `{}` state.", type_name); + let type_name = type_name::(); + error!("launching with unmanaged `{}` state.", type_name.primary().bold()); info_!("Using `State` requires managing it with `.manage()`."); return true; }