Expand description
The field sections of protocol messages, interpreted into typed structs.
HTTP (RFC 9110 section 6), the Internet Message Format of email (RFC 5322), and MIME parts (RFC 2045) share one message structure: header and trailer sections of named fields, around the content. This crate interprets those sections. Each FieldType says how its instances combine and how one value parses, and #[derive(FieldSection)] generates the interpretation of a whole section, so duplicate singletons, lists with quoted commas, forbidden fields, and unknown fields are handled in one reviewed place rather than by each consumer.
use base_message::{FieldSection, FieldType, FieldValueError, ascii_text, combination::{List, Singleton}};
/// A field type that borrows its value from the input.
struct Host<'a>(&'a str);
impl<'a> FieldType<'a> for Host<'a> {
type Combination = Singleton;
fn parse(value: &'a [u8]) -> Result<Self, FieldValueError> {
ascii_text(value).map(Self)
}
}
/// A field type that owns its value.
struct Accept(String);
impl FieldType<'_> for Accept {
type Combination = List;
fn parse(value: &[u8]) -> Result<Self, FieldValueError> {
Ok(Self(ascii_text(value)?.to_owned()))
}
}
#[derive(FieldSection)]
#[fields(forbid("transfer-encoding"))]
struct Request<'a> {
#[field("host")]
host: Host<'a>,
#[field("accept")]
accept: Vec<Accept>,
}
let fields = [("Host", "example.com"), ("Accept", "text/html, image/*"), ("User-Agent", "curl/8")];
let request = Request::interpret(fields)?;
assert_eq!(request.host.0, "example.com");
assert_eq!(request.accept.len(), 2);
let duplicate = Request::interpret([("Host", "a"), ("Host", "b")]).err().expect("a duplicate host");
assert_eq!(duplicate.to_string(), "duplicate host field at position 1, first at 0");The crate interprets field sections only. Parsing them from the wire, as well as control data, such as a request line or status, content, framing, and transport, belongs to each protocol’s own crate, which passes the fields it parses as name and value pairs in wire order. The Getting Started guide covers field types and sections, and the Layering guide covers passing fields between layers, trailers, and static tables.
Modules§
- combination
- How the instances of a field combine, as a type-level marker on each
FieldType.
Structs§
- Field
Error - Why a field section could not be interpreted, naming the field and its position in the original section.
- Field
Names - The lowercase field names a section declares and forbids, with those of the sections it flattens, and whether it rejects unknown fields, as a constant.
- Field
Ref - One field, borrowed, with its position in the original section.
- Field
Value Error - Why a field value is invalid, as a fixed description. It never includes the value, which may be large or untrusted.
- List
Elements - The elements of one instance of a list field, as
split_listproduces them. - Owned
Field - One field, owned, with its position in the original section.
- Owned
Fields - A remainder that owns its fields, for keeping the fields a section does not take beyond the lifetime of the input, in order.
- Static
Table Entry - One entry of a protocol’s static table of field names, classified for section
Sbystatic_table_entries.
Enums§
- Classification
- How a name in a protocol’s static table relates to a section.
- Field
Error Kind - The kind of
FieldError. - Field
Name - How a decoder with a static table names one field for section
S: by an entry of the table, classified forS, or as text when the name was sent literally. - Invalid
Value - What an invalid value means for a section.
Traits§
- Field
Section - A field section interpreted into a struct. It is implemented only by
#[derive(FieldSection)]. - Field
Type - One kind of field: how its instances combine, how one value parses, and what an invalid value means.
- Into
Field - Something section
Scan interpret as one field.
Functions§
- ascii_
text - The value as text, when it is visible ASCII, spaces, and tabs, as most field grammars require.
- split_
list - Split one instance of a list field into its elements, as RFC 9110 section 5.6.1 describes: a comma inside a quoted string does not separate elements, spaces and tabs around each element are removed, and empty elements are skipped.
- static_
table_ entries - Classify each name in a protocol’s static table of lowercase field names, such as HPACK’s or QPACK’s, for section
S, at compile time, so a decoder can interpret indexed fields without comparing names. - trim_
whitespace - Remove spaces and tabs from both ends, the optional whitespace of RFC 9110 section 5.6.3.
Derive Macros§
- Field
Section - Derive the interpretation of a field section from a struct’s declarations.