diff --git a/Cargo.lock b/Cargo.lock index aea58177e094..8bd202cacba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5281,7 +5281,6 @@ dependencies = [ "same-file", "schemars", "serde", - "serde-untagged", "tempfile", "thiserror", "tokio", diff --git a/crates/uv-distribution/src/metadata/requires_dist.rs b/crates/uv-distribution/src/metadata/requires_dist.rs index e1b1d763d4ea..730c287b1eba 100644 --- a/crates/uv-distribution/src/metadata/requires_dist.rs +++ b/crates/uv-distribution/src/metadata/requires_dist.rs @@ -278,7 +278,8 @@ mod test { | 8 | tqdm = true | ^^^^ - invalid type: boolean `true`, expected an array or map + invalid type: boolean `true`, expected a single source (as a map) or list of sources + "###); } @@ -301,7 +302,6 @@ mod test { 8 | tqdm = { git = "https://github.com/tqdm/tqdm", rev = "baaaaaab", tag = "v1.0.0" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most one of `rev`, `tag`, or `branch` - "###); } @@ -319,10 +319,10 @@ mod test { "#}; assert_snapshot!(format_err(input).await, @r###" - error: TOML parse error at line 8, column 8 + error: TOML parse error at line 8, column 48 | 8 | tqdm = { git = "https://github.com/tqdm/tqdm", ref = "baaaaaab" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ unknown field `ref`, expected one of `git`, `subdirectory`, `rev`, `tag`, `branch`, `url`, `path`, `editable`, `index`, `workspace`, `marker` "###); } @@ -399,14 +399,12 @@ mod test { "#}; assert_snapshot!(format_err(input).await, @r###" - error: TOML parse error at line 8, column 8 + error: TOML parse error at line 8, column 16 | 8 | tqdm = { url = "§invalid#+#*Ä" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ invalid value: string "§invalid#+#*Ä", expected relative URL without a base - - in `url` "###); } diff --git a/crates/uv-workspace/Cargo.toml b/crates/uv-workspace/Cargo.toml index 040f9fe068ba..967a90ae3ff4 100644 --- a/crates/uv-workspace/Cargo.toml +++ b/crates/uv-workspace/Cargo.toml @@ -37,7 +37,6 @@ rustc-hash = { workspace = true } same-file = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } -serde-untagged = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } toml = { workspace = true } diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index c72a3d7d5187..605a6e6f7df4 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -8,6 +8,7 @@ use glob::Pattern; use owo_colors::OwoColorize; +use serde::de::SeqAccess; use serde::{de::IntoDeserializer, Deserialize, Deserializer, Serialize}; use std::ops::Deref; use std::path::{Path, PathBuf}; @@ -502,10 +503,37 @@ impl<'de> serde::de::Deserialize<'de> for SourcesWire { where D: Deserializer<'de>, { - serde_untagged::UntaggedEnumVisitor::new() - .map(|map| map.deserialize().map(SourcesWire::One)) - .seq(|seq| seq.deserialize().map(SourcesWire::Many)) - .deserialize(deserializer) + struct Visitor; + + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = SourcesWire; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a single source (as a map) or list of sources") + } + + fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let sources = serde::de::Deserialize::deserialize( + serde::de::value::SeqAccessDeserializer::new(seq), + )?; + Ok(SourcesWire::Many(sources)) + } + + fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error> + where + M: serde::de::MapAccess<'de>, + { + let source = serde::de::Deserialize::deserialize( + serde::de::value::MapAccessDeserializer::new(&mut map), + )?; + Ok(SourcesWire::One(source)) + } + } + + deserializer.deserialize_any(Visitor) } }