use {
super::RawJson,
serde::de::{Deserialize, Error, IgnoredAny, MapAccess, SeqAccess, Visitor},
std::{fmt, str::FromStr},
};
#[derive(Debug, Clone, Copy)]
pub(crate) struct LazyVisitor<'p> {
k_or_idx: &'p str,
}
impl<'p> LazyVisitor<'p> {
pub(crate) fn new(k_or_idx: &'p str) -> Self {
Self { k_or_idx }
}
}
impl<'de, 'p> Visitor<'de> for LazyVisitor<'p> {
type Value = &'de RawJson;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"a map or array including the key or index: {}",
self.k_or_idx
)
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
internal_visit_map(self.k_or_idx, map)
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let index = u64::from_str(self.k_or_idx)
.map_err(|_| Error::custom(format!("not an indexable number: {}", self.k_or_idx)))?;
internal_visit_seq(index, seq)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct MapVisitor<'p> {
key: &'p str,
}
impl<'p> MapVisitor<'p> {
pub(crate) fn new(key: &'p str) -> Self {
Self { key }
}
}
impl<'de, 'p> Visitor<'de> for MapVisitor<'p> {
type Value = &'de RawJson;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a map including the key: {}", self.key)
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
internal_visit_map(self.key, map)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct ArrayVisitor {
index: u64,
}
impl ArrayVisitor {
pub(crate) fn new(index: u64) -> Self {
Self { index }
}
}
impl<'de> Visitor<'de> for ArrayVisitor {
type Value = &'de RawJson;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "an array including the index: {}", self.index)
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
internal_visit_seq(self.index, seq)
}
}
fn internal_visit_map<'de, A, T>(target: &str, map: A) -> Result<T, A::Error>
where
T: Deserialize<'de>,
A: MapAccess<'de>,
{
let mut map = map;
let mut out = None;
while let Some(k) = map.next_key::<&str>()? {
match k == target {
false => {
map.next_value::<IgnoredAny>()?;
}
true => {
out = Some(map.next_value()?);
break;
}
}
}
while let Some((_k, _v)) = map.next_entry::<IgnoredAny, IgnoredAny>()? {}
out.ok_or_else(|| Error::custom(format!("unable to locate a value with the key: {}", target)))
}
fn internal_visit_seq<'de, A, T>(target: u64, seq: A) -> Result<T, A::Error>
where
T: Deserialize<'de>,
A: SeqAccess<'de>,
{
let mut seq = seq;
let mut count = 0;
while count < target {
if seq.next_element::<IgnoredAny>()?.is_none() {
break;
}
count += 1;
}
let out = seq.next_element()?;
while let Some(_val) = seq.next_element::<IgnoredAny>()? {}
out.ok_or_else(|| {
Error::custom(format!(
"unable to locate a value with the index: {}",
target
))
})
}