#serde-yaml #serialization #serde #serde-derive

serde_yml

一个强大的Rust库,使用广泛使用的Serde框架简化Rust数据结构的序列化和反序列化到/从YAML格式。

11次发布

0.0.11 2024年7月21日
0.0.10 2024年5月30日
0.0.4 2024年4月3日
0.0.2 2024年3月29日

#56 in 编码

Download history 701/week @ 2024-05-03 933/week @ 2024-05-10 910/week @ 2024-05-17 1535/week @ 2024-05-24 1510/week @ 2024-05-31 2249/week @ 2024-06-07 2973/week @ 2024-06-14 2490/week @ 2024-06-21 3305/week @ 2024-06-28 3638/week @ 2024-07-05 3991/week @ 2024-07-12 5959/week @ 2024-07-19 6410/week @ 2024-07-26 6194/week @ 2024-08-02 9338/week @ 2024-08-09 10698/week @ 2024-08-16

33,863 每月下载量
用于 60 个crate(41直接)

MIT/Apache

465KB
11K SLoC

Serde YML logo

Serde YML(Serde YAML的分支)

GitHub Crates.io Docs.rs Codecov Build Status

Serde YML是一个Rust库,用于使用Serde序列化框架和YAML文件格式中的数据。该项目已重命名为Serde YML,以避免与已存档且不再维护的原始Serde YAML crate混淆。

致谢

这个库是David Tolnayserde-yaml库维护者所做优秀工作的延续。

虽然Serde YML最初是serde-yaml的分支,但它现在已经发展成为一个具有自己目标和方向的独立库,并不打算替代原始的serde-yaml crate。

如果你目前在项目中使用serde-yaml,我们建议你仔细评估你的需求,并考虑原始库的稳定性和成熟度,同时查看Rust生态系统中的其他YAML库提供的特性和改进。

我想向David Tolnayserde-yaml团队表达我衷心的感谢,他们为Rust社区做出了宝贵的贡献,并启发了这个项目。

依赖项

[dependencies]
serde = "1.0"
serde_yml = "0.0.11"

发布说明可以在GitHub发布下找到。

使用Serde YML

API文档以rustdoc形式提供,但基本思路是

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Point {
    x: f64,
    y: f64,
}

fn main() -> Result<(), serde_yml::Error> {
    let point = Point { x: 1.0, y: 2.0 };

    // Serialize to YAML
    let yaml = serde_yml::to_string(&point)?;
    assert_eq!(yaml, "x: 1.0\ny: 2.0\n");

    // Deserialize from YAML
    let deserialized_point: Point = serde_yml::from_str(&yaml)?;
    assert_eq!(point, deserialized_point);

    Ok(())
}

示例

Serde YML提供了一系列全面的示例。您可以在项目的examples目录中找到它们。要运行示例,请克隆存储库,并在项目的终端中执行以下命令

cargo run --example example

示例涵盖了各种场景,包括结构体、枚举、可选字段、自定义结构体等的序列化和反序列化。

以下是一些值得注意的示例

序列化和反序列化结构体

use serde::{Serialize, Deserialize};
use serde_yml;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Point {
    x: f64,
    y: f64,
}

fn main() -> Result<(), serde_yml::Error> {
    let point = Point { x: 1.0, y: 2.0 };

    // Serialize to YAML
    let yaml = serde_yml::to_string(&point)?;
    assert_eq!(yaml, "x: 1.0\ny: 2.0\n");

    // Deserialize from YAML
    let deserialized_point: Point = serde_yml::from_str(&yaml)?;
    assert_eq!(point, deserialized_point);

    Ok(())
}

本例演示了如何使用serde_yml crate将简单的结构体Point序列化和反序列化为YAML。

枚举的序列化和反序列化

use serde::{Serialize, Deserialize};
use serde_yml;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Shape {
    Rectangle { width: u32, height: u32 },
    Circle { radius: f64 },
    Triangle { base: u32, height: u32 },
}

