use serde::de::Error;
use serde::de::IgnoredAny;
use serde::de::MapAccess;
use serde::de::SeqAccess;
use serde::de::Visitor;
use super::WireEnvelopeOwned;
use super::wire_envelope_field::WireEnvelopeField;
pub(super) struct WireEnvelopeOwnedVisitor {
allow_sequence: bool,
}
impl WireEnvelopeOwnedVisitor {
#[must_use]
#[inline]
pub(super) fn new(allow_sequence: bool) -> Self {
Self { allow_sequence }
}
}
impl<'de> Visitor<'de> for WireEnvelopeOwnedVisitor {
type Value = WireEnvelopeOwned;
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("wire envelope record with version and value fields")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
if !self.allow_sequence {
return Err(Error::custom("human-readable record must use named fields"));
}
let version = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(0, &self))?;
let value = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(1, &self))?;
if seq.next_element::<IgnoredAny>()?.is_some() {
return Err(Error::invalid_length(3, &self));
}
Ok(WireEnvelopeOwned { version, value })
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut version = None;
let mut value = None;
while let Some(key) = map.next_key::<WireEnvelopeField>()? {
match key {
WireEnvelopeField::Version => {
if version.is_some() {
return Err(Error::duplicate_field("version"));
}
version = Some(map.next_value()?);
}
WireEnvelopeField::Value => {
if value.is_some() {
return Err(Error::duplicate_field("value"));
}
value = Some(map.next_value()?);
}
}
}
Ok(WireEnvelopeOwned {
version: version.ok_or_else(|| Error::missing_field("version"))?,
value: value.ok_or_else(|| Error::missing_field("value"))?,
})
}
}