Skip to main content

MessageAuthenticator

Struct MessageAuthenticator 

Source
pub struct MessageAuthenticator { /* private fields */ }
Expand description

Entry point for every verifier and DNS lookup in this crate.

A MessageAuthenticator wraps a DNS resolver and exposes the verifiers (verify_dkim, verify_dkim2, verify_arc, verify_spf, verify_dmarc, verify_iprev) together with the DNS lookup helpers used by them. Cloning is cheap: clones share the underlying resolver.

With the default dns-hickory feature the resolver is a hickory_resolver::TokioResolver, built with new, new_system_conf or one of the provider presets such as new_cloudflare_tls.

§Example

use mail_auth::{AuthenticatedMessage, DkimResult, MessageAuthenticator};

let authenticator = MessageAuthenticator::new_cloudflare_tls().unwrap();
let message = AuthenticatedMessage::parse(raw_message).unwrap();
let results = authenticator.verify_dkim(&message).await;
assert!(results.iter().all(|r| r.result() == &DkimResult::Pass));

Implementations§

Source§

impl MessageAuthenticator

Source

pub fn resolver(&self) -> &TokioResolver

Returns the underlying hickory resolver, for issuing DNS queries that this crate does not wrap.

Source

pub fn with_max_negative_ttl(self, ttl: Duration) -> Self

Sets the longest time a negative answer (NXDOMAIN or NODATA) is kept in the DNS caches.

Source§

impl MessageAuthenticator

Source

pub async fn verify_dkim<'x, C>( &self, params: impl Into<Parameters<'x, &'x AuthenticatedMessage<'x>, C>>, ) -> Vec<DkimOutput<'x>>
where C: DnsCache + 'x,

Verifies every DKIM-Signature header of a parsed RFC 5322 message (RFC 6376, Section 6).

params is an AuthenticatedMessage, or Parameters wrapping one together with a DNS cache. Returns one DkimOutput per signature: first a neutral output for each header rejected with a DKIM error (see DkimOutput), then one per parsed signature in header order. A message without signatures yields an empty vector; this function never fails.

For each well formed, unexpired signature whose body hash matches, it looks up the key record, a TXT record at <s>._domainkey.<d> (DomainKey). When the signature verifies and carries atps= equal to the domain of a From address, it also looks up the RFC 6541 ATPS record at <d or base32(hash(d))>._atps.<atps> (AtpsRecord); the result of that lookup becomes the result of the signature and DkimOutput::is_atps is set. Finally, for every signature with r=y that did not pass, it looks up the RFC 6651 report record at _report._domainkey.<d> (DkimReportRecord) to fill DkimOutput::report_address.

Result variants:

§Example
use mail_auth::{AuthenticatedMessage, DkimResult, MessageAuthenticator};

let authenticator = MessageAuthenticator::new_system_conf()?;
let message = AuthenticatedMessage::parse(raw_message).ok_or("invalid message")?;
let results = authenticator.verify_dkim(&message).await;
let all_pass = results.iter().all(|output| output.result() == &DkimResult::Pass);
Source§

impl MessageAuthenticator

Source

pub async fn verify_dkim2_dsn<'x, R, S, C, A, RT>( &self, params: impl Into<Parameters<'x, &'x Dkim2Dsn<'x, R, S>, C>>, envelope: Envelope<A, RT>, ) -> Result<Dkim2DsnOutput, Dkim2DsnFailure>
where R: AsRef<AuthenticatedMessage<'x>> + 'x, S: AsRef<AuthenticatedMessage<'x>> + 'x, C: DnsCache + 'x, A: AsRef<str> + Clone, RT: IntoIterator<Item: AsRef<str>> + Clone,

Authenticates an inbound DKIM2-signed delivery status notification (§16.4).

params wraps the Dkim2Dsn, optionally with a DNS cache (see Parameters). envelope is the SMTP envelope the DSN was received with, usually with a null MAIL FROM (<>).

