Skip to main content

ContextPiece

Enum ContextPiece 

Source
#[non_exhaustive]
pub enum ContextPiece<'a> {
Show 15 variants Text(Cow<'a, str>), Bytes(Cow<'a, [u8]>), Unit, U8(u8), U16(u16), U32(u32), U64(u64), U128(u128), I8(i8), I16(i16), I32(i32), I64(i64), I128(i128), Encoded(Cow<'a, [u8]>), List(Vec<ContextPiece<'a>>),
}
Expand description

One part of a context, or a list of parts.

IntoContext::into_context builds one from any context type, and encode turns it into the bytes both the AEAD and the PRF use. The tree is a stand-in for the value it was built from: a runtime list with the same parts is the same context as the static value, on both sides, because there is only one encoding.

use std::borrow::Cow;
use vitaminc_context::{ContextPiece, IntoContext};

let value = ("users/email", 7u64);
let runtime = ContextPiece::List(vec![
    ContextPiece::Text(Cow::Borrowed("users/email")),
    ContextPiece::U64(7),
]);
assert_eq!(runtime.encode(), value.into_context().encode());

This matters for a context that arrives as data rather than as a Rust type, for example across an FFI boundary. It needs no mirror type of its own:

  • Some(x) is the one-element list and None is the empty list;
  • (a, b) is the two-element list;
  • nonempty!(a).with(b).with(c) is the nested list ((a, b), c);
  • () is Unit.

A flat list of three or more parts is also a valid context. It has no tuple spelling in Rust, so build it with List directly.

Display renders a tree so that different trees never print the same, for example ("users/email", 7u64), and leaves walks the parts in encoding order for a caller that wants to render or bind them itself.

PartialEq compares trees, not encodings, and since every typed leaf is tagged, trees that differ encode differently too. The one exception is Encoded: a Bytes leaf and an Encoded leaf holding that leaf’s encoding are unequal as trees and equal as bytes, which is what Encoded is for.

MaybeEmpty is implemented by the same rule the static types use, so a tree can be wrapped in NonEmpty: text and bytes are empty at zero length, unit is empty, an integer never is, and a list is empty only when every part is. Encoded counts as empty whatever its bytes, because framing hides whether the value behind them carried anything.

The enum is #[non_exhaustive], so a new kind of leaf must not break a downstream match.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Text(Cow<'a, str>)

Text; a typed leaf of its UTF-8 bytes. &str, String.

§

