Skip to content

Commit 17c4431

Browse files
committed
refactor: Use more serde_untagged
1 parent 94770a5 commit 17c4431

File tree

1 file changed

+55
-143
lines changed

1 file changed

+55
-143
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 55 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -400,39 +400,22 @@ impl<'de> de::Deserialize<'de> for TomlOptLevel {
400400
where
401401
D: de::Deserializer<'de>,
402402
{
403-
struct Visitor;
404-
405-
impl<'de> de::Visitor<'de> for Visitor {
406-
type Value = TomlOptLevel;
407-
408-
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
409-
formatter.write_str("an optimization level")
410-
}
411-
412-
fn visit_i64<E>(self, value: i64) -> Result<TomlOptLevel, E>
413-
where
414-
E: de::Error,
415-
{
416-
Ok(TomlOptLevel(value.to_string()))
417-
}
418-
419-
fn visit_str<E>(self, value: &str) -> Result<TomlOptLevel, E>
420-
where
421-
E: de::Error,
422-
{
403+
use serde::de::Error as _;
404+
UntaggedEnumVisitor::new()
405+
.expecting("an optimization level")
406+
.i64(|value| Ok(TomlOptLevel(value.to_string())))
407+
.string(|value| {
423408
if value == "s" || value == "z" {
424409
Ok(TomlOptLevel(value.to_string()))
425410
} else {
426-
Err(E::custom(format!(
411+
Err(serde_untagged::de::Error::custom(format!(
427412
"must be `0`, `1`, `2`, `3`, `s` or `z`, \
428413
but found the string: \"{}\"",
429414
value
430415
)))
431416
}
432-
}
433-
}
434-
435-
d.deserialize_any(Visitor)
417+
})
418+
.deserialize(d)
436419
}
437420
}
438421

@@ -477,58 +460,48 @@ impl<'de> de::Deserialize<'de> for TomlDebugInfo {
477460
where
478461
D: de::Deserializer<'de>,
479462
{
480-
struct Visitor;
481-
482-
impl<'de> de::Visitor<'de> for Visitor {
483-
type Value = TomlDebugInfo;
484-
485-
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
486-
formatter.write_str(
487-
"a boolean, 0, 1, 2, \"line-tables-only\", or \"line-directives-only\"",
488-
)
489-
}
490-
491-
fn visit_i64<E>(self, value: i64) -> Result<TomlDebugInfo, E>
492-
where
493-
E: de::Error,
494-
{
463+
use serde::de::Error as _;
464+
let expecting = "a boolean, 0, 1, 2, \"line-tables-only\", or \"line-directives-only\"";
465+
UntaggedEnumVisitor::new()
466+
.expecting(expecting)
467+
.bool(|value| {
468+
Ok(if value {
469+
TomlDebugInfo::Full
470+
} else {
471+
TomlDebugInfo::None
472+
})
473+
})
474+
.i64(|value| {
495475
let debuginfo = match value {
496476
0 => TomlDebugInfo::None,
497477
1 => TomlDebugInfo::Limited,
498478
2 => TomlDebugInfo::Full,
499-
_ => return Err(de::Error::invalid_value(Unexpected::Signed(value), &self)),
479+
_ => {
480+
return Err(serde_untagged::de::Error::invalid_value(
481+
Unexpected::Signed(value),
482+
&expecting,
483+
))
484+
}
500485
};
501486
Ok(debuginfo)
502-
}
503-
504-
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
505-
where
506-
E: de::Error,
507-
{
508-
Ok(if v {
509-
TomlDebugInfo::Full
510-
} else {
511-
TomlDebugInfo::None
512-
})
513-
}
514-
515-
fn visit_str<E>(self, value: &str) -> Result<TomlDebugInfo, E>
516-
where
517-
E: de::Error,
518-
{
487+
})
488+
.string(|value| {
519489
let debuginfo = match value {
520490
"none" => TomlDebugInfo::None,
521491
"limited" => TomlDebugInfo::Limited,
522492
"full" => TomlDebugInfo::Full,
523493
"line-directives-only" => TomlDebugInfo::LineDirectivesOnly,
524494
"line-tables-only" => TomlDebugInfo::LineTablesOnly,
525-
_ => return Err(de::Error::invalid_value(Unexpected::Str(value), &self)),
495+
_ => {
496+
return Err(serde_untagged::de::Error::invalid_value(
497+
Unexpected::Str(value),
498+
&expecting,
499+
))
500+
}
526501
};
527502
Ok(debuginfo)
528-
}
529-
}
530-
531-
d.deserialize_any(Visitor)
503+
})
504+
.deserialize(d)
532505
}
533506
}
534507

@@ -927,32 +900,11 @@ impl<'de> de::Deserialize<'de> for StringOrVec {
927900
where
928901
D: de::Deserializer<'de>,
929902
{
930-
struct Visitor;
931-
932-
impl<'de> de::Visitor<'de> for Visitor {
933-
type Value = StringOrVec;
934-
935-
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
936-
formatter.write_str("string or list of strings")
937-
}
938-
939-
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
940-
where
941-
E: de::Error,
942-
{
943-
Ok(StringOrVec(vec![s.to_string()]))
944-
}
945-
946-
fn visit_seq<V>(self, v: V) -> Result<Self::Value, V::Error>
947-
where
948-
V: de::SeqAccess<'de>,
949-
{
950-
let seq = de::value::SeqAccessDeserializer::new(v);
951-
Vec::deserialize(seq).map(StringOrVec)
952-
}
953-
}
954-
955-
deserializer.deserialize_any(Visitor)
903+
UntaggedEnumVisitor::new()
904+
.expecting("string or list of strings")
905+
.string(|value| Ok(StringOrVec(vec![value.to_owned()])))
906+
.seq(|value| value.deserialize().map(StringOrVec))
907+
.deserialize(deserializer)
956908
}
957909
}
958910

