use serde::de::{self, IntoDeserializer, Visitor};
use super::{Error, Location};
use crate::Deserializer;
#[cold]
fn unreachable_deserialize_any(what: &str) -> Error {
Error::msg(format!("{what}::deserialize_any should not be reachable"))
}
#[cfg(not(feature = "huge_documents"))]
#[inline]
fn span_index_to_u64(v: crate::location::SpanIndex) -> u64 {
v as u64
}
#[cfg(feature = "huge_documents")]
#[inline]
fn span_index_to_u64(v: crate::location::SpanIndex) -> u64 {
v
}
pub(super) fn deserialize_yaml_spanned<'de, V>(
de: Deserializer<'de, '_>,
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
let loc = match de.ev.peek()? {
Some(ev) => ev.location(),
None => de.ev.last_location(),
};
let defined: Location = loc;
let referenced: Location = de.ev.reference_location();
visitor.visit_newtype_struct(SpannedDeser {
de,
referenced,
defined,
state: 0,
})
}
struct SpannedDeser<'de, 'e> {
de: Deserializer<'de, 'e>,
referenced: Location,
defined: Location,
state: u8,
}
impl<'de, 'e> de::Deserializer<'de> for SpannedDeser<'de, 'e> {
type Error = Error;
fn deserialize_any<Vv: Visitor<'de>>(self, visitor: Vv) -> Result<Vv::Value, Self::Error> {
self.deserialize_struct("Spanned", &["value", "referenced", "defined"], visitor)
}
fn deserialize_struct<Vv: Visitor<'de>>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: Vv,
) -> Result<Vv::Value, Self::Error> {
visitor.visit_map(SpannedMapAccess {
de: self.de,
referenced: self.referenced,
defined: self.defined,
state: self.state,
})
}
serde::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map enum identifier ignored_any
}
}
struct SpannedMapAccess<'de, 'e> {
de: Deserializer<'de, 'e>,
referenced: Location,
defined: Location,
state: u8,
}
impl<'de, 'e> de::MapAccess<'de> for SpannedMapAccess<'de, 'e> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: de::DeserializeSeed<'de>,
{
let key = match self.state {
0 => "value",
1 => "referenced",
2 => "defined",
_ => return Ok(None),
};
self.state += 1;
seed.deserialize(key.into_deserializer()).map(Some)
}
fn next_value_seed<Vv>(&mut self, seed: Vv) -> Result<Vv::Value, Error>
where
Vv: de::DeserializeSeed<'de>,
{
match self.state {
1 => {
seed.deserialize(Deserializer::new(&mut *self.de.ev, self.de.cfg))
}
2 => {
seed.deserialize(LocationDeser {
location: self.referenced,
})
}
3 => {
seed.deserialize(LocationDeser {
location: self.defined,
})
}
_ => Err(Error::msg("invalid Spanned<T> internal state")),
}
}
}
struct LocationDeser {
location: Location,
}
impl<'de> de::Deserializer<'de> for LocationDeser {
type Error = Error;
fn deserialize_any<Vv: Visitor<'de>>(self, _visitor: Vv) -> Result<Vv::Value, Self::Error> {
Err(unreachable_deserialize_any("LocationDeser"))
}
fn deserialize_struct<Vv: Visitor<'de>>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: Vv,
) -> Result<Vv::Value, Self::Error> {
visitor.visit_map(LocationMapAccess {
location: self.location,
state: 0,
})
}
serde::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map enum identifier ignored_any
}
}
struct LocationMapAccess {
location: Location,
state: u8,
}
impl<'de> de::MapAccess<'de> for LocationMapAccess {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: de::DeserializeSeed<'de>,
{
let key = match self.state {
0 => "line",
1 => "column",
2 => "span",
_ => return Ok(None),
};
self.state += 1;
seed.deserialize(key.into_deserializer()).map(Some)
}
fn next_value_seed<Vv>(&mut self, seed: Vv) -> Result<Vv::Value, Error>
where
Vv: de::DeserializeSeed<'de>,
{
match self.state {
1 => seed.deserialize(self.location.line.into_deserializer()),
2 => seed.deserialize(self.location.column.into_deserializer()),
3 => seed.deserialize(SpanDeser {
span: self.location.span,
}),
_ => Err(Error::msg("invalid Location internal state")),
}
}
}
struct SpanDeser {
span: crate::Span,
}
impl<'de> de::Deserializer<'de> for SpanDeser {
type Error = Error;
fn deserialize_any<Vv: Visitor<'de>>(self, _visitor: Vv) -> Result<Vv::Value, Self::Error> {
Err(unreachable_deserialize_any("SpanDeser"))
}
fn deserialize_struct<Vv: Visitor<'de>>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: Vv,
) -> Result<Vv::Value, Self::Error> {
visitor.visit_map(SpanMapAccess {
span: self.span,
state: 0,
})
}
serde::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map enum identifier ignored_any
}
}
struct ByteInfoTupleDeser((crate::location::SpanIndex, crate::location::SpanIndex));
impl<'de> de::Deserializer<'de> for ByteInfoTupleDeser {
type Error = Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
Err(unreachable_deserialize_any("ByteInfoTupleDeser"))
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_seq(ByteInfoSeqAccess {
byte_info: self.0,
index: 0,
})
}
serde::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq
tuple_struct map struct enum identifier ignored_any
}
}
struct ByteInfoSeqAccess {
byte_info: (crate::location::SpanIndex, crate::location::SpanIndex),
index: u8,
}
impl<'de> de::SeqAccess<'de> for ByteInfoSeqAccess {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
match self.index {
0 => {
self.index += 1;
let v = span_index_to_u64(self.byte_info.0);
seed.deserialize(v.into_deserializer()).map(Some)
}
1 => {
self.index += 1;
let v = span_index_to_u64(self.byte_info.1);
seed.deserialize(v.into_deserializer()).map(Some)
}
_ => Ok(None),
}
}
}
struct SpanMapAccess {
span: crate::Span,
state: u8,
}
impl<'de> de::MapAccess<'de> for SpanMapAccess {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: de::DeserializeSeed<'de>,
{
let key = match self.state {
0 => "offset",
1 => "len",
2 => "byte_info",
_ => return Ok(None),
};
self.state += 1;
seed.deserialize(key.into_deserializer()).map(Some)
}
fn next_value_seed<Vv>(&mut self, seed: Vv) -> Result<Vv::Value, Error>
where
Vv: de::DeserializeSeed<'de>,
{
match self.state {
1 => {
let v = span_index_to_u64(self.span.raw_offset());
seed.deserialize(v.into_deserializer())
}
2 => {
let v = span_index_to_u64(self.span.raw_len());
seed.deserialize(v.into_deserializer())
}
3 => seed.deserialize(ByteInfoTupleDeser(self.span.raw_byte_info())),
_ => Err(Error::msg("invalid Span internal state")),
}
}
}