Skip to main content

EnvelopeLayerBuilder

Struct EnvelopeLayerBuilder 

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

Configuration for an super::EnvelopeLayer. Nothing is checked until build, and the calls may come in any order.

Implementations§

Source§

impl EnvelopeLayerBuilder

Source

pub fn build(self) -> Result<EnvelopeLayer, CratestackError>

Check the configuration: CratestackError::Validation when the audience is empty (it would bind no recipient), the policy or the transport is missing, the REST route table is empty (a rest(..) given another schema’s, or an RPC schema’s, empty table would bind nothing), the body limit or the contract trials is zero, an allow-listed template does not start with /, or the envelope’s media type is not a valid header value naming application/cose or a type the envelope claims.

Source§

impl EnvelopeLayerBuilder

Source

pub fn policy(self, policy: impl EnvelopePolicy) -> EnvelopeLayerBuilder

Which mode each op runs in: an super::EnvelopeMode for all of them, or a closure per op. Required (decision D9).

Source

pub fn rest( self, prefix: &str, routes: &'static [RouteTransportDescriptor], ) -> EnvelopeLayerBuilder

A REST router mounted at prefix ("" at the root), over the generated cratestack_schema::axum::ROUTE_TRANSPORTS, which must not be empty.

Source

pub fn rpc(self, prefix: &str) -> EnvelopeLayerBuilder

A transport rpc router mounted at prefix ("" at the root).

Source

pub fn binding_resolver( self, resolver: impl BindingResolver, ) -> EnvelopeLayerBuilder

A custom BindingResolver, instead of rest or rpc.

Source

pub fn mount_prefix(self, prefix: &str) -> EnvelopeLayerBuilder

Where the router is mounted ("/api" for Router::nest("/api", router)). It wins over the prefix given to rest or rpc, whichever order the calls come in: the generated envelope_layer passes the root to those, so this is how its layer is told about a mount. Also what allow_unresolved templates are relative to.

Source

pub fn allow_unresolved<I, T>(self, templates: I) -> EnvelopeLayerBuilder
where I: IntoIterator<Item = T>, T: Into<String>,

Route templates (as given to Router::route, relative to the mount prefix, e.g. "/health") that the router may match without the resolver knowing them: hand-written routes merged into the generated router before the layer. Plain traffic to them passes through unsigned. Any other matched route the resolver cannot bind fails closed with a 500 when the policy’s unresolved_mode is Required (decision S2), which is what a wrong or missing mount prefix looks like. A COSE body to an allow-listed route is still refused (415).

Source

pub fn unresolved_mode(self, mode: EnvelopeMode) -> EnvelopeLayerBuilder

Replace the policy’s unresolved_mode with mode, whatever the policy answers (second-review nit). An explicit opt-in, mostly for a closure policy, whose unresolved_mode is always Required: with Optional or Off here, a matched route the resolver cannot bind passes through plain (warned about once per process) instead of failing closed with the 500, and so does every route when the mount prefix is wrong. It also lets through a method the schema does not generate on a generated path (normally the layer’s own 405), so a hand-written handler for that method runs unsigned. Prefer listing hand-written routes with allow_unresolved, which keeps a misconfiguration loud. The ops’ own modes are unchanged; a /rpc/batch whose frames cannot be read uses this mode too.

Source

pub fn principal_mapper( self, mapper: impl PrincipalMapper, ) -> EnvelopeLayerBuilder

Replace super::ThumbprintPrincipal (cose:<hex thumbprint>; ThumbprintPrincipal::with_prefix(..) keeps the thumbprint and changes the prefix).

Source

pub fn response_seal_policy( self, policy: impl ResponseSealPolicy, ) -> EnvelopeLayerBuilder

Replace super::AcceptNamesEnvelope (decision D10).

Source

pub fn max_contract_trials(self, trials: usize) -> EnvelopeLayerBuilder

How many accepted digests the layer tries for a request that names none (no Cratestack-Contract header: a hand-built client), newest first. Default super::DEFAULT_MAX_CONTRACT_TRIALS; at least 1. A request that does name one is verified under it alone, so an up-to-date generated client costs one verification however long an op’s accepted list grows, and a forged request without the header costs one parse, one key resolution and at most this many signature verifications (the COSE envelope’s open_request_any; a custom ServerEnvelope that keeps the default pays the parse and the resolution per trial). A failed trial records no nonce.

Source

pub fn max_body_bytes(self, limit: usize) -> EnvelopeLayerBuilder

The largest request body the layer buffers. Default super::DEFAULT_MAX_BODY_BYTES; keep it a little above the router’s own body limit, which applies to the payload after opening.

Source§

impl EnvelopeLayerBuilder

Source

pub fn payload_media_types<I, J>( self, request: I, response: J, ) -> EnvelopeLayerBuilder

The payload media types the layer allows inside the seal: request for what a client seals, response for what the layer seals back. Default: application/cbor for both, so a layer that never calls this changes nothing for anyone: a request that names no type is bound and opened with the bytes 0.15.3 used (AAD and body), and answered by a response whose AAD and body are 0.15.3’s too. The one difference a 0.15.3 client can see is a new response header, Cratestack-Payload-Type, which it ignores.

A client names the type of its request in the unbound Cratestack-Payload-Type header and the response types it reads, in order, in Cratestack-Payload-Accept (the same selector pattern as Cratestack-Contract: they select among what is allowed and never widen it). Both are authenticated by the binding, not by the headers: a request binding names the request payload’s type, a response binding names the response payload’s own type, and a response repeats it in Cratestack-Payload-Type. A header that lies about the request fails the signature with the coarse 401. Binding version 2 and the COSE wire are unchanged.

What an op allows is this set intersected with the route’s declared types (ResolvedRoute::with_payload_types, filled from the schema’s capabilities by RestBindingResolver and RpcBindingResolver). /rpc/batch stays CBOR both ways. An empty route list (the generated reads and deletes, which take no payload) constrains nothing, and a GET, HEAD or DELETE is not checked for the type its empty payload names (bound as sent, never refused): a payload that is not empty is held to this set and the route’s once opened, and refused as a sealed 415.

A retry under the same Idempotency-Key must repeat its Cratestack-Payload-Accept: the idempotency layer fingerprints the request’s content type and body, not the types it reads, so a response stored for the first attempt in a type the retry did not negotiate is never sealed for it (a sealed 500, fail closed).

Refusals are unsigned and made before any key is looked up or nonce spent: a selector header sent twice or malformed is a 400, a request type outside the op’s set a 415 (payload_type_unsupported), and a Cratestack-Payload-Accept with no type the op can answer in a 406 (payload_type_not_acceptable). A handler’s success in a type the request did not negotiate is a sealed 500; its error in one is re-encoded in the transport’s error shape, in the client’s first choice of CBOR or JSON, and sealed.

build refuses a type outside the grammar of cratestack_core::parse_payload_type, one that may never be sealed (application/cose*, application/cbor-seq, text/event-stream, multipart/*), an empty request set, and a response set without application/cbor or application/json, which the layer’s own errors are sealed in.

use cratestack_axum::envelope_layer::EnvelopeLayer;
// vpay's shape: forms in, JSON out, and CBOR for the generated clients.
let builder = EnvelopeLayer::builder(envelope, "payments", &[]).payload_media_types(
    ["application/cbor", "application/x-www-form-urlencoded"],
    ["application/cbor", "application/json"],
);

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

§

impl<T> Instrument for T

§

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

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

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
§

impl<'src, T> IntoMaybe<'src, T> for T
where T: 'src,

§

type Proj<U: 'src> = U

§

fn map_maybe<R>( self, _f: impl FnOnce(&'src T) -> &'src R, g: impl FnOnce(T) -> R, ) -> <T as IntoMaybe<'src, T>>::Proj<R>
where R: 'src,

Source§

impl<T> MaybeSend for T
where T: Send + ?Sized,

Source§

impl<T> MaybeSendSync for T
where T: Send + Sync + ?Sized,

§

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

§

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();
§

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

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

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

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

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

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

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));
§

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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();
§

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

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

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

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

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

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

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));
§

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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();
§

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

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

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

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

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

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

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

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

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

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());
§

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

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

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

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

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

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

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

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

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

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();
§

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

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

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

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

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

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

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

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

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

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());
§

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

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

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

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

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

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

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

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

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

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);
§

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

Create a new [Painted] with a default [Style]. Read more
§

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
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T, S> SpanWrap<S> for T
where S: WrappingSpan<T>,

§

fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned

Invokes [WrappingSpan::make_wrapped] to wrap an AST node in a span.
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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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