fn main() -> Result<(), serde_yml::Error> {
    let shapes = vec![
        Shape::Rectangle { width: 10, height: 20 },
        Shape::Circle { radius: 5.0 },
        Shape::Triangle { base: 8, height: 12 },
    ];

    // Serialize to YAML
    let yaml = serde_yml::to_string(&shapes)?;
    println!("Serialized YAML:\n{}", yaml);

    // Deserialize from YAML
    let deserialized_shapes: Vec<Shape> = serde_yml::from_str(&yaml)?;
    assert_eq!(shapes, deserialized_shapes);

    Ok(())
}

本例演示了如何使用serde_yml crate将枚举Shape(具有结构体变体)序列化和反序列化为YAML。

可选字段的序列化和反序列化

use serde::{Serialize, Deserialize};
use serde_yml;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct User {
    name: String,
    age: Option<u32>,
    #[serde(default)]
    is_active: bool,
}

fn main() -> Result<(), serde_yml::Error> {
    let user = User {
        name: "John".to_string(),
        age: Some(30),
        is_active: true,
    };

    // Serialize to YAML
    let yaml = serde_yml::to_string(&user)?;
    println!("Serialized YAML:\n{}", yaml);

    // Deserialize from YAML
    let deserialized_user: User = serde_yml::from_str(&yaml)?;
    assert_eq!(user, deserialized_user);

    Ok(())
}

本例演示了如何使用serde_yml crate将包含可选字段age的结构体User序列化和反序列化为YAML。

HashMap的序列化和反序列化

use std::collections::HashMap;
use serde_yml;

fn main() -> Result<(), serde_yml::Error> {
    let mut map = HashMap::new();
    map.insert("name".to_string(), "John".to_string());
    map.insert("age".to_string(), "30".to_string());

    let yaml = serde_yml::to_string(&map)?;
    println!("Serialized YAML: {}", yaml);

    let deserialized_map: HashMap<String, serde_yml::Value> = serde_yml::from_str(&yaml)?;
    println!("Deserialized map: {:?}", deserialized_map);

    Ok(())
}

本例演示了如何使用serde_yml crate将HashMap序列化和反序列化为YAML。

自定义结构的序列化和反序列化

use serde::{Serialize, Deserialize};
use serde_yml;

#[derive(Serialize, Deserialize, Debug)]
struct Person {
    name: String,
    age: u32,
    city: String,
}

fn main() -> Result<(), serde_yml::Error> {
    let person = Person {
        name: "Alice".to_string(),
        age: 25,
        city: "New York".to_string(),
    };

    let yaml = serde_yml::to_string(&person)?;
    println!("Serialized YAML: {}", yaml);

    let deserialized_person: Person = serde_yml::from_str(&yaml)?;
    println!("Deserialized person: {:?}", deserialized_person);

    Ok(())
}

本例演示了如何使用serde_yml crate将自定义结构体Person序列化和反序列化为YAML。

使用Serde derive

它还可以与Serde的derive宏一起使用来处理程序中定义的结构体和枚举。

结构体以明显的方式序列化

use serde_derive::{Serialize, Deserialize};
use serde_yml;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Point {
    x: f64,
    y: f64,
}

fn main() -> Result<(), serde_yml::Error> {
    let point = Point { x: 1.0, y: 2.0 };

    let yaml = serde_yml::to_string(&point)?;
    assert_eq!(yaml, "x: 1.0\n'y': 2.0\n");

    let deserialized_point: Point = serde_yml::from_str(&yaml)?;
    assert_eq!(point, deserialized_point);
    Ok(())
}

枚举使用YAML的!tag语法来标识变体名称进行序列化。

use serde_derive::{Serialize, Deserialize};
use serde_yml;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Enum {
    Unit,
    Newtype(usize),
    Tuple(usize, usize, usize),
    Struct { x: f64, y: f64 },
}