Both messages must be DKIM2 signed. A DSN is expected to carry a single DKIM2-Signature and Message-Instance (§16.2), but a longer chain is accepted when it verifies. The DSN is verified against envelope as with verify_dkim2. The returned message is verified against the envelope recorded in its most recent signature; its body hashes are checked only when Dkim2Dsn::returned_full is true. Finally the DSN must be aligned with the returned message:

  1. An rt= recipient domain of the returned message’s most recent signature relaxed-matches the signing domain of the DSN’s i=1 signature.
  2. The d= of that signature relaxed-matches the domain of an envelope RCPT TO address, which shows that the receiving system made it.

Each chain costs one DNS TXT lookup per s= entry of each signature, for the public key at <selector>._domainkey.<d>.

On success both fields of Dkim2DsnOutput are Dkim2Result::Pass.

§Errors

Returns Dkim2DsnFailure::DsnNotSigned or Dkim2DsnFailure::ReturnedNotSigned if a message has no DKIM2-Signature header field, Dkim2DsnFailure::DsnChainFailed or Dkim2DsnFailure::ReturnedChainFailed if a chain does not pass (including temporary DNS failures), and Dkim2DsnFailure::NotAligned if the alignment checks fail.

§Example
use mail_auth::{
    MessageAuthenticator, Parameters,
    dkim2::{Dkim2Dsn, Envelope},
};

let authenticator = MessageAuthenticator::new_cloudflare_tls().unwrap();
let dsn = Dkim2Dsn::parse(raw_dsn).unwrap();

let envelope = Envelope::new("<>", ["sender@example.com"]);
match authenticator
    .verify_dkim2_dsn(Parameters::new(&dsn), envelope)
    .await
{
    Ok(_) => println!("authentic DSN"),
    Err(failure) => println!("DSN rejected: {failure}"),
}
Source§

impl MessageAuthenticator

Source

pub async fn verify_dkim2<'x, C, A, R>( &self, params: impl Into<Parameters<'x, &'x AuthenticatedMessage<'x>, C>>, envelope: Envelope<A, R>, ) -> Dkim2Output<'x>
where C: DnsCache + 'x, A: AsRef<str>, R: IntoIterator<Item: AsRef<str>>,

Verifies the DKIM2 signature chain of an RFC 5322 message: whether it is a Fully Verified DKIM2 Message (§13 and §14).

params wraps the parsed message, optionally with a DNS cache (see Parameters); a plain &AuthenticatedMessage also works. envelope is the SMTP envelope the message was received with. It must match the most recent signature: MAIL FROM equals its mf= and every RCPT TO appears in its rt=.

The verifier checks, in order, the syntax and numbering of every DKIM2-Signature and Message-Instance (§14.2), the signature timestamps (at most 14 days old and at most one day in the future, §14.3), the envelope binding, the mf=/d= match of every signature and the chain of custody (§14.4), the signatures of every DKIM2-Signature (§14.5 and §14.6), the hashes of every instance, applying recipes to recreate earlier revisions (§14.7), and that every From header field, current or recreated, is Authentic (§11 and §14.8). Signatures and hashes are combined over their , and | groups: a group passes when all its entries pass, and the tag passes when any group does. It stops once the result is known. Domains are compared as A-labels (§18).

For each s= entry it evaluates it performs one DNS TXT lookup for the public key at <selector>._domainkey.<d>, served from the cache when one is given. Entries of a group that already failed and groups after one that passed are not looked up.

The returned Dkim2Output holds one of:

  • Dkim2Result::Pass: the whole chain verified. The output lists every hop in Dkim2Output::chain.
  • Dkim2Result::Fail: verification completed but the message is not a Fully Verified DKIM2 Message: a signature, header hash or body hash did not match, a timestamp is out of range, the envelope or chain of custody does not match, a From header field is not Authentic, or a null body recipe prevents checking earlier body hashes (§13).
  • Dkim2Result::PermError: a DKIM2 header field is malformed, incomplete or missing, the numbering has a gap, the chain is longer than 50 hops, a signature or hash algorithm is not implemented, or a public key is missing, malformed, duplicated, revoked or of the wrong type, and no group passed.
  • Dkim2Result::TempError: a public key lookup failed with a temporary DNS error and no group passed.
  • Dkim2Result::None: the message has no DKIM2-Signature and no Message-Instance header field.
