3 个不稳定版本

0.2.0 2022年4月1日
0.1.1 2022年3月23日
0.1.0 2020年10月8日

#1000编码

MIT/Apache

72KB
1.5K SLoC

JSON Feed 模型

JSON Feed 模型提供可用于操作 JSON Feed 数据的类型。

该包基本上是对 新类型 包装 Serde JSONMap 类型,并提供 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.0MIT License许可。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,任何有意提交以包含在您的工作中的贡献,都应如上所述双许可,不附加任何额外条款或条件。

依赖关系

~355–760KB
~17K SLoC