Expand description
sfv
crate is an implementation of Structured Field Values for HTTP as specified in RFC 8941 for parsing and serializing HTTP field values.
It also exposes a set of types that might be useful for defining new structured fields.
Data Structures
There are three types of structured fields:
Item
- can be anInteger
,Decimal
,String
,Token
,Byte Sequence
, orBoolean
. It can have associatedParameters
.List
- array of zero or more members, each of which can be anItem
or anInnerList
, both of which can beParameterized
.Dictionary
- ordered map of name-value pairs, where the names are short textual strings and the values areItems
or arrays ofItems
(represented withInnerList
), both of which can beParameterized
. There can be zero or more members, and their names are unique in the scope of theDictionary
they occur within.
There’s also a few primitive types used to construct structured field values:
BareItem
used asItem
’s value or as a parameter value inParameters
.Parameters
are an ordered map of key-value pairs that are associated with anItem
orInnerList
. The keys are unique within the scope theParameters
they occur within, and the values areBareItem
.InnerList
is an array of zero or moreItems
. Can haveParameters
.ListEntry
represents eitherItem
orInnerList
as a member ofList
or as member-value inDictionary
.
Examples
Parsing
use sfv::Parser;
// Parsing structured field value of Item type.
let item_header_input = "12.445;foo=bar";
let item = Parser::parse_item(item_header_input.as_bytes());
assert!(item.is_ok());
println!("{:#?}", item);
// Parsing structured field value of List type.
let list_header_input = "1;a=tok, (\"foo\" \"bar\");baz, ()";
let list = Parser::parse_list(list_header_input.as_bytes());
assert!(list.is_ok());
println!("{:#?}", list);
// Parsing structured field value of Dictionary type.
let dict_header_input = "a=?0, b, c; foo=bar, rating=1.5, fruits=(apple pear)";
let dict = Parser::parse_dictionary(dict_header_input.as_bytes());
assert!(dict.is_ok());
println!("{:#?}", dict);
Getting Parsed Value Members
use sfv::*;
let dict_header = "u=2, n=(* foo 2)";
let dict = Parser::parse_dictionary(dict_header.as_bytes()).unwrap();
// Case 1 - handling value if it's an Item of Integer type
let u_val = match dict.get("u") {
Some(ListEntry::Item(item)) => item.bare_item.as_int(),
_ => None,
};
if let Some(u_val) = u_val {
println!("{}", u_val);
}
// Case 2 - matching on all possible types
match dict.get("u") {
Some(ListEntry::Item(item)) => match &item.bare_item {
BareItem::Token(val) => {
// do something if it's a Token
println!("{}", val);
}
BareItem::Integer(val) => {
// do something if it's an Integer
println!("{}", val);
}
BareItem::Boolean(val) => {
// do something if it's a Boolean
println!("{}", val);
}
BareItem::Decimal(val) => {
// do something if it's a Decimal
println!("{}", val);
}
BareItem::String(val) => {
// do something if it's a String
println!("{}", val);
}
BareItem::ByteSeq(val) => {
// do something if it's a ByteSeq
println!("{:?}", val);
}
},
Some(ListEntry::InnerList(inner_list)) => {
// do something if it's an InnerList
println!("{:?}", inner_list.items);
}
None => panic!("key not found"),
}
Structured Field Value Construction and Serialization
Creates Item
with empty parameters:
use sfv::{Item, BareItem, SerializeValue};
let str_item = Item::new(BareItem::String(String::from("foo")));
assert_eq!(str_item.serialize_value().unwrap(), "\"foo\"");
Creates Item
field value with parameters:
use sfv::{Item, BareItem, SerializeValue, Parameters, Decimal, FromPrimitive};
let mut params = Parameters::new();
let decimal = Decimal::from_f64(13.45655).unwrap();
params.insert("key".into(), BareItem::Decimal(decimal));
let int_item = Item::with_params(BareItem::Integer(99), params);
assert_eq!(int_item.serialize_value().unwrap(), "99;key=13.457");
Creates List
field value with Item
and parametrized InnerList
as members:
use sfv::{Item, BareItem, InnerList, List, SerializeValue, Parameters};
let tok_item = BareItem::Token("tok".into());
// Creates Item.
let str_item = Item::new(BareItem::String(String::from("foo")));
// Creates InnerList members.
let mut int_item_params = Parameters::new();
int_item_params.insert("key".into(), BareItem::Boolean(false));
let int_item = Item::with_params(BareItem::Integer(99), int_item_params);
// Creates InnerList.
let mut inner_list_params = Parameters::new();
inner_list_params.insert("bar".into(), BareItem::Boolean(true));
let inner_list = InnerList::with_params(vec![int_item, str_item], inner_list_params);
let list: List = vec![Item::new(tok_item).into(), inner_list.into()];
assert_eq!(
list.serialize_value().unwrap(),
"tok, (99;key=?0 \"foo\");bar"
);
Creates Dictionary
field value:
use sfv::{Parser, Item, BareItem, SerializeValue, ParseValue, Dictionary};
let member_value1 = Item::new(BareItem::String(String::from("apple")));
let member_value2 = Item::new(BareItem::Boolean(true));
let member_value3 = Item::new(BareItem::Boolean(false));
let mut dict = Dictionary::new();
dict.insert("key1".into(), member_value1.into());
dict.insert("key2".into(), member_value2.into());
dict.insert("key3".into(), member_value3.into());
assert_eq!(
dict.serialize_value().unwrap(),
"key1=\"apple\", key2, key3=?0"
);
Structs
Decimal
represents a 128 bit representation of a fixed-precision decimal number. The finite set of values of typeDecimal
are of the form m / 10e, where m is an integer such that -296 < m < 296, and e is an integer between 0 and 28 inclusive.- Array of
Items
with associatedParameters
. - Represents
Item
type structured field value. Can be used as a member ofList
orDictionary
. - Exposes methods for parsing input into structured field value.
- Serializes
Dictionary
field value components incrementally. - Serializes
Item
field value components incrementally. - Serializes
List
field value components incrementally.
Enums
BareItem
type is used to constructItems
orParameters
values.- Represents a member of
List
orDictionary
structured field value. - Similar to
BareItem
, but used to serialize values viaRefItemSerializer
,RefListSerializer
,RefDictSerializer
.
Traits
- A generic trait for converting a number to a value.
- Parse a value from a string
- If structured field value of List or Dictionary type is split into multiple lines, allows to parse more lines and merge them into already existing structure field value.
- Implements parsing logic for each structured field value type.
- Serializes structured field value into String.
Type Aliases
- Represents
Dictionary
type structured field value. - Represents
List
type structured field value. - Parameters of
Item
orInnerList
.