§Example
use mail_auth::{AuthenticatedMessage, Dkim2Result, MessageAuthenticator, dkim2::Envelope};

let authenticator = MessageAuthenticator::new_cloudflare_tls().unwrap();
let message = AuthenticatedMessage::parse(raw_message).unwrap();

let envelope = Envelope::new("sender@example.com", ["recipient@example.org"]);
let output = authenticator.verify_dkim2(&message, envelope).await;

match output.result() {
    Dkim2Result::Pass => {
        for link in output.chain() {
            println!("hop {} signed by {}", link.signature.i, link.signature.d);
        }
    }
    Dkim2Result::None => println!("not DKIM2 signed"),
    _ => println!("DKIM2 failed: {:?}", output.error()),
}
Source

pub async fn verify_dkim2_provisionally<'x, C, A, R>( &self, params: impl Into<Parameters<'x, &'x AuthenticatedMessage<'x>, C>>, envelope: Envelope<A, R>, ) -> Dkim2Output<'x>
where C: DnsCache + 'x, A: AsRef<str>, R: IntoIterator<Item: AsRef<str>>,

Checks whether a message is Provisionally Verified (§13.2): the initial assessment a receiver may make before accepting delivery, and the precondition for later sending a DSN about the message.

Performs the header field validity, timestamp and envelope checks of verify_dkim2, then verifies only the most recent signature and the hashes of the most recent Message-Instance. It does not check the chain of custody of earlier hops, earlier signatures or hashes, or whether From header fields are Authentic. A most recent signature with nd= is a Dkim2Result::Fail (§14.4).

A passing result is reported with Verification::Provisional, its Dkim2Output::chain holds only the most recent signature, and it is neither a proof of validity for Dkim2Signer nor an authenticated identity for DMARC or Authentication-Results.

Source§

impl MessageAuthenticator

Source

pub async fn verify_dmarc<'x, C>( &self, params: impl Into<Parameters<'x, DmarcParameters<'x>, C>>, ) -> DmarcOutput
where C: DnsCache + 'x,

Evaluates the DMARC policy of a message (RFC 9989, Section 4.10).

The Author Domain is taken from the RFC5322.From header. Messages without a From domain, or whose From header lists several different domains, are exempt and yield an empty output (result None).

DNS lookups performed:

  • A DNS Tree Walk of TXT queries for _dmarc.<name>, from the Author Domain up to the top-level domain, capped at eight queries. A record with psd=y or psd=n stops the walk. The Author Domain’s own record applies if present, otherwise the Organizational Domain’s, otherwise the shortest one found.
  • An A query for the Author Domain when a record found above it has np different from sp, to tell a non-existent subdomain (NXDOMAIN, RFC 8020) from an existing one.
  • Further Tree Walks to find the Organizational Domain of SPF and DKIM identifiers under relaxed alignment.

A record without a valid p tag is treated as p=none when it has a valid rua tag; otherwise DMARC does not apply.

The returned DmarcOutput carries per-mechanism results (DmarcOutput::spf_result, DmarcOutput::dkim_result) and the overall DmarcOutput::result:

§Example
use mail_auth::{
    AuthenticatedMessage, DmarcResult, MessageAuthenticator, dmarc::Policy,
    dmarc::verify::DmarcParameters, spf::verify::SpfParameters,
};

let message = AuthenticatedMessage::parse(raw_message).unwrap();
let dkim_output = authenticator.verify_dkim(&message).await;
let spf_output = authenticator
    .verify_spf(SpfParameters::mail_from(
        "192.0.2.1".parse().unwrap(),
        "mx.example.org",
        "mx.my-host.org",
        "sender@example.org",
    ))
    .await;