Bytes(Cow<'a, [u8]>)

Opaque bytes; a typed leaf of the bytes themselves. Byte slices and arrays, Vec<u8>, Cow<[u8]>.

§

Unit

The unit context, (). Encodes as no bytes at all. Not the same as empty bytes, which are a typed leaf, or the empty list, which is framed.

§

U8(u8)

A u8; a typed leaf of one little-endian byte.

§

U16(u16)

A u16; a typed leaf of two little-endian bytes.

§

U32(u32)

A u32; a typed leaf of four little-endian bytes.

§

U64(u64)

A u64; a typed leaf of eight little-endian bytes.

§

U128(u128)

A u128; a typed leaf of sixteen little-endian bytes.

§

I8(i8)

An i8; a typed leaf of one two’s-complement byte.

§

I16(i16)

An i16; a typed leaf of two little-endian two’s-complement bytes.

§

I32(i32)

An i32; a typed leaf of four little-endian two’s-complement bytes.

§

I64(i64)

An i64; a typed leaf of eight little-endian two’s-complement bytes.

§

I128(i128)

An i128; a typed leaf of sixteen little-endian two’s-complement bytes.

§

Encoded(Cow<'a, [u8]>)

Bytes this encoder already produced; encodes as itself, untagged. The parts view of a Context, which is how a stored or derived context is passed back in as a value. Only Context::from_encoded and the derived-context methods on Context produce one. It counts as empty whatever its bytes, because framing hides whether the value behind them carried anything.

§

List(Vec<ContextPiece<'a>>)

A list of parts; encodes as their PAE. A tuple is the list of its halves, Some(x) the one-element list, None the empty list.

Implementations§

Source§

impl<'a> ContextPiece<'a>

Source

pub fn encode(self) -> Context<'a>

The canonical bytes of this context.

A typed leaf and a list allocate exactly once, sized up front. Unit allocates nothing. Encoded hands its bytes through as they are, so a borrowed encoded context stays borrowed.

Source

pub fn into_owned(self) -> ContextPiece<'static>

Copy every borrowed part, so the tree can outlive its source.

Source

pub fn leaves(&self) -> impl Iterator<Item = &ContextPiece<'a>>

The non-list parts, depth first, in the order they are encoded. A leaf piece yields itself; an empty list yields nothing.

Nesting is dropped, so distinct contexts can share a leaf sequence: (("a", 1u8), "b") and ("a", (1u8, "b")) both yield a, 1, b while encoding to different bytes. Use this to render or bind the parts, not to identify the context; the bytes from encode are its identity.

Trait Implementations§

Source§

impl<'a> Clone for ContextPiece<'a>

Source§

fn clone(&self) -> ContextPiece<'a>

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

impl<'a> Debug for ContextPiece<'a>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Display for ContextPiece<'_>

Renders the tree in Rust literal syntax, and different trees never render the same. Text is quoted and escaped as Debug does, integers carry their type suffix, bytes print as 0x-prefixed hex, encoded bytes print as Encoded(0x…), unit prints as (), a list is parenthesised and comma-separated, and the empty list prints as None (the context it is). So ("users/email", 7u64) prints as ("users/email", 7u64).

Each kind starts differently: " for text, a digit or - for an integer, 0x for bytes, E for encoded bytes, () for unit, ( followed by a part for a list, and None for the empty list. Integer suffixes keep types of the same width apart, and quoting keeps separators inside text from reading as structure. Two contexts that encode to different bytes therefore never share a log line.

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<'a> Eq for ContextPiece<'a>

Source§

impl<'a> IntoContext<'a> for ContextPiece<'a>

The tree of a tree is itself.

Source§

fn into_context(self) -> ContextPiece<'a>

Describe self as a tree of parts.
Source§

impl MaybeEmpty for ContextPiece<'_>

The same emptiness rule the static types use, applied to the tree. Text and bytes are empty at zero length. Unit is empty. An integer is never empty, because even zero is information the caller chose. A list is empty only when every part is, so None and Some("") are empty and ("", 7u64) is not, matching what Option<T> and (A, B) decide.

An Encoded leaf counts as empty whatever its bytes, because those bytes cannot say whether the value behind them carried anything: framing gives an empty value a non-empty encoding, so None arrives back as an eight-byte count word and a byte check would certify exactly the degenerate context NonEmpty exists to exclude. It is the same reason Context has no MaybeEmpty impl of its own. An encoded context therefore never contributes to a proof: prove the value non-empty before it is encoded, or extend a proven head with NonEmpty::with, which pairs a tail in without checking it.

Source§

fn is_empty(&self) -> bool

Returns true if this value carries no caller-supplied bytes.
Source§

impl<'a> PartialEq for ContextPiece<'a>

Source§

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

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

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

Inequality operator !=. Read more
Source§

impl<'a> StructuralPartialEq for ContextPiece<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for ContextPiece<'a>

§

impl<'a> RefUnwindSafe for ContextPiece<'a>

§

impl<'a> Send for ContextPiece<'a>

§

impl<'a> Sync for ContextPiece<'a>

§

impl<'a> Unpin for ContextPiece<'a>

§

impl<'a> UnsafeUnpin for ContextPiece<'a>

§

impl<'a> UnwindSafe for ContextPiece<'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<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, 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> Same for T

Source§

type Output = T

Should always be Self
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> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. 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.