3 个不稳定版本
0.2.0 | 2022年4月1日 |
---|---|
0.1.1 | 2022年3月23日 |
0.1.0 | 2020年10月8日 |
#1000 在 编码
72KB
1.5K SLoC
JSON Feed 模型
JSON Feed 模型提供可用于操作 JSON Feed 数据的类型。
该包基本上是对 新类型 包装 Serde JSON 的 Map
类型,并提供 JSON Feed 属性的方法。
例如,库用户可以有一个字节数组切片,并通过调用 from_slice
创建一个 Feed
。如果字节数组切片是一个 JSON 对象,则返回一个 Feed
实例。只有 Feed
和其他模型类型确保 JSON 数据是一个 JSON 对象。
库用户可以在 Feed
实例上调用 is_valid(Version::Version1_1)
来确定 JSON 对象是否为有效的 1.1 版本 JSON Feed。
文档
安装
默认情况下,包含依赖于 Rust std
库的功能。
[dependencies]
json-feed-model = "0.2.0"
仅分配
如果宿主环境有分配器但无法访问 Rust std
库
[dependencies]
json-feed-model = { version = "0.2.0", default-features = false, features = ["alloc"]}
访问器方法
如果库用户想要读取或写入数据,则 Feed
上存在诸如 title()
、set_title(...)
和 remove_title()
之类的访问器方法。
对于“获取”方法,返回类型为Result<Option<type>, ...>
。由于期望错误的JSON类型,“获取”方法可能会失败。例如,如果字段期望是JSON字符串,但值是JSON数字,则将返回Error::UnexpectedType
。字段值可能存在或不存在,因此使用Option
类型来表示是否存在值。
对于“设置”和“删除”方法,返回JSON对象中的任何现有值。
所有者、借用和可变借用类型
每个模型类型有三种变体,即“所有者”数据类型(例如Feed
)、“借用”数据类型(例如FeedRef
)和“可变借用”数据类型(例如FeedMut
)。在大多数情况下,“所有者”数据类型将是主要类型,明确使用。由于性能原因,“借用”和“可变借用”变体可能从“获取”方法返回。
实现了一些标准特性,如From<Map<String,Value>>
和Serialize
,以及一些辅助方法,如as_map()
和as_map_mut()
,用于模型类型。
示例
以下示例展示了如何读取属性。
use json_feed_model::{Feed, ItemRef, Version};
let json = serde_json::json!({
"version": "https://jsonfeed.org/version/1.1",
"title": "Lorem ipsum dolor sit amet.",
"home_page_url": "https://example.org/",
"feed_url": "https://example.org/feed.json",
"items": [
{
"id": "cd7f0673-8e81-4e13-b273-4bd1b83967d0",
"content_text": "Aenean tristique dictum mauris, et.",
"url": "https://example.org/aenean-tristique"
},
{
"id": "2bcb497d-c40b-4493-b5ae-bc63c74b48fa",
"content_html": "Vestibulum non magna vitae tortor.",
"url": "https://example.org/vestibulum-non"
}
]
});
let feed = json_feed_model::from_value(json)?;
assert!(feed.is_valid(&Version::Version1_1));
assert_eq!(feed.version()?, Some(json_feed_model::VERSION_1_1));
assert_eq!(feed.title()?, Some("Lorem ipsum dolor sit amet."));
assert_eq!(feed.home_page_url()?, Some("https://example.org/"));
assert_eq!(feed.feed_url()?, Some("https://example.org/feed.json"));
let items: Option<Vec<ItemRef>> = feed.items()?;
assert!(items.is_some());
let items: Vec<ItemRef> = items.unwrap();
assert_eq!(items.len(), 2);
assert_eq!(items[0].id()?, Some("cd7f0673-8e81-4e13-b273-4bd1b83967d0"));
assert_eq!(
items[0].content_text()?,
Some("Aenean tristique dictum mauris, et.")
);
assert_eq!(
items[0].url()?,
Some("https://example.org/aenean-tristique")
);
assert_eq!(items[1].id()?, Some("2bcb497d-c40b-4493-b5ae-bc63c74b48fa"));
assert_eq!(
items[1].content_html()?,
Some("Vestibulum non magna vitae tortor.")
);
assert_eq!(items[1].url()?, Some("https://example.org/vestibulum-non"));
# Ok::<(), json_feed_model::Error>(())
自定义扩展
以下示例使用自定义特性来写入然后读取自定义扩展。它还展示了使用serde_json
写入JSON Feed的简单方法。有关其他序列化方法,请参阅serde_json
。
use json_feed_model::{Feed, Item, Version};
use serde_json::Value;
trait ExampleExtension {
fn example(&self) -> Result<Option<&str>, json_feed_model::Error>;
fn set_example<T>(&mut self, value: T) -> Option<Value>
where
T: ToString;
}
impl ExampleExtension for Feed {
fn example(&self) -> Result<Option<&str>, json_feed_model::Error> {
self.as_map().get("_example").map_or_else(
|| Ok(None),
|value| match value {
Value::String(s) => Ok(Some(s.as_str())),
_ => Err(json_feed_model::Error::UnexpectedType),
},
)
}
fn set_example<T>(&mut self, value: T) -> Option<Value>
where
T: ToString,
{
self.as_map_mut()
.insert(String::from("_example"), Value::String(value.to_string()))
}
}
let mut feed = Feed::new();
feed.set_version(Version::Version1_1);
feed.set_title("Lorem ipsum dolor sit amet.");
feed.set_example("123456");
let mut item = Item::new();
item.set_id("2bcb497d-c40b-4493-b5ae-bc63c74b48fa");
item.set_content_text("Vestibulum non magna vitae tortor.");
item.set_url("https://example.org/vestibulum-non");
feed.set_items(vec![item]);
assert!(feed.is_valid(&Version::Version1_1));
let expected_json = serde_json::json!({
"version": "https://jsonfeed.org/version/1.1",
"title": "Lorem ipsum dolor sit amet.",
"_example": "123456",
"items": [
{
"id": "2bcb497d-c40b-4493-b5ae-bc63c74b48fa",
"content_text": "Vestibulum non magna vitae tortor.",
"url": "https://example.org/vestibulum-non",
}
]
});
assert_eq!(feed, json_feed_model::from_value(expected_json)?);
assert_eq!(feed.example()?, Some("123456"));
let output = serde_json::to_string(&feed);
assert!(output.is_ok());
# Ok::<(), json_feed_model::Error>(())
许可证
根据您的选择,受Apache License, Version 2.0或MIT License许可。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义,任何有意提交以包含在您的工作中的贡献,都应如上所述双许可,不附加任何额外条款或条件。
依赖关系
~355–760KB
~17K SLoC