fn main() -> Result<(), serde_yml::Error> {
    let yaml = "
        - !Newtype 1
        - !Tuple [0, 0, 0]
        - !Struct {x: 1.0, y: 2.0}
    ";
    let values: Vec<Enum> = serde_yml::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Newtype(1));
    assert_eq!(values[1], Enum::Tuple(0, 0, 0));
    assert_eq!(values[2], Enum::Struct { x: 1.0, y: 2.0 });

    // The last two in YAML's block style instead:
    let yaml = "
        - !Tuple
        - 0
        - 0
        - 0
        - !Struct
        x: 1.0
        'y': 2.0
    ";
    let values: Vec<Enum> = serde_yml::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Tuple(0, 0, 0));
    assert_eq!(values[1], Enum::Struct { x: 1.0, y: 2.0 });

    // Variants with no data can be written using !Tag or just the string name.
    let yaml = "
        - Unit  # serialization produces this one
        - !Unit
    ";
    let values: Vec<Enum> = serde_yml::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Unit);
    assert_eq!(values[1], Enum::Unit);

    Ok(())
}

本例演示了如何使用Serde的derive宏自动为结构体Point实现SerializeDeserialize特质,然后使用serde_yml crate将其序列化和反序列化为YAML。

具有自定义序列化和反序列化的枚举的序列化和反序列化

use serde::{Deserialize, Serialize};
use serde::de::{self, Deserializer, MapAccess, Visitor};
use serde::ser::{SerializeMap, Serializer};
use std::fmt;
use serde_yml;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum MyEnum {
    Variant1(String),
    Variant2 { field: i32 },
}

#[derive(PartialEq, Debug)]
struct MyStruct {
    field: MyEnum,
}

// Include custom Serialize and Deserialize implementations for MyStruct here
// ...

fn main() -> Result<(), serde_yml::Error> {
    let input = MyStruct {
        field: MyEnum::Variant2 { field: 42 },
    };

    let yaml = serde_yml::to_string(&input).unwrap();
    println!("\n✅ Serialized YAML:\n{}", yaml);

    let output: MyStruct = serde_yml::from_str(&yaml).unwrap();
    println!("\n✅ Deserialized YAML:\n{:#?}", output);

    assert_eq!(input, output);

    Ok(())
}

本例演示了如何为包含枚举字段的结构体使用自定义的SerializeDeserialize实现,以及如何利用serde_yml将结构体序列化和反序列化为YAML。

可选枚举的序列化和反序列化

