rocket::mtls

Struct Certificate

pub struct Certificate<'a> { /* private fields */ }
Available on crate feature mtls only.
Expand description

A request guard for validated, verified client certificates.

This type is a wrapper over x509::TbsCertificate with convenient methods and complete documentation. Should the data exposed by the inherent methods not suffice, this type derefs to x509::TbsCertificate.

§Request Guard

The request guard implementation succeeds if:

  • The client presents certificates.
  • The certificates are active and not yet expired.
  • The client’s certificate chain was signed by the CA identified by the configured ca_certs and with respect to SNI, if any. See module level docs for configuration details.

If the client does not present certificates, the guard forwards with a status of 401 Unauthorized.

If the certificate chain fails to validate or verify, the guard fails with the respective Error.

§Wrapping

To implement roles, the Certificate guard can be wrapped with a more semantically meaningful type with extra validation. For example, if a certificate with a specific serial number is known to belong to an administrator, a CertifiedAdmin type can authorize as follow:

use rocket::mtls::{self, bigint::BigUint, Certificate};
use rocket::request::{Request, FromRequest, Outcome};
use rocket::outcome::try_outcome;
use rocket::http::Status;

// The serial number for the certificate issued to the admin.
const ADMIN_SERIAL: &str = "65828378108300243895479600452308786010218223563";

// A request guard that authenticates and authorizes an administrator.
struct CertifiedAdmin<'r>(Certificate<'r>);

#[rocket::async_trait]
impl<'r> FromRequest<'r> for CertifiedAdmin<'r> {
    type Error = mtls::Error;

    async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
        let cert = try_outcome!(req.guard::<Certificate<'r>>().await);
        if let Some(true) = cert.has_serial(ADMIN_SERIAL) {
            Outcome::Success(CertifiedAdmin(cert))
        } else {
            Outcome::Forward(Status::Unauthorized)
        }
    }
}

#[get("/admin")]
fn admin(admin: CertifiedAdmin<'_>) {
    // This handler can only execute if an admin is authenticated.
}

#[get("/admin", rank = 2)]
fn unauthorized(user: Option<Certificate<'_>>) {
    // This handler always executes, whether there's a non-admin user that's
    // authenticated (user = Some()) or not (user = None).
}

§Example

To retrieve certificate data in a route, use Certificate as a guard:

use rocket::mtls::{self, Certificate};

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    // This handler only runs when a valid certificate was presented.
}

#[get("/maybe")]
fn maybe_auth(cert: Option<Certificate<'_>>) {
    // This handler runs even if no certificate was presented or an invalid
    // certificate was presented.
}

#[get("/ok")]
fn ok_auth(cert: mtls::Result<Certificate<'_>>) {
    // This handler does not run if a certificate was not presented but
    // _does_ run if a valid (Ok) or invalid (Err) one was presented.
}

Implementations§

§

impl<'a> Certificate<'a>

pub fn serial(&self) -> &BigUint

Returns the serial number of the X.509 certificate.

§Example
use rocket::mtls::Certificate;

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    let cert = cert.serial();
}

pub fn version(&self) -> u32

Returns the version of the X.509 certificate.

§Example
use rocket::mtls::Certificate;

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    let cert = cert.version();
}

pub fn subject(&self) -> &Name<'a>

Returns the subject (a “DN” or “Distinguished Name”) of the X.509 certificate.

§Example
use rocket::mtls::Certificate;

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    if let Some(name) = cert.subject().common_name() {
        println!("Hello, {}!", name);
    }
}

pub fn issuer(&self) -> &Name<'a>

Returns the issuer (a “DN” or “Distinguished Name”) of the X.509 certificate.

§Example
use rocket::mtls::Certificate;

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    if let Some(name) = cert.issuer().common_name() {
        println!("Issued by: {}", name);
    }
}

pub fn extensions(&self) -> &[X509Extension<'a>]

Returns a slice of the extensions in the X.509 certificate.

§Example
use rocket::mtls::{oid, x509, Certificate};

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    let subject_alt = cert.extensions().iter()
        .find(|e| e.oid == oid::OID_X509_EXT_SUBJECT_ALT_NAME)
        .and_then(|e| match e.parsed_extension() {
            x509::ParsedExtension::SubjectAlternativeName(s) => Some(s),
            _ => None
        });

    if let Some(subject_alt) = subject_alt {
        for name in &subject_alt.general_names {
            if let x509::GeneralName::RFC822Name(name) = name {
                println!("An email, perhaps? {}", name);
            }
        }
    }
}

