Skip to content

Commit d0a7cd6

Browse files
authored
perf(json5): Remove use of serde(untagged) (#677)
Prep for #472 `serde(untagged)` translates to an `if`/`else if` ladder that ends up being pretty expensive, including the error generation for each branch that gets skipped. This switches us to dispatch on type instead, speeding things up. This is also prep for speeding up builds by removing the need for `serde_derive`. Once `serde_core` is published, we can depend on that and not wait for `syn`, `quote`, etc.
2 parents 07f13ff + 43d5b6b commit d0a7cd6

File tree

4 files changed

+58
-15
lines changed

4 files changed

+58
-15
lines changed

Cargo.lock

Lines changed: 38 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ default = ["toml", "json", "yaml", "ini", "ron", "json5", "convert-case", "async
125125
json = ["serde_json"]
126126
yaml = ["yaml-rust2"]
127127
ini = ["rust-ini"]
128-
json5 = ["json5_rs", "serde/derive"]
128+
json5 = ["json5_rs", "dep:serde-untagged"]
129129
convert-case = ["convert_case"]
130130
preserve_order = ["indexmap", "toml?/preserve_order", "serde_json?/preserve_order", "ron?/indexmap"]
131131
async = ["async-trait"]
@@ -145,6 +145,7 @@ indexmap = { version = "2.10.0", features = ["serde"], optional = true }
145145
convert_case = { version = "0.6", optional = true }
146146
pathdiff = "0.2"
147147
winnow = "0.7.0"
148+
serde-untagged = { version = "0.1.8", optional = true }
148149

149150
[dev-dependencies]
150151
serde_derive = "1.0"

src/file/format/json5.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use crate::format;
44
use crate::map::Map;
55
use crate::value::{Value, ValueKind};
66

7-
#[derive(serde::Deserialize, Debug)]
8-
#[serde(untagged)]
7+
#[derive(Debug)]
98
pub(crate) enum Val {
109
Null,
1110
Boolean(bool),
@@ -16,6 +15,23 @@ pub(crate) enum Val {
1615
Object(Map<String, Self>),
1716
}
1817

18+
impl<'de> serde::de::Deserialize<'de> for Val {
19+
fn deserialize<D>(d: D) -> Result<Self, D::Error>
20+
where
21+
D: serde::de::Deserializer<'de>,
22+
{
23+
serde_untagged::UntaggedEnumVisitor::new()
24+
.bool(|value| Ok(Self::Boolean(value)))
25+
.i64(|value| Ok(Self::Integer(value)))
26+
.f64(|value| Ok(Self::Float(value)))
27+
.string(|value| Ok(Val::String(value.to_owned())))
28+
.none(|| Ok(Self::Null))
29+
.seq(|value| value.deserialize().map(Val::Array))
30+
.map(|value| value.deserialize().map(Val::Object))
31+
.deserialize(d)
32+
}
33+
}
34+
1935
pub(crate) fn parse(
2036
uri: Option<&String>,
2137
text: &str,

src/ser.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,8 +676,6 @@ impl ser::SerializeStructVariant for Unreachable {
676676

677677
#[cfg(test)]
678678
mod test {
679-
use serde::{Deserialize, Serialize};
680-
#[cfg(not(feature = "json5"))]
681679
use serde_derive::{Deserialize, Serialize};
682680

683681
use super::*;

0 commit comments

Comments
 (0)