@@ -975,8 +927,8 @@ impl<'de> Deserialize<'de> for StringOrBool {
975927
D: de::Deserializer<'de>,
976928
{
977929
UntaggedEnumVisitor::new()
978-
.string(|s| Ok(StringOrBool::String(s.to_owned())))
979930
.bool(|b| Ok(StringOrBool::Bool(b)))
931+
.string(|s| Ok(StringOrBool::String(s.to_owned())))
980932
.deserialize(deserializer)
981933
}
982934
}
@@ -993,68 +945,28 @@ impl<'de> de::Deserialize<'de> for VecStringOrBool {
993945
where
994946
D: de::Deserializer<'de>,
995947
{
996-
struct Visitor;
997-
998-
impl<'de> de::Visitor<'de> for Visitor {
999-
type Value = VecStringOrBool;
1000-
1001-
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1002-
formatter.write_str("a boolean or vector of strings")
1003-
}
1004-
1005-
fn visit_seq<V>(self, v: V) -> Result<Self::Value, V::Error>
1006-
where
1007-
V: de::SeqAccess<'de>,
1008-
{
1009-
let seq = de::value::SeqAccessDeserializer::new(v);
1010-
Vec::deserialize(seq).map(VecStringOrBool::VecString)
1011-
}
1012-
1013-
fn visit_bool<E>(self, b: bool) -> Result<Self::Value, E>
1014-
where
1015-
E: de::Error,
1016-
{
1017-
Ok(VecStringOrBool::Bool(b))
1018-
}
1019-
}
1020-
1021-
deserializer.deserialize_any(Visitor)
948+
UntaggedEnumVisitor::new()
949+
.expecting("a boolean or vector of strings")
950+
.bool(|value| Ok(VecStringOrBool::Bool(value)))
951+
.seq(|value| value.deserialize().map(VecStringOrBool::VecString))
952+
.deserialize(deserializer)
1022953
}
1023954
}
1024955

1025956
fn version_trim_whitespace<'de, D>(deserializer: D) -> Result<MaybeWorkspaceSemverVersion, D::Error>
1026957
where
1027958
D: de::Deserializer<'de>,
1028959
{
1029-
struct Visitor;
1030-
1031-
impl<'de> de::Visitor<'de> for Visitor {
1032-
type Value = MaybeWorkspaceSemverVersion;
1033-
1034-
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1035-
formatter.write_str("SemVer version")
1036-
}
1037-
1038-
fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
1039-
where
1040-
E: de::Error,
1041-
{
1042-
match string.trim().parse().map_err(de::Error::custom) {
960+
UntaggedEnumVisitor::new()
961+
.expecting("SemVer version")
962+
.string(
963+
|value| match value.trim().parse().map_err(de::Error::custom) {
1043964
Ok(parsed) => Ok(MaybeWorkspace::Defined(parsed)),
1044965
Err(e) => Err(e),
1045-
}
1046-
}
1047-
1048-
fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
1049-
where
1050-
V: de::MapAccess<'de>,
1051-
{
1052-
let mvd = de::value::MapAccessDeserializer::new(map);
1053-
TomlWorkspaceField::deserialize(mvd).map(MaybeWorkspace::Workspace)
1054-
}
1055-
}
1056-
1057-
deserializer.deserialize_any(Visitor)
966+
},
967+
)
968+
.map(|value| value.deserialize().map(MaybeWorkspace::Workspace))
969+
.deserialize(deserializer)
1058970
}
1059971

1060972
/// This Trait exists to make [`MaybeWorkspace::Workspace`] generic. It makes deserialization of

0 commit comments

Comments
 (0)