use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
use serde::de::Error;
use serde::de::IgnoredAny;
use serde::de::MapAccess;
use serde::de::SeqAccess;
use serde::de::Visitor;
use super::NamedValueWireOwned;
use super::named_value_field::NamedValueField;
use crate::ValueWireV1;
use crate::ValueWireV1Seed;
pub(super) struct NamedValueWireOwnedVisitor {
allow_sequence: bool,
}
impl NamedValueWireOwnedVisitor {
#[must_use]
#[inline]
pub(super) fn new(allow_sequence: bool) -> Self {
Self { allow_sequence }
}
}
impl<'de> Visitor<'de> for NamedValueWireOwnedVisitor {
type Value = NamedValueWireOwned;
fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str("named scalar record with name 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 name = seq
.next_element()?
.ok_or_else(|| Error::invalid_length(0, &self))?;
let value = seq
.next_element_seed(ValueWireV1Seed::new())?
.ok_or_else(|| Error::invalid_length(1, &self))?;
if seq.next_element::<IgnoredAny>()?.is_some() {
return Err(Error::invalid_length(3, &self));
}
Ok(NamedValueWireOwned { name, value })
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut name: Option<String> = None;
let mut value: Option<ValueWireV1> = None;
while let Some(key) = map.next_key::<NamedValueField>()? {
match key {
NamedValueField::Name => {
if name.is_some() {
return Err(Error::duplicate_field("name"));
}
name = Some(map.next_value()?);
}
NamedValueField::Value => {
if value.is_some() {
return Err(Error::duplicate_field("value"));
}
value = Some(map.next_value_seed(ValueWireV1Seed::new())?);
}
}
}
Ok(NamedValueWireOwned {
name: name.ok_or_else(|| Error::missing_field("name"))?,
value: value.ok_or_else(|| Error::missing_field("value"))?,
})
}
}