let dmarc_output = authenticator
    .verify_dmarc(DmarcParameters::new(
        &message,
        &dkim_output,
        "example.org",
        &spf_output,
    ))
    .await;

if matches!(dmarc_output.result(), DmarcResult::Fail(_))
    && dmarc_output.policy() == Policy::Reject
{
    println!("reject message from {}", dmarc_output.domain());
}
Source

pub async fn authorized_report_addresses<'x, 'y, T, C>( &self, params: impl Into<Parameters<'y, (&'y str, &'x [T]), C>>, ) -> Result<Vec<&'x T>>
where T: AsRef<str> + 'x, C: DnsCache + 'y,

Returns the reporting addresses that are authorized to receive DMARC reports for a policy domain (RFC 9989).

Takes a (policy_domain, addresses) pair, optionally wrapped in Parameters to supply a DNS cache. addresses is usually DmarcRecord::rua or DmarcRecord::ruf, but any AsRef<str> holding an email address works. An address is authorized when its domain is the policy domain or a subdomain of it (internal), or, for an external destination, when a v=DMARC1 TXT record exists at <policy_domain>._report._dmarc.<destination_domain>. One TXT lookup is performed per external address. Addresses are returned in input order.

§Errors

Returns Error::Dns with DnsError::Resolver when a lookup fails with a transient resolver error. A missing or invalid authorization record is not an error: the address is left out.

§Example
use mail_auth::{DmarcOutput, MessageAuthenticator};

if let Some(record) = output.record() {
    let authorized = authenticator
        .authorized_report_addresses((output.domain(), record.rua()))
        .await?;
    for uri in authorized {
        println!("send aggregate report to {}", uri.uri());
    }
}
Source§

impl MessageAuthenticator

Source

pub fn new_cloudflare_tls() -> Result<Self, NetError>

Creates an authenticator that queries Cloudflare’s public resolvers over DNS-over-TLS (RFC 7858). Requires the aws-lc-rs feature.

§Errors

Returns a NetError if the resolver cannot be built.

Source

pub fn new_cloudflare() -> Result<Self, NetError>

Creates an authenticator that queries Cloudflare’s public resolvers over UDP and TCP.

§Errors

Returns a NetError if the resolver cannot be built.

Source

pub fn new_google() -> Result<Self, NetError>

Creates an authenticator that queries Google’s public resolvers over UDP and TCP.

§Errors

Returns a NetError if the resolver cannot be built.

Source

pub fn new_quad9() -> Result<Self, NetError>

Creates an authenticator that queries Quad9’s public resolvers over UDP and TCP.

§Errors

Returns a NetError if the resolver cannot be built.

Source

pub fn new_quad9_tls() -> Result<Self, NetError>

Creates an authenticator that queries Quad9’s public resolvers over DNS-over-TLS (RFC 7858). Requires the aws-lc-rs feature.

§Errors

Returns a NetError if the resolver cannot be built.

Source

pub fn new_system_conf() -> Result<Self, NetError>

Creates an authenticator that uses the system resolver configuration (/etc/resolv.conf on Unix, the registry on Windows).

§Errors

Returns a NetError if the system configuration cannot be read or the resolver cannot be built.

Source

pub fn new( config: ResolverConfig, options: ResolverOpts, ) -> Result<Self, NetError>

Creates an authenticator from an explicit hickory resolver configuration and options.

§Errors

Returns a NetError if the resolver cannot be built.

Source§

impl MessageAuthenticator

Source

pub async fn txt_raw_lookup(&self, key: impl ToFqdn) -> Result<Vec<u8>>

Queries the TXT records of key and returns their contents concatenated into one byte string, without parsing or caching.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name.

Source

pub async fn txt_lookup<T: TxtRecordParser + Into<TxtRecord> + UnwrapTxtRecord>( &self, key: impl ToFqdn, cache: Option<&impl ResolverCache<Box<str>, TxtRecord>>, ) -> Result<Arc<T>>

Queries the TXT records of key and returns the first one that parses as T (for example SpfRecord, DmarcRecord or TlsRptRecord).

When cache is set, a cached entry is returned without querying, and the parse outcome (the record or the parse error) is stored after a query. A negative answer that carries an SOA record is stored as TxtRecord::Error until its negative TTL expires.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name. When no record parses as T, returns the error of the last parse attempt (usually DnsError::InvalidRecordType), or InvalidRecordType when the answer holds no TXT data.

Source

pub async fn mx_lookup( &self, key: impl ToFqdn, cache: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Mx>, Negative>>>, ) -> Result<RecordSet<Mx>>

Queries the MX records of key (RFC 5321 Section 5.1).

Records are grouped by preference into Mx values sorted by ascending preference. When cache is set, it is consulted before and updated after the query; a negative answer that carries an SOA record is stored as Err(Negative) until its negative TTL expires.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name.

Source

pub async fn ipv4_lookup( &self, key: impl ToFqdn, cache: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Ipv4Addr>, Negative>>>, ) -> Result<RecordSet<Ipv4Addr>>

Queries the A records of key. When cache is set, it is consulted before and updated after the query; a negative answer that carries an SOA record is stored as Err(Negative) until its negative TTL expires.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name.

Source

pub async fn ipv4_lookup_raw( &self, key: &str, ) -> Result<DnsEntry<Arc<[Ipv4Addr]>>>

Queries the A records of key without caching. key is queried as given, without conversion to a fully qualified name. Returns the addresses with their expiry time.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name.

Source

pub async fn ipv6_lookup( &self, key: impl ToFqdn, cache: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Ipv6Addr>, Negative>>>, ) -> Result<RecordSet<Ipv6Addr>>

Queries the AAAA records of key. When cache is set, it is consulted before and updated after the query; a negative answer that carries an SOA record is stored as Err(Negative) until its negative TTL expires.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name.

Source

pub async fn ipv6_lookup_raw( &self, key: &str, ) -> Result<DnsEntry<Arc<[Ipv6Addr]>>>

Queries the AAAA records of key without caching. key is queried as given, without conversion to a fully qualified name. Returns the addresses with their expiry time.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the name has no records of this type, DnsError::Resolver when the query fails, or Error::Parse when the name is not a valid DNS name.

Source

pub async fn ip_lookup( &self, key: &str, strategy: IpLookupStrategy, max_results: usize, cache_ipv4: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Ipv4Addr>, Negative>>>, cache_ipv6: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Ipv6Addr>, Negative>>>, ) -> Result<Vec<IpAddr>>

Resolves key to at most max_results IP addresses, querying A and AAAA records in the order given by strategy.

With a fallback strategy (IpLookupStrategy::Ipv4thenIpv6 or IpLookupStrategy::Ipv6thenIpv4), any error from the first query triggers the second one. The caches are consulted before and updated after each query.

§Errors

Returns the error of the last query performed. See ipv4_lookup for the possible errors.

Source

pub async fn ptr_lookup( &self, addr: IpAddr, cache: Option<&impl ResolverCache<IpAddr, Result<RecordSet<Box<str>>, Negative>>>, ) -> Result<RecordSet<Box<str>>>

Queries the PTR records of addr (reverse DNS). Host names are returned lowercased. When cache is set, it is consulted before and updated after the query; a negative answer that carries an SOA record is stored as Err(Negative) until its negative TTL expires.

§Errors

Returns Error::Dns with DnsError::RecordNotFound when the address has no PTR record, or DnsError::Resolver when the query fails.

Source

pub async fn exists( &self, key: impl ToFqdn, cache_ipv4: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Ipv4Addr>, Negative>>>, cache_ipv6: Option<&impl ResolverCache<Box<str>, Result<RecordSet<Ipv6Addr>, Negative>>>, ) -> Result<bool>

Returns true if key has at least one A or AAAA record, as needed by the SPF exists mechanism (RFC 7208 Section 5.7).

Returns true without querying when a cache holds an A or AAAA answer with records, and false without querying when the caches hold a negative or empty answer for both types. Query results are not added to the caches.

§Errors

Returns Error::Dns with DnsError::Resolver when a query fails, or Error::Parse when the name is not a valid DNS name. A name without records is not an error.

Source§

impl MessageAuthenticator

Source

pub async fn verify_iprev<'x, C>( &self, params: impl Into<Parameters<'x, IpAddr, C>>, ) -> IprevOutput
where C: DnsCache + 'x,

