use crate::{DeserializeErrors, DeserializeTable};
use miette::{Diagnostic, SourceSpan};
use nonempty::NonEmpty;
use thiserror::Error;
use toml::de::DeTable;
use crate::{DeserializeValue, Error, util::value_type_description};
#[doc = concat!("Failed to deserialize [`toml_edit::Table`]")]
#[derive(Diagnostic, Error, Debug, Clone, Eq, PartialEq, Hash)]
#[error("Type mismatch")]
pub struct DeserializeTomlTableError {
pub details: String,
#[label("{details}")]
pub span: SourceSpan,
}
impl Error for DeserializeTomlTableError {
fn expected_type() -> std::borrow::Cow<'static, str> {
"table".into()
}
}
impl<'de> DeserializeTable<'de> for DeTable<'de> {
type Error = DeserializeTomlTableError;
fn deserialize_table(
table: toml::Spanned<DeTable<'de>>,
) -> Result<Self, DeserializeErrors<Self, NonEmpty<Self::Error>>> {
Ok(table.into_inner())
}
}
#[derive(Diagnostic, Error, Debug, Clone, Eq, PartialEq, Hash)]
#[error("Type mismatch")]
pub struct DeserializeDatetimeError {
pub details: String,
#[label("{details}")]
pub span: SourceSpan,
}
impl Error for DeserializeDatetimeError {
fn expected_type() -> std::borrow::Cow<'static, str> {
"datetime".into()
}
}
impl DeserializeValue<'_> for toml_datetime::Datetime {
type Error = DeserializeDatetimeError;
fn deserialize_value(
_key: crate::Key,
value: crate::Value,
) -> Result<Self, DeserializeErrors<Self, NonEmpty<Self::Error>>> {
let span = value.span();
let description = value_type_description(&value);
if let toml::de::DeValue::Datetime(datetime) = value.into_inner() {
Ok(datetime)
} else {
Err(DeserializeErrors::err(DeserializeDatetimeError {
details: DeserializeDatetimeError::details(description),
span: span.into(),
}))
}
}
}
#[derive(Diagnostic, Error, Debug, Clone, Eq, PartialEq, Hash)]
#[error("Type mismatch")]
pub struct DeserializeTomlArrayError {
pub details: String,
#[label("{details}")]
pub span: SourceSpan,
}
impl Error for DeserializeTomlArrayError {
fn expected_type() -> std::borrow::Cow<'static, str> {
"list".into()
}
}
impl<'v> DeserializeValue<'v> for toml::de::DeArray<'v> {
type Error = DeserializeTomlArrayError;
fn deserialize_value<'k>(
_key: crate::Key<'k>,
value: crate::Value<'v>,
) -> Result<Self, DeserializeErrors<Self, NonEmpty<Self::Error>>> {
let span = value.span();
let description = value_type_description(&value);
if let toml::de::DeValue::Array(array) = value.into_inner() {
Ok(array)
} else {
Err(DeserializeErrors::err(DeserializeTomlArrayError {
details: DeserializeTomlArrayError::details(description),
span: span.into(),
}))
}
}
}