use crate::DeserializeErrors;
use crate::util::deserialize_sequence;
use crate::{Key, Value};
use std::rc::Rc;
use std::sync::Arc;
use std::collections::{BTreeSet, BinaryHeap, HashSet, LinkedList, VecDeque};
use std::borrow::Cow;
use crate::{DeserializeValue, Error};
use miette::{Diagnostic, SourceSpan};
use nonempty::NonEmpty;
use thiserror::Error;
macro_rules! impl_DeserializeTomlValue_for {
(
$collection:ty where $($tt:tt)*
) => {
impl<'de, $($tt)*> $crate::DeserializeValue<'de>
for $collection
{
type Error = DeserializeSequenceError<T::Error>;
fn deserialize_value<'k>(
_key: Key<'k>,
value: Value<'de>,
) -> Result<Self, DeserializeErrors<Self, NonEmpty<Self::Error>>> {
match deserialize_sequence(
value,
T::deserialize_value,
|value| {
DeserializeSequenceError::<T::Error>::details(
crate::util::value_type_description(value),
)
}
) {
Ok(t) => {
Ok(t.into_iter().collect())
}
Err((a, b)) => {
Err(DeserializeErrors::new(a.map(|it| it.into_iter().collect()), b))
}
}
}
}
};
}
#[derive(Diagnostic, Error, Debug, Clone, Eq, PartialEq, Hash)]
#[error("Type mismatch")]
pub enum DeserializeSequenceError<E: Error> {
NotList {
details: String,
#[label("{details}")]
span: SourceSpan,
},
InvalidSequence {
details: String,
#[label("{details}")]
span: SourceSpan,
#[related]
errors: NonEmpty<E>,
},
}
impl<E: Error> Error for DeserializeSequenceError<E> {
fn expected_type() -> Cow<'static, str> {
format!("list of {}", E::expected_type()).into()
}
}
impl_DeserializeTomlValue_for!( HashSet<T, S>
where
T: DeserializeValue<'de> + Eq + std::hash::Hash,
S: std::hash::BuildHasher + Default,
);
impl_DeserializeTomlValue_for!( Vec<T>
where
T: DeserializeValue<'de>
);
impl_DeserializeTomlValue_for!( BTreeSet<T>
where
T: DeserializeValue<'de> + Ord
);
impl_DeserializeTomlValue_for!( BinaryHeap<T>
where
T: DeserializeValue<'de> + Ord
);
impl_DeserializeTomlValue_for!( LinkedList<T>
where
T: DeserializeValue<'de>
);
impl_DeserializeTomlValue_for!( VecDeque<T>
where
T: DeserializeValue<'de>
);
impl_DeserializeTomlValue_for!( Rc<[T]>
where
T: DeserializeValue<'de>
);
impl_DeserializeTomlValue_for!( Cow<'a, [T]>
where
'a, T: DeserializeValue<'de> + Clone
);
impl_DeserializeTomlValue_for!( Box<[T]>
where
T: DeserializeValue<'de>
);
impl_DeserializeTomlValue_for!( Arc<[T]>
where
T: DeserializeValue<'de>
);