pub fn has_serial(&self, number: &str) -> Option<bool>

Checks if the certificate has the serial number number.

If number is not a valid unsigned integer in base 10, returns None.

Otherwise, returns Some(true) if it does and Some(false) if it does not.

use rocket::mtls::Certificate;

const SERIAL: &str = "65828378108300243895479600452308786010218223563";

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    if cert.has_serial(SERIAL).unwrap_or(false) {
        println!("certificate has the expected serial number");
    }
}

pub fn as_bytes(&self) -> &'a [u8]

Returns the raw, unmodified, DER-encoded X.509 certificate data bytes.

§Example
use rocket::mtls::Certificate;

const SHA256_FINGERPRINT: &str =
    "CE C2 4E 01 00 FF F7 78 CB A4 AA CB D2 49 DD 09 \
     02 EF 0E 9B DA 89 2A E4 0D F4 09 83 97 C1 97 0D";

#[get("/auth")]
fn auth(cert: Certificate<'_>) {
    if sha256_fingerprint(cert.as_bytes()) == SHA256_FINGERPRINT {
        println!("certificate fingerprint matched");
    }
}

Methods from Deref<Target = TbsCertificate<'a>>§

Source

pub fn version(&self) -> X509Version

Get the version of the encoded certificate

Source

pub fn subject(&self) -> &X509Name<'_>

Get the certificate subject.

Source

pub fn issuer(&self) -> &X509Name<'_>

Get the certificate issuer.

Source

pub fn validity(&self) -> &Validity

Get the certificate validity.

Source

pub fn public_key(&self) -> &SubjectPublicKeyInfo<'_>

Get the certificate public key information.

Source