use serde::{Deserialize, Serialize};
use serde_yml;
use serde_yml::with::singleton_map_optional;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum OptionalEnum {
    Variant1(String),
    Variant2 { field: i32 },
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct OptionalStruct {
    #[serde(with = "singleton_map_optional")]
    field: Option<OptionalEnum>,
}

fn main() -> Result<(), serde_yml::Error> {
    let input = OptionalStruct {
        field: Some(OptionalEnum::Variant2 { field: 42 }),
    };

    let yaml = serde_yml::to_string(&input).unwrap();
    println!("\n✅ Serialized YAML:\n{}", yaml);

    let output: OptionalStruct = serde_yml::from_str(&yaml).unwrap();
    println!("\n✅ Deserialized YAML:\n{:#?}", output);

    assert_eq!(input, output);

    Ok(())
}

本例演示了如何使用singleton_map_optional属性将Option<Enum>字段序列化和反序列化为单个YAML映射条目,其中键为枚举变体名称。

嵌套枚举的序列化和反序列化

use serde::{Deserialize, Serialize};
use serde_yml;
use serde_yml::with::singleton_map_recursive;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum NestedEnum {
    Variant1(String),
    Variant2(Option<InnerEnum>),
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum InnerEnum {
    Inner1(i32),
    Inner2(i32),
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct NestedStruct {
    #[serde(with = "singleton_map_recursive")]
    field: NestedEnum,
}

fn main() -> Result<(), serde_yml::Error> {
    let input = NestedStruct {
        field: NestedEnum::Variant2(Some(InnerEnum::Inner2(42))),
    };

    let yaml = serde_yml::to_string(&input).unwrap();
    println!("\n✅ Serialized YAML:\n{}", yaml);

    let output: NestedStruct = serde_yml::from_str(&yaml).unwrap();
    println!("\n✅ Deserialized YAML:\n{:#?}", output);

    assert_eq!(input, output);

    Ok(())
}

本例演示了如何使用singleton_map_recursive属性来序列化和反序列化包含可选嵌套枚举的结构体变体。

使用singleton_map_recursive序列化和反序列化枚举

use serde::{Deserialize, Serialize};
use serde_yml;
use serde_yml::with::singleton_map_recursive;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum MyEnum {
    Variant1(String),
    Variant2 { field: i32 },
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct MyStruct {
    #[serde(with = "singleton_map_recursive")]
    field: MyEnum,
}

fn main() -> Result<(), serde_yml::Error> {
    let input = MyStruct {
        field: MyEnum::Variant2 { field: 42 },
    };

    let yaml = serde_yml::to_string(&input).unwrap();
    println!("\n✅ Serialized YAML:\n{}", yaml);

    let output: MyStruct = serde_yml::from_str(&yaml).unwrap();
    println!("\n✅ Deserialized YAML:\n{:#?}", output);

    assert_eq!(input, output);

    Ok(())
}

本例演示了如何使用singleton_map_recursive属性将枚举字段序列化为单个YAML映射条目,其中键为枚举变体名称。

使用singleton_map_with和自定义序列化序列化和反序列化枚举

use serde::{Deserialize, Serialize};
use serde_yml;
use serde_yml::with::singleton_map_with;

fn custom_serialize<T, S>(
    value: &T,
    serializer: S,
) -> Result<S::Ok, S::Error>
where
    T: Serialize,
    S: serde::Serializer,
{
    // Custom serialization logic
    singleton_map_with::serialize(value, serializer)
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum MyEnum {
    Variant1(String),
    Variant2 { field: i32 },
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct MyStruct {
    #[serde(
        serialize_with = "custom_serialize",
        deserialize_with = "singleton_map_with::deserialize"
    )]
    field: MyEnum,
}

fn main() -> Result<(), serde_yml::Error> {
    let input = MyStruct {
        field: MyEnum::Variant2 { field: 42 },
    };
    let yaml = serde_yml::to_string(&input).unwrap();
    println!("\n✅ Serialized YAML:\n{}", yaml);

    let output: MyStruct = serde_yml::from_str(&yaml).unwrap();
    println!("\n✅ Deserialized YAML:\n{:#?}", output);
    assert_eq!(input, output);

    Ok(())
}

本例演示了如何将singleton_map_with属性与自定义序列化函数(custom_serialize)结合使用来序列化和反序列化结构体MyStruct中的枚举字段(MyEnum)。

custom_serialize函数用于序列化,而singleton_map_with::deserialize函数用于反序列化。这允许在反序列化时利用singleton_map_with属性进行额外自定义,同时仍使用该属性进行序列化。

使用singleton_map_with序列化和反序列化枚举

use serde::{Deserialize, Serialize};
use serde_yml;
use serde_yml::with::singleton_map_with;

#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum MyEnum {
    Variant1(String),
    Variant2 { field: i32 },
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct MyStruct {
    #[serde(with = "singleton_map_with")]
    field: MyEnum,
}

fn main() -> Result<(), serde_yml::Error> {
    let input = MyStruct {
        field: MyEnum::Variant2 { field: 42 },
    };
    let yaml = serde_yml::to_string(&input).unwrap();
    println!("\n✅ Serialized YAML:\n{}", yaml);

    let output: MyStruct = serde_yml::from_str(&yaml).unwrap();
    println!("\n✅ Deserialized YAML:\n{:#?}", output);
    assert_eq!(input, output);

    Ok(())
}

本例演示了如何使用 singleton_map_with 属性在结构体(MyStruct)内序列化和反序列化枚举字段(MyEnum)。singleton_map_with 属性通过使用辅助函数允许对序列化和反序列化过程进行额外的定制。

许可证

根据您的选择,受Apache许可证MIT许可证许可。

除非您明确声明,否则您提交给此crate的任何贡献,根据Apache-2.0许可证的定义,应按上述方式双重许可,不附加任何额外条款或条件。

依赖关系

~4–13MB
~176K SLoC