Verifies the reverse DNS of an SMTP client IP address (RFC 8601 Section 3).

params is the client IP address, either alone or wrapped in Parameters together with a DNS cache.

The check performs these DNS lookups:

  1. A PTR query for the IP address.
  2. For each of the first two names returned, an A query (IPv4 client) or AAAA query (IPv6 client).

The result is:

IprevOutput::ptr holds the PTR names whenever the PTR lookup succeeded.

§Example
use mail_auth::{AuthenticationResults, IprevResult, MessageAuthenticator};
use std::net::IpAddr;

let authenticator = MessageAuthenticator::new_cloudflare_tls().unwrap();
let remote_ip: IpAddr = "192.0.2.10".parse().unwrap();

let iprev = authenticator.verify_iprev(remote_ip).await;
if iprev.result() == &IprevResult::Pass {
    println!("PTR names: {:?}", iprev.ptr);
}

let header = AuthenticationResults::new("mx.example.org")
    .with_iprev_result(&iprev, remote_ip)
    .to_string();
Source§

impl MessageAuthenticator

Source

pub async fn verify_spf<'x, C>( &self, params: impl Into<Parameters<'x, SpfParameters<'x>, C>>, ) -> SpfOutput
where C: DnsCache + 'x,

Verifies the SPF identities of an SMTP session (RFC 7208).

