in crates/iceberg/src/spec/values.rs [138:214]
fn deserialize<D: serde::Deserializer<'de>>(
deserializer: D,
) -> std::result::Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Type,
Literal,
}
struct DatumVisitor;
impl<'de> serde::de::Visitor<'de> for DatumVisitor {
type Value = Datum;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("struct Datum")
}
fn visit_seq<A>(self, mut seq: A) -> std::result::Result<Self::Value, A::Error>
where A: serde::de::SeqAccess<'de> {
let r#type = seq
.next_element::<PrimitiveType>()?
.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
let value = seq
.next_element::<RawLiteral>()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
let Literal::Primitive(primitive) = value
.try_into(&Type::Primitive(r#type.clone()))
.map_err(serde::de::Error::custom)?
.ok_or_else(|| serde::de::Error::custom("None value"))?
else {
return Err(serde::de::Error::custom("Invalid value"));
};
Ok(Datum::new(r#type, primitive))
}
fn visit_map<V>(self, mut map: V) -> std::result::Result<Datum, V::Error>
where V: MapAccess<'de> {
let mut raw_primitive: Option<RawLiteral> = None;
let mut r#type: Option<PrimitiveType> = None;
while let Some(key) = map.next_key()? {
match key {
Field::Type => {
if r#type.is_some() {
return Err(de::Error::duplicate_field("type"));
}
r#type = Some(map.next_value()?);
}
Field::Literal => {
if raw_primitive.is_some() {
return Err(de::Error::duplicate_field("literal"));
}
raw_primitive = Some(map.next_value()?);
}
}
}
let Some(r#type) = r#type else {
return Err(serde::de::Error::missing_field("type"));
};
let Some(raw_primitive) = raw_primitive else {
return Err(serde::de::Error::missing_field("literal"));
};
let Literal::Primitive(primitive) = raw_primitive
.try_into(&Type::Primitive(r#type.clone()))
.map_err(serde::de::Error::custom)?
.ok_or_else(|| serde::de::Error::custom("None value"))?
else {
return Err(serde::de::Error::custom("Invalid value"));
};
Ok(Datum::new(r#type, primitive))
}
}
const FIELDS: &[&str] = &["type", "literal"];
deserializer.deserialize_struct("Datum", FIELDS, DatumVisitor)
}