3 unstable releases

new 0.10.0 May 26, 2024
0.9.36 May 3, 2024
0.9.35 May 3, 2024

#239 in Encoding

Download history 281/week @ 2024-05-02 7/week @ 2024-05-09 14/week @ 2024-05-16 217/week @ 2024-05-23

519 downloads per month

MIT license

350KB
9K SLoC

Serde YAML

github crates.io docs.rs build status

Rust library for using the Serde serialization framework with data in YAML file format. This library only follows the YAML specification 1.1..

This library is a fork from the latest commit of serde-yaml, which was 200950. [original] [this project] My goal is to be compatible as much as possible with David Tolnay's original library.

Dependency

[dependencies]
serde = "1.0"
serde_yaml_ng = "0.9"

Release notes are available under GitHub releases.

Using Serde YAML

API documentation is available in rustdoc form but the general idea is:

use std::collections::BTreeMap;

fn main() -> Result<(), serde_yaml_ng::Error> {
    // You have some type.
    let mut map = BTreeMap::new();
    map.insert("x".to_string(), 1.0);
    map.insert("y".to_string(), 2.0);

    // Serialize it to a YAML string.
    let yaml = serde_yaml_ng::to_string(&map)?;
    assert_eq!(yaml, "x: 1.0\ny: 2.0\n");

    // Deserialize it back to a Rust type.
    let deserialized_map: BTreeMap<String, f64> = serde_yaml_ng::from_str(&yaml)?;
    assert_eq!(map, deserialized_map);
    Ok(())
}

It can also be used with Serde's derive macros to handle structs and enums defined in your program.

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_yaml_ng = "0.9"

Structs serialize in the obvious way:

use serde::{Serialize, Deserialize};

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

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

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

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

Enums serialize using YAML's !tag syntax to identify the variant name.

use serde::{Serialize, Deserialize};

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

fn main() -> Result<(), serde_yaml_ng::Error> {
    let yaml = "
        - !Newtype 1
        - !Tuple [0, 0, 0]
        - !Struct {x: 1.0, y: 2.0}
    ";
    let values: Vec<Enum> = serde_yaml_ng::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_yaml_ng::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_yaml_ng::from_str(yaml).unwrap();
    assert_eq!(values[0], Enum::Unit);
    assert_eq!(values[1], Enum::Unit);

    Ok(())
}

Why?

I haven't found any good fork as of the start of this project. The best candidate was serde_yml which is based on a giant "Initial commit" from the main maintainer. This is the type of practices which leads to security disasters.

I don't want to fight with people about their practices, that's why I'm maintaining this library for myself, and for the rust ecosystem as a whole. As we say in French: "You are never better served than by yourself". 😉

Use it, don't use it, I don't care. I'll try to fix as many bugs as I can. I'll accept pull requests if they're reasonable or easy to work with.

Financial Support

I'm a guy working out of his garage at night with a well-paid job during the day. I do not need your money. Please! Instead, give money to David Tolnay. This guy carries half of the Rust ecosystem on his shoulders, and wrote most of the code for this project before I forked it. I'm just a loser who jumped on the train, don't give me any money.

License

Licensed MIT license.

Any contribution must be accompanied with a signature of the Developer Certificate of Origin, by using the --signoff flag on git commit.

Dependencies

~1.3–1.8MB
~35K SLoC