With parameters built by SpfParameters::helo_and_mail_from (or SpfParameters::new), the HELO identity is checked first. Its output is returned when the result is fail or the sender is empty; otherwise the MAIL FROM identity is checked and its output returned. With parameters built by SpfParameters::helo or SpfParameters::mail_from, a single check_host is run for that identity.

The DNS lookups performed are those of check_host, once per identity checked. See SpfResult for the meaning of each result.

§Example
use mail_auth::{MessageAuthenticator, SpfResult, spf::verify::SpfParameters};

let output = authenticator
    .verify_spf(SpfParameters::helo_and_mail_from(
        "192.0.2.1".parse().unwrap(),
        "mx.example.org",
        "mx.my-host.org",
        "sender@example.org",
    ))
    .await;

if output.result() == SpfResult::Fail {
    println!("rejected: {:?}", output.explanation());
}
Source

pub async fn check_host<'x, C>( &self, params: impl Into<Parameters<'x, SpfParameters<'x>, C>>, ) -> SpfOutput
where C: DnsCache + 'x,

Runs the check_host() function (RFC 7208, Section 4) for a single identity.

Evaluates the SPF record of the parameters’ domain against the client IP. The DNS lookups performed are:

  • TXT for the v=spf1 record of the domain, and of every include: and redirect= target.
  • A or AAAA (depending on the client IP family) for the a, mx, ptr and exists mechanisms.
  • MX for the mx mechanism.
  • PTR for the ptr mechanism and the p macro.
  • TXT for the exp= explanation, only on a fail result.

The number of DNS-querying mechanisms and modifiers is limited to 10 and the whole evaluation to 20 seconds; an mx mechanism may resolve at most 10 exchanges. Exceeding a limit yields permerror.

The returned SpfOutput holds one of:

§Example
use mail_auth::{MessageAuthenticator, spf::verify::SpfParameters};

let output = authenticator
    .check_host(SpfParameters::new(
        "192.0.2.1".parse().unwrap(),
        "example.org",
        "mx.example.org",
        "mx.my-host.org",
        "sender@example.org",
    ))
    .await;
println!("spf={} domain={}", output.result(), output.domain());

Trait Implementations§

Source§

impl Clone for MessageAuthenticator

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

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<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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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.

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> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<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