pub fn extensions(&self) -> &[X509Extension<'a>]

Returns the certificate extensions

Source

pub fn iter_extensions(&self) -> impl Iterator<Item = &X509Extension<'a>>

Returns an iterator over the certificate extensions

Source

pub fn get_extension_unique( &self, oid: &Oid<'_>, ) -> Result<Option<&X509Extension<'a>>, X509Error>

Searches for an extension with the given Oid.

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error DuplicateExtensions if the extension is present twice or more.

Source

pub fn find_extension(&self, oid: &Oid<'_>) -> Option<&X509Extension<'a>>

👎Deprecated since 0.13.0: Do not use this function (duplicate extensions are not checked), use get_extension_unique

Searches for an extension with the given Oid.

§Duplicate extensions

Note: if there are several extensions with the same Oid, the first one is returned, masking other values.

RFC5280 forbids having duplicate extensions, but does not specify how errors should be handled.

Because of this, the find_extension method is not safe and should not be used! The get_extension_unique method checks for duplicate extensions and should be preferred.

Source

pub fn extensions_map( &self, ) -> Result<HashMap<Oid<'_>, &X509Extension<'a>>, X509Error>

Builds and returns a map of extensions.

If an extension is present twice, this will fail and return DuplicateExtensions.

Source

pub fn basic_constraints( &self, ) -> Result<Option<BasicExtension<&BasicConstraints>>, X509Error>

Attempt to get the certificate Basic Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is present twice or more.

Source

pub fn key_usage(&self) -> Result<Option<BasicExtension<&KeyUsage>>, X509Error>

Attempt to get the certificate Key Usage extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn extended_key_usage( &self, ) -> Result<Option<BasicExtension<&ExtendedKeyUsage<'_>>>, X509Error>

Attempt to get the certificate Extended Key Usage extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn policy_constraints( &self, ) -> Result<Option<BasicExtension<&PolicyConstraints>>, X509Error>

Attempt to get the certificate Policy Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn inhibit_anypolicy( &self, ) -> Result<Option<BasicExtension<&InhibitAnyPolicy>>, X509Error>

Attempt to get the certificate Policy Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn policy_mappings( &self, ) -> Result<Option<BasicExtension<&PolicyMappings<'_>>>, X509Error>

Attempt to get the certificate Policy Mappings extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn subject_alternative_name( &self, ) -> Result<Option<BasicExtension<&SubjectAlternativeName<'_>>>, X509Error>

Attempt to get the certificate Subject Alternative Name extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn name_constraints( &self, ) -> Result<Option<BasicExtension<&NameConstraints<'_>>>, X509Error>

Attempt to get the certificate Name Constraints extension

Return Ok(Some(extension)) if exactly one was found, Ok(None) if none was found, or an error if the extension is invalid, or is present twice or more.

Source

pub fn is_ca(&self) -> bool

Returns true if certificate has basicConstraints CA:true

Source

pub fn raw_serial(&self) -> &'a [u8]

Get the raw bytes of the certificate serial number

Source

pub fn raw_serial_as_string(&self) -> String

Get a formatted string of the certificate serial number, separated by ‘:’

Trait Implementations§

§

impl<'a> Debug for Certificate<'a>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<'a> Deref for Certificate<'a>

§

type Target = TbsCertificate<'a>

The resulting type after dereferencing.
§

fn deref(&self) -> &<Certificate<'a> as Deref>::Target

Dereferences the value.
Source§

impl<'r> FromRequest<'r> for Certificate<'r>

Source§

type Error = Error

The associated error to be returned if derivation fails.
Source§

fn from_request<'life0, 'async_trait>( req: &'r Request<'life0>, ) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'r: 'async_trait, 'life0: 'async_trait,

Derives an instance of Self from the incoming request metadata. Read more
§

impl<'a> PartialEq for Certificate<'a>

§

fn eq(&self, other: &Certificate<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
§

impl<'a> StructuralPartialEq for Certificate<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Certificate<'a>

§

impl<'a> RefUnwindSafe for Certificate<'a>

§

impl<'a> Send for Certificate<'a>

§

impl<'a> Sync for Certificate<'a>

§

impl<'a> Unpin for Certificate<'a>

§

impl<'a> UnwindSafe for Certificate<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T> AsTaggedExplicit<'a> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self>

Source§

impl<'a, T> AsTaggedImplicit<'a> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoCollection<T> for T

§

fn into_collection<A>(self) -> SmallVec<A>
where A: Array<Item = T>,

Converts self into a collection.
§

fn mapped<U, F, A>(self, f: F) -> SmallVec<A>
where F: FnMut(T) -> U, A: Array<Item = U>,

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Paint for T
where T: ?Sized,

Source§

fn fg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the foreground set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like red() and green(), which have the same functionality but are pithier.

§Example

Set foreground color to white using fg():

use yansi::{Paint, Color};

painted.fg(Color::White);

Set foreground color to white using white().

use yansi::Paint;

painted.white();
Source§

fn primary(&self) -> Painted<&T>

Returns self with the fg() set to Color::Primary.

§Example
println!("{}", value.primary());
Source§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to Color::Fixed.

§Example
println!("{}", value.fixed(color));
Source§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to Color::Rgb.

§Example
println!("{}", value.rgb(r, g, b));
Source§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to Color::Black.

§Example
println!("{}", value.black());
Source§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to Color::Red.

§Example
println!("{}", value.red());
Source§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to Color::Green.

§Example
println!("{}", value.green());
Source§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to Color::Yellow.

§Example
println!("{}", value.yellow());
Source§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to Color::Blue.

§Example
println!("{}", value.blue());
Source§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to Color::Magenta.

§Example
println!("{}", value.magenta());
Source§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to Color::Cyan.

§Example
println!("{}", value.cyan());
Source§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to Color::White.

§Example
println!("{}", value.white());
Source§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightBlack.

§Example
println!("{}", value.bright_black());
Source§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightRed.

§Example
println!("{}", value.bright_red());
Source§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightGreen.

§Example
println!("{}", value.bright_green());
Source§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightYellow.

§Example
println!("{}", value.bright_yellow());
Source§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightBlue.

§Example
println!("{}", value.bright_blue());
Source§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightMagenta.

§Example
println!("{}", value.bright_magenta());
Source§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightCyan.

§Example
println!("{}", value.bright_cyan());
Source§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to Color::BrightWhite.

§Example
println!("{}", value.bright_white());
Source§

fn bg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the background set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like on_red() and on_green(), which have the same functionality but are pithier.

§Example

Set background color to red using fg():

use yansi::{Paint, Color};

painted.bg(Color::Red);

Set background color to red using on_red().

use yansi::Paint;

painted.on_red();
Source§

fn on_primary(&self) -> Painted<&T>

Returns self with the bg() set to Color::Primary.

§Example
println!("{}", value.on_primary());
Source§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to Color::Fixed.

§Example
println!("{}", value.on_fixed(color));
Source§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to Color::Rgb.

§Example
println!("{}", value.on_rgb(r, g, b));
Source§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to Color::Black.

§Example
println!("{}", value.on_black());
Source§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to Color::Red.

§Example
println!("{}", value.on_red());
Source§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to Color::Green.

§Example
println!("{}", value.on_green());
Source§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to Color::Yellow.

§Example
println!("{}", value.on_yellow());
Source§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to Color::Blue.

§Example
println!("{}", value.on_blue());
Source§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to Color::Magenta.

§Example
println!("{}", value.on_magenta());
Source§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to Color::Cyan.

§Example
println!("{}", value.on_cyan());
Source§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to Color::White.

§Example
println!("{}", value.on_white());
Source§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightBlack.

§Example
println!("{}", value.on_bright_black());
Source§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightRed.

§Example
println!("{}", value.on_bright_red());
Source§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightGreen.

§Example
println!("{}", value.on_bright_green());
Source§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightYellow.

§Example
println!("{}", value.on_bright_yellow());
Source§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightBlue.

§Example
println!("{}", value.on_bright_blue());
Source§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightMagenta.

§Example
println!("{}", value.on_bright_magenta());
Source§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightCyan.

§Example
println!("{}", value.on_bright_cyan());
Source§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to Color::BrightWhite.

§Example
println!("{}", value.on_bright_white());
Source§

fn attr(&self, value: Attribute) -> Painted<&T>

Enables the styling Attribute value.

This method should be used rarely. Instead, prefer to use attribute-specific builder methods like bold() and underline(), which have the same functionality but are pithier.

§Example

Make text bold using attr():

use yansi::{Paint, Attribute};

painted.attr(Attribute::Bold);

Make text bold using using bold().

use yansi::Paint;

painted.bold();
Source§

fn bold(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Bold.

§Example
println!("{}", value.bold());
Source§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Dim.

§Example
println!("{}", value.dim());
Source§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Italic.

§Example
println!("{}", value.italic());
Source§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Underline.

§Example
println!("{}", value.underline());

Returns self with the attr() set to Attribute::Blink.

§Example
println!("{}", value.blink());

Returns self with the attr() set to Attribute::RapidBlink.

§Example
println!("{}", value.rapid_blink());
Source§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Invert.

§Example
println!("{}", value.invert());
Source§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Conceal.

§Example
println!("{}", value.conceal());
Source§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to Attribute::Strike.

§Example
println!("{}", value.strike());
Source§

fn quirk(&self, value: Quirk) -> Painted<&T>

Enables the yansi Quirk value.

This method should be used rarely. Instead, prefer to use quirk-specific builder methods like mask() and wrap(), which have the same functionality but are pithier.

§Example

Enable wrapping using .quirk():

use yansi::{Paint, Quirk};

painted.quirk(Quirk::Wrap);

Enable wrapping using wrap().

use yansi::Paint;

painted.wrap();
Source§

fn mask(&self) -> Painted<&T>

Returns self with the quirk() set to Quirk::Mask.

§Example
println!("{}", value.mask());
Source§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to Quirk::Wrap.

§Example
println!("{}", value.wrap());
Source§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to Quirk::Linger.

§Example
println!("{}", value.linger());
Source§

fn clear(&self) -> Painted<&T>

👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear(). The clear() method will be removed in a future release.

Returns self with the quirk() set to Quirk::Clear.

§Example
println!("{}", value.clear());
Source§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to Quirk::Resetting.

§Example
println!("{}", value.resetting());
Source§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to Quirk::Bright.

§Example
println!("{}", value.bright());
Source§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to Quirk::OnBright.

§Example
println!("{}", value.on_bright());
Source§

fn whenever(&self, value: Condition) -> Painted<&T>

Conditionally enable styling based on whether the Condition value applies. Replaces any previous condition.

See the crate level docs for more details.

§Example

Enable styling painted only when both stdout and stderr are TTYs:

use yansi::{Paint, Condition};

painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
Source§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new Painted with a default Style. Read more
Source§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more