Use serde-untagged to improve some untagged enum error messages (#7822)

## Summary

This is related to https://github.com/astral-sh/uv/issues/7817, but
doesn't close it.
This commit is contained in:
Charlie Marsh 2024-09-30 19:40:21 -04:00 committed by GitHub
parent 67769a4985
commit b6de417c94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 123 additions and 44 deletions

View file

@ -27,6 +27,7 @@ mailparse = { workspace = true }
regex = { workspace = true }
rkyv = { workspace = true }
serde = { workspace = true }
serde-untagged = { workspace = true }
thiserror = { workspace = true }
toml = { workspace = true }
toml_edit = { workspace = true }

View file

@ -1,9 +1,8 @@
use std::str::FromStr;
use jiff::Timestamp;
use serde::{Deserialize, Deserializer, Serialize};
use pep440_rs::{VersionSpecifiers, VersionSpecifiersParseError};
use serde::{Deserialize, Deserializer, Serialize};
use crate::lenient_requirement::LenientVersionSpecifiers;
@ -71,13 +70,24 @@ where
))
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
#[derive(Debug, Clone)]
pub enum CoreMetadata {
Bool(bool),
Hashes(Hashes),
}
impl<'de> Deserialize<'de> for CoreMetadata {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
serde_untagged::UntaggedEnumVisitor::new()
.bool(|bool| Ok(CoreMetadata::Bool(bool)))
.map(|map| map.deserialize().map(CoreMetadata::Hashes))
.deserialize(deserializer)
}
}
impl CoreMetadata {
pub fn is_available(&self) -> bool {
match self {
@ -87,24 +97,25 @@ impl CoreMetadata {
}
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Hash,
Deserialize,
rkyv::Archive,
rkyv::Deserialize,
rkyv::Serialize,
)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[rkyv(derive(Debug))]
#[serde(untagged)]
pub enum Yanked {
Bool(bool),
Reason(String),
}
impl<'de> Deserialize<'de> for Yanked {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
serde_untagged::UntaggedEnumVisitor::new()
.bool(|bool| Ok(Yanked::Bool(bool)))
.string(|string| Ok(Yanked::Reason(string.to_owned())))
.deserialize(deserializer)
}
}
impl Yanked {
pub fn is_yanked(&self) -> bool {
match self {