/*! `sfv`isanimplementationof*StructuredFieldValuesforHTTP*,asspecifiedin[RFC9651](https://httpwg.org/specs/rfc9651.html) for parsing and serializing HTTP field values. Italsoexposesasetoftypesthatmightbeusefulfordefiningnewstructuredfields.
``` # use sfv::{Dictionary, Item, List, Parser}; # fn main() -> Result<(), sfv::Error> { // Parsing a structured field value of Item type. let input = "12.445;foo=bar"; let item: Item = Parser::new(input).parse()?;
println!("{:#?}", item);
// Parsing a structured field value of List type. let input = r#"1;a=tok, ("foo""bar");baz, ()"#; let list: List = Parser::new(input).parse()?;
println!("{:#?}", list);
// Parsing a structured field value of Dictionary type. let input = "a=?0, b, c; foo=bar, rating=1.5, fruits=(apple pear)"; let dict: Dictionary = Parser::new(input).parse()?;
println!("{:#?}", dict); # Ok(()) # }
```
### Getting Parsed Value Members
``` # use sfv::*; # fn main() -> Result<(), sfv::Error> { let input = "u=2, n=(* foo 2)"; let dict: Dictionary = Parser::new(input).parse()?;
-`parsed-types`(enabledbydefault)--Whenenabled,exposesfullyownedtypes `Item`,`Dictionary`,`List`,andtheircomponents,whichcanbeobtainedfrom `Parser::parse_item`,etc.Thesetypesareimplementedusingthe [`indexmap`](https://crates.io/crates/indexmap) crate, so disabling this featurecanavoidthatdependencyifparsingusingavisitor ([`Parser::parse_item_with_visitor`],etc.)issufficient.
mod date; mod decimal; mod error; mod integer; mod key; #[cfg(feature = "parsed-types")] mod parsed; mod parser; mod ref_serializer; mod serializer; mod string; mod token; mod utils; pubmod visitor;
#[cfg(test)] mod test_decimal; #[cfg(test)] mod test_integer; #[cfg(test)] mod test_key; #[cfg(test)] mod test_parser; #[cfg(test)] mod test_ref_serializer; #[cfg(test)] mod test_serializer; #[cfg(test)] mod test_string; #[cfg(test)] mod test_token;
use std::borrow::{Borrow, Cow}; use std::fmt; use std::string::String as StdString;
type SFVResult<T> = std::result::Result<T, Error>;
/// An abstraction over multiple kinds of ownership of a [bare item]. /// /// In general most users will be interested in: /// - [`BareItem`], for completely owned data /// - [`RefBareItem`], for completely borrowed data /// - [`BareItemFromInput`], for data borrowed from input when possible /// /// [bare item]: <https://httpwg.org/specs/9651.html#item> #[derive(Debug, Clone, Copy)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pubenum GenericBareItem<S, B, T, D> { /// A [decimal](https://httpwg.org/specs/rfc9651.html#decimal). // sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT
Decimal(Decimal), /// An [integer](https://httpwg.org/specs/rfc9651.html#integer). // sf-integer = ["-"] 1*15DIGIT
Integer(Integer), /// A [string](https://httpwg.org/specs/rfc9651.html#string). // sf-string = DQUOTE *chr DQUOTE // chr = unescaped / escaped // unescaped = %x20-21 / %x23-5B / %x5D-7E // escaped = "\" ( DQUOTE / "\" )
String(S), /// A [byte sequence](https://httpwg.org/specs/rfc9651.html#binary). // ":" *(base64) ":" // base64 = ALPHA / DIGIT / "+" / "/" / "="
ByteSequence(B), /// A [boolean](https://httpwg.org/specs/rfc9651.html#boolean). // sf-boolean = "?" boolean // boolean = "0" / "1"
Boolean(bool), /// A [token](https://httpwg.org/specs/rfc9651.html#token). // sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" )
Token(T), /// A [date](https://httpwg.org/specs/rfc9651.html#date). /// /// [`Parser`] will never produce this variant when used with /// [`Version::Rfc8941`]. // sf-date = "@" sf-integer
Date(Date), /// A [display string](https://httpwg.org/specs/rfc9651.html#displaystring). /// /// Display Strings are similar to [`String`]s, in that they consist of zero /// or more characters, but they allow Unicode scalar values (i.e., all /// Unicode code points except for surrogates), unlike [`String`]s. /// /// [`Parser`] will never produce this variant when used with /// [`Version::Rfc8941`]. /// /// [display string]: <https://httpwg.org/specs/rfc9651.html#displaystring> // sf-displaystring = "%" DQUOTE *( unescaped / "\" / pct-encoded ) DQUOTE // pct-encoded = "%" lc-hexdig lc-hexdig // lc-hexdig = DIGIT / %x61-66 ; 0-9, a-f
DisplayString(D),
}
impl<S, B, T, D> GenericBareItem<S, B, T, D> { /// If the bare item is a decimal, returns it; otherwise returns `None`. #[must_use] pubfn as_decimal(&self) -> Option<Decimal> { match *self { Self::Decimal(val) => Some(val),
_ => None,
}
}
/// If the bare item is an integer, returns it; otherwise returns `None`. #[must_use] pubfn as_integer(&self) -> Option<Integer> { match *self { Self::Integer(val) => Some(val),
_ => None,
}
}
/// If the bare item is a string, returns a reference to it; otherwise returns `None`. #[must_use] pubfn as_string(&self) -> Option<&StringRef> where
S: Borrow<StringRef>,
{ match *self { Self::String(ref val) => Some(val.borrow()),
_ => None,
}
}
/// If the bare item is a byte sequence, returns a reference to it; otherwise returns `None`. #[must_use] pubfn as_byte_sequence(&self) -> Option<&[u8]> where
B: Borrow<[u8]>,
{ match *self { Self::ByteSequence(ref val) => Some(val.borrow()),
_ => None,
}
}
/// If the bare item is a boolean, returns it; otherwise returns `None`. #[must_use] pubfn as_boolean(&self) -> Option<bool> { match *self { Self::Boolean(val) => Some(val),
_ => None,
}
}
/// If the bare item is a token, returns a reference to it; otherwise returns `None`. #[must_use] pubfn as_token(&self) -> Option<&TokenRef> where
T: Borrow<TokenRef>,
{ match *self { Self::Token(ref val) => Some(val.borrow()),
_ => None,
}
}
/// If the bare item is a date, returns it; otherwise returns `None`. #[must_use] pubfn as_date(&self) -> Option<Date> { match *self { Self::Date(val) => Some(val),
_ => None,
}
}
/// If the bare item is a display string, returns a reference to it; otherwise returns `None`. #[must_use] pubfn as_display_string(&self) -> Option<&D> { match *self { Self::DisplayString(ref val) => Some(val),
_ => None,
}
}
}
#[derive(Debug, PartialEq)] pub(crate) enum Num {
Decimal(Decimal),
Integer(Integer),
}
/// A [bare item] that owns its data. /// /// [bare item]: <https://httpwg.org/specs/rfc9651.html#item> #[cfg_attr(
feature = "parsed-types",
doc = "Used to construct an [`Item`] or [`Parameters`] values."
)] /// /// Note: This type deliberately does not implement `From<StdString>` as a /// shorthand for [`BareItem::DisplayString`] because it is too easy to confuse /// with conversions from [`String`]: /// /// ```compile_fail /// # use sfv::BareItem; /// let _: BareItem = "x".to_owned().into(); /// ``` /// /// Instead, use: /// /// ``` /// # use sfv::BareItem; /// let _ = BareItem::DisplayString("x".to_owned()); /// ``` pubtype BareItem = GenericBareItem<String, Vec<u8>, Token, StdString>;
/// A [bare item] that borrows its data. /// /// Used to serialize values via [`ItemSerializer`], [`ListSerializer`], and [`DictSerializer`]. /// /// [bare item]: <https://httpwg.org/specs/rfc9651.html#item> /// /// Note: This type deliberately does not implement `From<&str>` as a shorthand /// for [`RefBareItem::DisplayString`] because it is too easy to confuse with /// conversions from [`StringRef`]: /// /// ```compile_fail /// # use sfv::RefBareItem; /// let _: RefBareItem = "x".into(); /// ``` /// /// Instead, use: /// /// ``` /// # use sfv::RefBareItem; /// let _ = RefBareItem::DisplayString("x"); /// ``` pubtype RefBareItem<'a> = GenericBareItem<&'a StringRef, &'a [u8], &'a TokenRef, &'a str>;
/// A [bare item] that borrows data from input when possible. /// /// Used to parse input incrementally in the [`visitor`] module. /// /// [bare item]: <https://httpwg.org/specs/rfc9651.html#item> /// /// Note: This type deliberately does not implement `From<Cow<str>>` as a /// shorthand for [`BareItemFromInput::DisplayString`] because it is too easy to /// confuse with conversions from [`Cow<StringRef>`]: /// /// ```compile_fail /// # use sfv::BareItemFromInput; /// # use std::borrow::Cow; /// let _: BareItemFromInput = "x".to_owned().into(); /// ``` /// /// Instead, use: /// /// ``` /// # use sfv::BareItemFromInput; /// # use std::borrow::Cow; /// let _ = BareItemFromInput::DisplayString(Cow::Borrowed("x")); /// ``` pubtype BareItemFromInput<'a> =
GenericBareItem<Cow<'a, StringRef>, Vec<u8>, &'a TokenRef, Cow<'a, str>>;
impl<S1, B1, T1, D1, S2, B2, T2, D2> PartialEq<GenericBareItem<S2, B2, T2, D2>> for GenericBareItem<S1, B1, T1, D1> where for<'a> RefBareItem<'a>: From<&'a Self>, for<'a> RefBareItem<'a>: From<&'a GenericBareItem<S2, B2, T2, D2>>,
{ fn eq(&self, other: &GenericBareItem<S2, B2, T2, D2>) -> bool { match (RefBareItem::from(self), RefBareItem::from(other)) {
(RefBareItem::Integer(a), RefBareItem::Integer(b)) => a == b,
(RefBareItem::Decimal(a), RefBareItem::Decimal(b)) => a == b,
(RefBareItem::String(a), RefBareItem::String(b)) => a == b,
(RefBareItem::ByteSequence(a), RefBareItem::ByteSequence(b)) => a == b,
(RefBareItem::Boolean(a), RefBareItem::Boolean(b)) => a == b,
(RefBareItem::Token(a), RefBareItem::Token(b)) => a == b,
(RefBareItem::Date(a), RefBareItem::Date(b)) => a == b,
(RefBareItem::DisplayString(a), RefBareItem::DisplayString(b)) => a == b,
_ => false,
}
}
}
/// A version for serialized structured field values. /// /// Each HTTP specification that uses structured field values must indicate /// which version it uses. See [the guidance from RFC 9651] for details. /// /// [RFC 9651]: <https://httpwg.org/specs/rfc9651.html#using-new-structured-types-in-extensions> #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pubenum Version { /// [RFC 8941], which does not support dates or display strings. /// /// [RFC 8941]: <https://httpwg.org/specs/rfc8941.html>
Rfc8941, /// [RFC 9651], which supports dates and display strings. /// /// [RFC 9651]: <https://httpwg.org/specs/rfc9651.html>
Rfc9651,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.