diff --git a/Cargo.lock b/Cargo.lock index bfb9aa31..a155e50c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -234,6 +234,7 @@ dependencies = [ "ron", "rust-ini", "serde", + "serde-untagged", "serde_derive", "serde_json", "snapbox", @@ -357,6 +358,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.5" @@ -1345,18 +1356,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -1619,18 +1630,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] +[[package]] +name = "serde-untagged" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3" +dependencies = [ + "erased-serde", + "serde", + "typeid", +] + [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1769,9 +1791,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.38" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -2056,6 +2078,12 @@ dependencies = [ "utf-8", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.17.0" diff --git a/Cargo.toml b/Cargo.toml index 59ac8873..063ba7e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,7 @@ default = ["toml", "json", "yaml", "ini", "ron", "json5", "convert-case", "async json = ["serde_json"] yaml = ["yaml-rust2"] ini = ["rust-ini"] -json5 = ["json5_rs", "serde/derive"] +json5 = ["json5_rs", "dep:serde-untagged"] convert-case = ["convert_case"] preserve_order = ["indexmap", "toml?/preserve_order", "serde_json?/preserve_order", "ron?/indexmap"] async = ["async-trait"] @@ -145,6 +145,7 @@ indexmap = { version = "2.10.0", features = ["serde"], optional = true } convert_case = { version = "0.6", optional = true } pathdiff = "0.2" winnow = "0.7.0" +serde-untagged = { version = "0.1.8", optional = true } [dev-dependencies] serde_derive = "1.0" diff --git a/src/file/format/json5.rs b/src/file/format/json5.rs index c0e557fc..56397e66 100644 --- a/src/file/format/json5.rs +++ b/src/file/format/json5.rs @@ -4,8 +4,7 @@ use crate::format; use crate::map::Map; use crate::value::{Value, ValueKind}; -#[derive(serde::Deserialize, Debug)] -#[serde(untagged)] +#[derive(Debug)] pub(crate) enum Val { Null, Boolean(bool), @@ -16,6 +15,23 @@ pub(crate) enum Val { Object(Map), } +impl<'de> serde::de::Deserialize<'de> for Val { + fn deserialize(d: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + serde_untagged::UntaggedEnumVisitor::new() + .bool(|value| Ok(Self::Boolean(value))) + .i64(|value| Ok(Self::Integer(value))) + .f64(|value| Ok(Self::Float(value))) + .string(|value| Ok(Val::String(value.to_owned()))) + .none(|| Ok(Self::Null)) + .seq(|value| value.deserialize().map(Val::Array)) + .map(|value| value.deserialize().map(Val::Object)) + .deserialize(d) + } +} + pub(crate) fn parse( uri: Option<&String>, text: &str, diff --git a/src/ser.rs b/src/ser.rs index 46b90e45..041938be 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -676,8 +676,6 @@ impl ser::SerializeStructVariant for Unreachable { #[cfg(test)] mod test { - use serde::{Deserialize, Serialize}; - #[cfg(not(feature = "json5"))] use serde_derive::{Deserialize, Serialize}; use super::*;