use serde::de::Error;
use serde::de::IgnoredAny;
use serde::de::MapAccess;
use serde::de::SeqAccess;
use serde::de::Visitor;
use super::DurationPayload;
use super::duration_payload_field::DurationPayloadField;
pub(super) struct DurationPayloadVisitor {
allow_sequence: bool,
}
impl DurationPayloadVisitor {
#[must_use]
#[inline]
pub(super) fn new(allow_sequence: bool) -> Self {
Self { allow_sequence }
}
}
impl<'de> Visitor<'de> for DurationPayloadVisitor {
type Value = DurationPayload;
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("duration payload record with secs and nanos 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 secs = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(0, &self))?;
let nanos = 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(DurationPayload { secs, nanos })
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut secs = None;
let mut nanos = None;
while let Some(key) = map.next_key::<DurationPayloadField>()? {
match key {
DurationPayloadField::Secs => {
if secs.is_some() {
return Err(Error::duplicate_field("secs"));
}
secs = Some(map.next_value()?);
}
DurationPayloadField::Nanos => {
if nanos.is_some() {
return Err(Error::duplicate_field("nanos"));
}
nanos = Some(map.next_value()?);
}
}
}
Ok(DurationPayload {
secs: secs.ok_or_else(|| Error::missing_field("secs"))?,
nanos: nanos.ok_or_else(|| Error::missing_field("nanos"))?,
})
}
}