Repository: toml-rs/toml (language: rust)

Issue:
Migrate `toml` to be on `toml_edit`
`toml` will be a wrapper around the `toml_edit` crate, providing serde integration, decoupled from the format-preserving parsing, and offering a more stable API

As part of switching cargo adopting `toml_edit`, `toml_edit::easy`, a copy of `toml`s API, was created so cargo could have a single toml parser for both serde and editing.

We plan to move `toml_edit::easy` into the `toml` crate, providing nearly the same API at nearly the same performance while reducing overall maintenance effort and allowing people who have both needs to have a common parser.

Blockers
- [x] #327
- [x] #302
- [x] #303
- [x] Release a 0.5 with deprecations and 1.48 MSRV (https://github.com/toml-rs/toml/issues/346)
  - `Deserializer::end`
  - `Deserializer::set_require_newline_after_table`
  - `Deserializer::set_allow_duplicate_after_longer_table`

Performance
- See https://github.com/rust-lang/cargo/pull/10086#issuecomment-1006751490

Compatibility
- https://github.com/toml-rs/toml/issues/287
- https://github.com/toml-rs/toml/pull/344


Discussion / hints:
@samuelcolvin 

> How does `toml_edit`s performance compare to `toml-rs`?

Last time we looked at this was when deciding if cargo could switch to toml_edit and we found micro-benchmarks to show toml_edit was up to 5% slower.  See https://github.com/rust-lang/cargo/pull/10086#issuecomment-1006751490

@epage I don't understand why you've closed all the issues and pull requests on toml-rs? 

If the library is no longer maintained, mark it as such, but just closing all issues makes it harder to understand what issues toml-rs had, and harder to maintain it going forward. 

You've effectively just destroyed the fastest rust toml parser.

I don't think this is a sensible or considerate way to "maintain" an open source library that many people rely on.

It would be bad enough if you were the sole or primary author, but you're not afaik.

Quite disappointed by this 😞.
Alex was looking for a [new maintainer for `toml`](https://github.com/toml-rs/toml-rs/issues/460) and accepted my proposal for me to maintain it by moving the `toml` crate to be on top of `toml_edit` (`toml_edit` already duplicated `toml`s API).  To make development easier, I wanted to merge the repos as the two sides will be tightly integrated.  Alex and I were planning on archiving the old repo.  Closing out the Issues and PRs was to help let the authors know that the repo was being archived and development has moved to a new repo.

The `toml` crate will still exist.  It will receive only a negligible performance hit.  We will not have to duplicate effort between these crates anymore.
I understand that sometimes projects become unmaintained and need to be archived.

However, toml-rs/toml-rs#460 was only created 5 months ago - for a project as widely used as `toml-rs`, I don't think that's long enough to go from "Anyone else want to maintain this?" to "issues and pull requests deliberately closed, repo archived, no one can comment or contribute in any way!".

I think the decision to close every issue and pull request was a profound mistake, it destroys knowledge (about what issues toml-ts has/had) - or at least makes it much harder to find that knowledge. It's not like `toml-rs` was toxic, had major security bugs or licensing issues.

I'm also pretty surprised and worried that toml-ts has been archived so soon. There are still a significant number of packages which rely on toml-rs, which suddenly have an obsolete dependencies. Including a library I maintain [rtoml](https://github.com/samuelcolvin/rtoml). Does the new, slower library have an identical API so I can switch over easily?

How do you expect people to report bugs to toml-rs now??? You've blocked new issues and PRs. If a security vulnerability is discovered (unlikely I know), how would you propose it be reported?

@alexcrichton do you agree with what @epage has done here?

---

To be constructive, here's my proposal for a reasonable way to go about deprecating a library like this:
* Add a prominent message to the README, explaining what's happening, and how to migrate to a new library, including any associated API changes
* If the change is really urgent, comment on all/some issues saying something similar
* Wait ... wait a reasonably long time for users of the library to realise and migrate way, for a library like this, perhaps a year
* Archive the repo unless anyone brings up major problems with that choice during the notice period

I propose that issues closed today are re-opened and the repo is un-archived for a while, with a prominent message explaining the plan.
The package is not made obsolete by moving repositories. It is not being replaced by `toml_edit`, it is being rewritten to build on `toml_edit`. If another release without that is warranted, it can be created in this repository (you can find the crate [here](https://github.com/toml-rs/toml/tree/main/crates/toml), as of the time of writing this it's still the same old crate, not depending on `toml_edit`).

Issues can be posted on this repo. I don't really understand the problem...
wait, so the code is still being used here?!

Well I'm pleased it's not completely forgotten.

That's not clear at all from the message on https://github.com/toml-rs/toml-rs.

I also think that the disruption caused by archiving the `toml-rs` repo isn't worth the questionable benefits of a mono-repo, but if that is going to happen, why not migrate the issues to this repo, rather than summarily closing them???
@samuelcolvin 
> wait, so the code is still being used here?!

Yes.

@samuelcolvin 
> That's not clear at all from the message on https://github.com/toml-rs/toml-rs.

I might not have been too clear in the PRs but I thought this was fairly clear for Issues,

> Maintenance of this crate has moved 

Meaning the crate will still exist.

> we plan to move toml to be on top of toml_edit

Again, the crate will still exist, it will just depend on `toml_edit`.

@samuelcolvin 
>  why not migrate the issues to this repo, rather than summarily closing them???

I've used a script in the past to migrate issues (e.g. from `structopt` to `clap`) and I considered it here but there were a lot of stale (and soon to be stale) issues over there and the work to triage all of them was going to be large.  I decided to crowd source it by asking people to check if they still care about it and migrate it over.

There are many users and only 1-2 maintainers; we can't do it alone.
I totally hear you on limited maintainers but clicking "Transfer Issue" and selecting a repo barely takes longer than closing the issue.

I'm pleased th `toml-rs` codebase will still be maintained, and I really appreciate the work it takes (I know how thankless open-source maintenance can be). 

But I think you might have under-estimated how disruptive marking a repo with a 1k stars that is (and will remain) the top (or one of the top) links when searching "toml-rs" or "rust toml" will be.

Who knows, that might not be the case, and I might be wrong. I hope I am.
*Sorry if this has been asked already, I'm sure it could be a really annoying question to get repeatedly, but I didn't see it mentioned in the existing comments, and wanted to ask rather than assume one way or the other.*

Is there any intention for mitigating the compile time impact of this?

I have some crates that read toml files in build.rs (which might seem weird, but is also the plan for [metabuild](https://github.com/rust-lang/rfcs/blob/master/text/2196-metabuild.md), FWIW), and I would very much prefer not to add 5-10s[^1] to the time before the build script even can run (because it's in a build script, this sadly must happen even for `check` builds). The `toml` crate as-is is already slow enough to make me not really want to use the format for such a purpose in the future (unfortunate, given that it's a de-facto standard for most Rust configuration and tooling).

Neither here nor there, but I care a lot more about compile-time performance than runtime in... basically all the code I have that parses toml. Large toml files are quite rare in my experience, and I'm not sure I've ever seen them outside of `Cargo.lock` (although they likely exist).

To be clear: I'll totally understand if the answer is "no, the maintenance burden is too much" (and I'd happily accept it if you don't think that this will ultimately necessitate a compile time hit -- you'd be in a better position than I to judge that).

Sorry to bother you if this isn't something you're interested in worrying about as a maintainer, I do get it.

[^1]: On my fastest machine, currently `toml` compiles in ~5s, `toml_edit` in ~10s, and `toml_edit = {..., features=["serde", "easy"]}` (which seems like the equivalent to what the future `toml` crate will be) in ~15s. (All times are from a clean `cargo build` of an otherwise empty binary that just has a single `toml`/`toml_edit` dep).
> 1. On my fastest machine, currently `toml` compiles in ~5s, `toml_edit` in ~10s, and `toml_edit = {..., features=["serde", "easy"]}` (which seems like the equivalent to what the future `toml` crate will be) in ~15s. (All times are from a clean `cargo build` of an otherwise empty binary that just has a single `toml`/`toml_edit` dep).

You'll notice that #327 is the first blocker listed and I am working on it right now.

Yep, sorry! Not sure how I missed that!
From [comment on #327](https://github.com/toml-rs/toml/issues/327#issuecomment-1363550569):

> > We plan to move toml_edit::easy into the toml crate, providing nearly the same API at nearly the same performance while reducing overall maintenance effort and allowing people who have both needs to have a common parser.
> 
> We plan to move toml_edit::easy into the toml crate, providing nearly the same API at nearly the same performance while reducing overall maintenance effort and allowing people who have both needs to have a common parser.
> 
> We do not want toml_edit in tomls public API as toml is easier to maintain compatibility on and I'd like for it to be something people can rely on not changing. Or in other words, I want to take toml to 1.0 soon after this change over happens.

So there will be another crate that does the parsing, which is used by both `toml` and `toml_edit`?
`toml_edit` will be the parser crate.  Just `toml_edit::easy` will change (be removed) and instead it will be in the `toml` crate, calling into `toml_edit`.
> `toml_edit` will be the parser crate. Just `toml_edit::easy` will change (be removed) and instead it will be in the `toml` crate, calling into `toml_edit`.

Thanks for the explanation, though I am a bit worried about the extra compilation time and the increase in binary size caused by this.

I just replace toml_edit with toml in cargo-binstall and that removes 3 dependencies while reducing the size of the debug build https://github.com/cargo-bins/cargo-binstall/pull/610 , but if toml is to use toml_edit, I guess it will be no difference from just keep using toml_edit.
We can't say much about either until #327 is complete but once it is, I'd recommend trying it out and reporting back (as new issue) concrete build time and release binary size numbers for us to evaluate if the impact is bad enough and what we can do about it.

I say release binary size as that is what I expect most end-users will care about (that is what is generally distributed).  If you have a use case for debug binary size, feel free to also share that.


> We can't say much about either until #327 is complete but once it is, I'd recommend trying it out and reporting back (as new issue) concrete build time and release binary size numbers for us to evaluate if the impact is bad enough and what we can do about it.

Sure

> I say release binary size as that is what I expect most end-users will care about (that is what is generally distributed).  If you have a use case for debug binary size, feel free to also share that.

TBH, I also don't care about debug binary size much, I just use it to check whether a PR might increase the final release build.
I'd like to join in the conversation by saying that debug builds will matter for constraint machines.

It seems that the crate can be made `no_std` so it still makes sense not to bloat the size.
Once toml-rs/toml#435 is merged, all of the blockers will be resolved and we can move forward with changing out `toml`s parser.
#457 switched `de` support to `toml_edit`, only leaving `ser` support.
#470 takes care of `ser` support.

That just leaves
- moving around tests
- identifying serde issues this fixes and closing them out
- marking deprecations in 0.5

Fix patch:
diff --git a/crates/toml_edit/src/easy/macros.rs b/crates/toml_edit/src/easy/macros.rs
index abdd9faa..e9895528 100644
--- a/crates/toml_edit/src/easy/macros.rs
+++ b/crates/toml_edit/src/easy/macros.rs
@@ -2,30 +2,8 @@ pub use serde::de::{Deserialize, IntoDeserializer};
 
 use crate::easy::value::{Array, Table, Value};
 
-/// Construct a [`toml_edit::easy::Value`] from TOML syntax.
-///
-/// [`toml_edit::easy::Value`]: value/enum.Value.html
-///
-/// ```rust
-/// let cargo_toml = toml_edit::easy::toml! {
-///     [package]
-///     name = "toml"
-///     version = "0.4.5"
-///     authors = ["Alex Crichton <alex@alexcrichton.com>"]
-///
-///     [badges]
-///     travis-ci = { repository = "alexcrichton/toml-rs" }
-///
-///     [dependencies]
-///     serde = "1.0"
-///
-///     [dev-dependencies]
-///     serde_derive = "1.0"
-///     serde_json = "1.0"
-/// };
-///
-/// println!("{:#?}", cargo_toml);
-/// ```
+#[doc(hidden)]
+#[deprecated(since = "0.18.0", note = "Replaced with `toml::toml!`")]
 #[macro_export]
 macro_rules! toml {
     ($($toml:tt)+) => {{
diff --git a/crates/toml_edit/src/easy/map.rs b/crates/toml_edit/src/easy/map.rs
index 3d18f1bb..061ca962 100644
--- a/crates/toml_edit/src/easy/map.rs
+++ b/crates/toml_edit/src/easy/map.rs
@@ -19,7 +19,8 @@ use serde::{de, ser};
 
 use crate::easy::value::Value;
 
-/// Represents a TOML key/value type.
+#[doc(hidden)]
+#[deprecated(since = "0.18.0", note = "Replaced with `toml::map::Map`")]
 pub struct Map<K, V> {
     map: MapImpl<K, V>,
 }
diff --git a/crates/toml_edit/src/easy/mod.rs b/crates/toml_edit/src/easy/mod.rs
index f1c94219..3bc46193 100644
--- a/crates/toml_edit/src/easy/mod.rs
+++ b/crates/toml_edit/src/easy/mod.rs
@@ -1,137 +1,6 @@
-//! A [TOML]-parsing library
-//!
-//! This library implements a [TOML] v0.5.0 compatible parser,
-//! primarily supporting the [`serde`] library for encoding/decoding
-//! various types in Rust
-//!
-//! **NOTE:** Unlike the core `toml_edit` API, this is not format preserving but is a drop-in
-//! replacement for [toml-rs](https://github.com/alexcrichton/toml-rs) for those needing both
-//! `toml_edit` and `toml-rs` but want either consistency in behavior or to reduce their
-//! dependencies.
-//!
-//! TOML itself is a simple, ergonomic, and readable configuration format:
-//!
-//! ```toml
-//! [package]
-//! name = "toml"
-//! version = "0.4.2"
-//! authors = ["Alex Crichton <alex@alexcrichton.com>"]
-//!
-//! [dependencies]
-//! serde = "1.0"
-//! ```
-//!
-//! The TOML format tends to be relatively common throughout the Rust community
-//! for configuration, notably being used by [Cargo], Rust's package manager.
-//!
-//! ## TOML values
-//!
-//! A value in TOML is represented with the [`Value`] enum in this crate.
-//!
-//! TOML is similar to JSON with the notable addition of a [`Datetime`][crate::Datetime]
-//! type. In general, TOML and JSON are interchangeable in terms of
-//! formats.
-//!
-//! ## Parsing TOML
-//!
-//! The easiest way to parse a TOML document is via the [`Value`] type:
-//!
-//! ```rust
-//! use toml_edit::easy::Value;
-//!
-//! let value = "foo = 'bar'".parse::<Value>().unwrap();
-//!
-//! assert_eq!(value["foo"].as_str(), Some("bar"));
-//! ```
-//!
-//! The [`Value`] type implements a number of convenience methods and
-//! traits; the example above uses [`FromStr`][std::str::FromStr] to parse a [`str`] into a
-//! [`Value`].
-//!
-//! ## Deserialization and Serialization
-//!
-//! This crate supports [`serde`] 1.0 with a number of
-//! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
-//! `Serializer` traits. Namely, you'll find:
-//!
-//! * `Deserialize for Value`
-//! * `Serialize for Value`
-//! * `Deserialize for Datetime`
-//! * `Serialize for Datetime`
-//! * `Deserializer for de::Deserializer`
-//! * `Serializer for ser::Serializer`
-//! * `Deserializer for Value`
-//!
-//! This means that you can use Serde to deserialize/serialize the
-//! [`Value`] type as well as the [`Datetime`][crate::Datetime] type in this crate. You can also
-//! use the [`Deserializer`], [`ValueSerializer`], or [`Value`] type itself to act as
-//! a deserializer/serializer for arbitrary types.
-//!
-//! An example of deserializing with TOML is:
-//!
-//! ```rust
-//! use serde::Deserialize;
-//!
-//! #[derive(Deserialize)]
-//! struct Config {
-//!     ip: String,
-//!     port: Option<u16>,
-//!     keys: Keys,
-//! }
-//!
-//! #[derive(Deserialize)]
-//! struct Keys {
-//!     github: String,
-//!     travis: Option<String>,
-//! }
-//!
-//! let config: Config = toml_edit::easy::from_str(r#"
-//!     ip = '127.0.0.1'
-//!
-//!     [keys]
-//!     github = 'xxxxxxxxxxxxxxxxx'
-//!     travis = 'yyyyyyyyyyyyyyyyy'
-//! "#).unwrap();
-//!
-//! assert_eq!(config.ip, "127.0.0.1");
-//! assert_eq!(config.port, None);
-//! assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx");
-//! assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy");
-//! ```
-//!
-//! You can serialize types in a similar fashion:
-//!
-//! ```rust
-//! use serde::Serialize;
-//!
-//! #[derive(Serialize)]
-//! struct Config {
-//!     ip: String,
-//!     port: Option<u16>,
-//!     keys: Keys,
-//! }
-//!
-//! #[derive(Serialize)]
-//! struct Keys {
-//!     github: String,
-//!     travis: Option<String>,
-//! }
-//!
-//! let config = Config {
-//!     ip: "127.0.0.1".to_string(),
-//!     port: None,
-//!     keys: Keys {
-//!         github: "xxxxxxxxxxxxxxxxx".to_string(),
-//!         travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
-//!     },
-//! };
-//!
-//! let toml = toml_edit::easy::to_string(&config).unwrap();
-//! ```
-//!
-//! [TOML]: https://github.com/toml-lang/toml
-//! [Cargo]: https://crates.io/
-//! [`serde`]: https://serde.rs/
+#![doc(hidden)]
+#![deprecated(since = "0.18.0", note = "Replaced with `toml::Value`")]
+#![allow(deprecated)]
 
 mod datetime;
 
diff --git a/crates/toml_edit/src/easy/value.rs b/crates/toml_edit/src/easy/value.rs
index 4be4cad2..096da369 100644
--- a/crates/toml_edit/src/easy/value.rs
+++ b/crates/toml_edit/src/easy/value.rs
@@ -14,7 +14,8 @@ pub use crate::easy::datetime::*;
 use crate::easy::map::Entry;
 pub use crate::easy::map::Map;
 
-/// Representation of a TOML value.
+#[doc(hidden)]
+#[deprecated(since = "0.18.0", note = "Replaced with `toml::Value`")]
 #[derive(PartialEq, Clone, Debug, serde::Serialize)]
 #[serde(untagged)]
 pub enum Value {
@@ -34,12 +35,12 @@ pub enum Value {
     Table(Table),
 }
 
-/// Type representing a TOML array, payload of the `Value::Array` variant
+#[doc(hidden)]
+#[deprecated(since = "0.18.0", note = "Replaced with `toml::value::Array`")]
 pub type Array = Vec<Value>;
 
-/// Type representing a TOML table, payload of the `Value::Table` variant.
-/// By default it is backed by a BTreeMap, enable the `preserve_order` feature
-/// to use a LinkedHashMap instead.
+#[doc(hidden)]
+#[deprecated(since = "0.18.0", note = "Replaced with `toml::Table`")]
 pub type Table = Map<String, Value>;
 
 impl Value {
diff --git a/crates/toml_edit/src/lib.rs b/crates/toml_edit/src/lib.rs
index 4f6b5745..6ab09875 100644
--- a/crates/toml_edit/src/lib.rs
+++ b/crates/toml_edit/src/lib.rs
@@ -8,9 +8,7 @@
 //! documents, while preserving comments, spaces *and
 //! relative order* or items.
 //!
-//! It is primarily tailored to the needs of [cargo-edit](https://github.com/killercup/cargo-edit/).
-//!
-//! If you also need the ease of a more traditional API, see the [`easy`] module.
+//! If you also need the ease of a more traditional API, see the [`toml`] crate.
 //!
 //! # Example
 //!
@@ -62,6 +60,7 @@
 //! * Scattered array of tables (tables are reordered by default, see [test]).
 //! * Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163).
 //!
+//! [toml]: https://docs.rs/toml/latest/toml/
 //! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84
 
 mod array;


Test patch: