Serde-yaml deprecation. alternatives?

I've seen people complaining that it requires more dependencies and has a very high MSRV. The MSRV in particular is a problem because it's much higher than the original yaml-rust, and it's technically a breaking change to bump it.

There is no consensus on whether bumping MSRV is a breaking change or not, and the general recommendation in Cargo's documentation is to treat it as a semver minor change.

(I am responding narrowly here and not trying to say that folks complaining about MSRV are wrong to do so, but I feel it's important not to leave factual statements like "bumping MSRV is technically a breaking change" unchallenged.)

6 Likes

Keep in mind the libxz attack was two years of the attacker building up reputation with contributions before having maintainer status granted and adding the attack.

Unless we're doing background checks on maintainers, or perhaps where there's a Apache Foundation situation where there's a diffusion of maintenance responsibility there's not really any good way to safely vet maintainers for such high value packages.

1 Like

Further, the powers of a crate maintainer exceed those of a maintainer of a c library in the sense that
a crate maintainer has the ability to make sem-ver compatible releases. While the xz attack made quite a bit of effort just attempting to convince people to upgrade.

To flip this around, the trust you place in the maintainer when taking a dependency on a crate is that future sem-ver compatible releases of the crate will also be trustworthy. Which seems to me like additional risk to be taken into account when transferring ownership of a crate, since they come with a captive audience.

2 Likes

The serde_yml crate has picked up where serde-yaml left off. It's a fork. I've just updated my project to it, and it works. And the author is developing new features, too.

I just glanced at that project's dependencies, and it seems to have added a number of irrelevant dependencies for no discernable reason, including openssl, env_logger, and figlet-rs. I don't trust it.

2 Likes

Yeah, I agree. I'm preparing a PR to eliminate those right now. Also shady, the author didn't mention that serde_yml was a fork of serde-yaml until somebody mentioned it on an issue. It may have been an oversight, or me may have been trying to claim undue credit.

With the recent deprecation of serde_yaml by dtolnay, i have the following thoughts:

Problem: The current crate dependency ecosystem in Rust can be fragile when a single maintainer abandons a well used crate like serde_yaml. This lack of continuity can cause issues for projects relying on it and also

Proposed Solution: Implement a "batteries-included assurance" system through a preset group of maintainers.

  • Group Ownership: Critical crates would have a designated group of maintainers responsible for upkeep and updates.
  • Transfer of Ownership: When the original developer decides to step down, they can seamlessly transfer ownership to the group, ensuring continued maintenance.

Benefits:

  • Improved Stability: Projects depending on these crates would benefit from continued maintenance and reduced risk of abandonment.
  • Faster Response: A group can handle issues and updates more efficiently than a single maintainer.
  • Knowledge Transfer: The group can share knowledge and expertise, fostering long-term sustainability.
  • Security: Already trustworthy vetted developers, reducing chances of and libxz attack.

Challenges:

  • Resource Management: Identifying and allocating resources for the maintainer group.
  • Decision Making: Establishing a clear decision-making process within the group.
2 Likes

It's not just the dependencies. From a quick glance to the repository:

  • there is a run function that seems to print ascii art and log some stuff to a file;
  • there is an example build.rs that does nothing;
  • there are various comments that seem AI generated (look for example at the src/main.rs file)
  • the history is a mess. It could be just how the author works, but it makes looking around even harder, for example the commit that introduces a bunch of those useless dependencies also runs rustfmt on the whole repository, totaling 3k lines changed.

I prefer using the deprecated serde_yaml or creating my own fork rather than using this mess.

7 Likes

All of those criticisms are valid, @SkiFire13. And here's another: serde_yml's author forked unsafe-libyaml to a new crated yamed libyml. Most of the same mistakes he made in serde_yml he also made in libyml.
But the key point remains: serde_yml is the only fork I know of. So it's our only option. Unless you're volunteering to maintain one?

Continuing to use the original serde_yaml is still an option and IMO better than using this fork. It's not like a crate like this needs continuous maintenance. And if an issue actually does pop up, you always have the option to make a kinda-private fork and fix it for yourself, and that's assuming the issue will even affect you.

6 Likes

Since I maintain the packages for the serde_yaml and unsafe-libyaml crates for Fedora Linux, I reached out to dtolnay about continuing basic maintenance of serde_yaml and unsafe-libyaml. His response's TL;DR boiled down to "please don't".

If I understood his response correctly (big caveat here!), there is no YAML library in Rust that supports both YAML 1.2 and the features that would be necessary to losslessly represent YAML syntax with Rust data structures, so there seems to currently be no way toward a future where serde_yaml supports both YAML 1.2 and all weird-but-valid YAML features at the same time.

I think unsafe-libyaml was used for serde_yaml 0.9 because it supported more things than the now unmaintained yaml_rust crate, but it didn't support the latest YAML 1.2 standard. And while the maintained yaml-rust2 fork does claim to be compliant with YAML 1.2, it doesn't represent all YAML syntax in a way that's usable by serde_yaml.

So IIUC, there's currently no YAML library available that would satisfy all the needs of a fully featured and YAML 1.2 conformant YAML frontend for serde.

10 Likes

In addition, dtolnay seems to think differently about "only option"
Releases ยท dtolnay/serde-yaml (github.com)

I think there is no yaml parser (in any language) out there implementing the whole specification. I may be misremembering.

yaml-rust2 has only three direct runtime dependencies: arraydeque, encoding_rs and hashlink. This looks like a reasonable number for a general purpose library. Serde-yaml requires five: indexmap, itoa, ryu, serde and the notable unsafe-libyaml. It is easy to check by looking into Cargo.toml files in GitHub.

I would also be happy to review the code of the run function you talk about but unable to find it. grep run . -r | grep fn only lists some bundled tests and tools:

./tests/yaml-test-suite.rs:fn run_yaml_test(test: &Test) -> Outcome {
./tools/bench_compare/src/main.rs:fn run_bench(config: &Config) -> Result<(), Error> {
./tools/bench_compare/src/main.rs:fn save_run_bench_csv(

If such a thing hangs out in production part, seems not a bad idea to open an PR for dropping it.

Deciding from the comparison matrix, looks like there are only two: libfyaml (that is not the same as libyaml) and the Perl Generated RefParser.

But some YAML features like empty key are such that really not every project needs them. You can read about these features on the bottom right.

yaml-rust2 would be a replacement for yaml-rust, which only depends on linked_hash_map (itself without dependencies, while yaml-rust2 also has some transitive dependencies). Also, yaml-rust2 has a 1.70.0 MSRV, released less than a year ago, while yaml-rust supports at least rust 1.51, released more than 3 years ago.

1 Like

The comparison matrix and its suite must be a bit lacking. We know that for example this trivial bit of yaml:

- false
- n
- off

Will be successfully parsed by most parsers but might give very different outputs. Some will give a array of boolean, others will give an array of strings. Other still might give you a mix of bool and strings. This is compliant with the spec and will pass the official test suite (of course since it is compliant). But it's not really what we want.

There's rust-yaml yaml-rust (EDIT: I brain farted rust-yaml instead of yaml-rust. Nobody get any ideas it's confusing enough as it is :wink:) which doesn't appear to get any maintenance for a few years, maintainer not responding.

Then there's yaml-rust2 which is a maintained version of rust-yaml, targets more recent version of rust and aims for stable API. A drop-in replacement for rust-yaml yaml-rust:

[dependencies]
yaml-rust = { version = "#.#", package = "yaml-rust2" }

The new maintainers also wanted to update the API, make breaking changes, so they have made another project for people interested in that and don't mind the churn. That's called saphyr. More info on that page and this helpful issue on yaml-rust2.

Downside with all of this is both saphyr and yaml-rust[2] lack serde support, it seems saphyr has it planned but not started yet.

All interesting stuff, but still no obvious answer for a replacement for serde_yaml.

I'd personally avoid serde_yml (note the missing a), it seems sus.

I found serde_yaml_ng which seems to be an honest continuation of serde_yaml. That might be the best short term solution, I don't want to put undue pressure on it's owner, they talk about their motivation in the readme which I found refreshing :slight_smile:

I've got no affiliation with any of these crates, just an interested observer searching on GitHub.

2 Likes