13个版本 (8个破坏性)

0.9.4 2024年1月11日
0.9.3 2022年12月23日
0.9.2 2022年1月31日
0.9.1 2021年2月14日
0.3.0 2020年7月24日

#107 in 编码

Download history 9587/week @ 2024-04-20 10388/week @ 2024-04-27 9790/week @ 2024-05-04 8981/week @ 2024-05-11 8711/week @ 2024-05-18 7451/week @ 2024-05-25 7028/week @ 2024-06-01 9325/week @ 2024-06-08 10982/week @ 2024-06-15 9419/week @ 2024-06-22 10920/week @ 2024-06-29 12187/week @ 2024-07-06 12821/week @ 2024-07-13 12393/week @ 2024-07-20 14324/week @ 2024-07-27 12801/week @ 2024-08-03

55,054 每月下载量
用于 24 个crate (6 直接)

MIT/Apache

100KB
2K SLoC

License Build Status Version Docs

HTTP的结构化字段值

sfv crate是按照RFC 8941中规定的HTTP结构化字段值进行解析和序列化的实现。

它还公开了一组类型,这些类型可能有助于定义新的结构化字段。


许可协议

根据您的选择,在Apache License, Version 2.0MIT license下许可。

lib.rs:

sfv crate是按照RFC 8941中规定的HTTP结构化字段值进行解析和序列化的实现。它还公开了一组类型,这些类型可能有助于定义新的结构化字段。

数据结构

有三种结构化字段类型

  • Item - 可以是一个 IntegerDecimalStringTokenByte SequenceBoolean。它可以有相关的 Parameters
  • List - 零个或多个成员的数组,每个成员可以是一个 Item 或一个 InnerList,这两个都可以 Parameterized
  • Dictionary - 有序的名值对映射,其中名称是简短文本字符串,值是 ItemsItems 的数组(用 InnerList 表示),这两个都可以 Parameterized。可以有零个或多个成员,且它们的名称在它们出现的 Dictionary 的作用域内是唯一的。

还有一些原始类型用于构建结构化字段值

  • BareItem 用作 Item 的值或作为 Parameters 中的参数值。
  • 参数是一个有序键值对的映射,与内嵌列表相关联。键在其出现的参数作用域内是唯一的,值是裸项
  • 内嵌列表是由零个或多个组成的数组。可以包含参数
  • 列表条目代表作为列表的成员或作为字典中的成员值,代表内嵌列表

示例

解析

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

获取解析值成员

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"),
}

结构化字段值构造和序列化

创建具有空参数的

use sfv::{Item, BareItem, SerializeValue};

let str_item = Item::new(BareItem::String(String::from("foo")));
assert_eq!(str_item.serialize_value().unwrap(), "\"foo\"");

创建带有参数的字段值

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

创建具有和参数化内嵌列表成员的列表字段值

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

创建字典字段值

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

依赖项

~1.5MB
~27K SLoC