use qubit_datatype::DataType;
#[cfg(feature = "converter")]
use qubit_datatype::{
DataConversionError,
DataListConversionError,
};
use thiserror::Error;
use crate::ValueMissing;
#[non_exhaustive]
#[derive(Debug, Clone, Error, PartialEq, Eq)]
pub enum ValueError {
#[error("Missing value: {0}")]
Missing(
ValueMissing,
),
#[error("Type mismatch: expected {expected}, actual {actual}")]
TypeMismatch {
expected: DataType,
actual: DataType,
},
#[cfg(feature = "converter")]
#[error("Conversion error: {0}")]
Conversion(
#[source]
DataConversionError,
),
#[cfg(feature = "converter")]
#[error("List conversion error: {0}")]
ListConversion(
#[source]
DataListConversionError,
),
}
impl ValueError {
#[must_use]
#[inline(always)]
pub const fn is_missing(&self) -> bool {
matches!(self, Self::Missing(_))
}
#[must_use]
#[inline(always)]
pub const fn missing(&self) -> Option<&ValueMissing> {
match self {
Self::Missing(missing) => Some(missing),
Self::TypeMismatch { .. } => None,
#[cfg(feature = "converter")]
Self::Conversion(_) | Self::ListConversion(_) => None,
}
}
}
#[cfg(feature = "converter")]
impl From<DataConversionError> for ValueError {
fn from(error: DataConversionError) -> Self {
if error.is_missing()
&& let Some(from) = error.from_type()
{
return Self::Missing(ValueMissing::Conversion {
from,
to: error.to_type(),
});
}
if error.kind()
== qubit_datatype::DataConversionErrorKind::EmptyCollection
{
return Self::Missing(ValueMissing::EmptyCollectionConversion {
to: error.to_type(),
});
}
Self::Conversion(error)
}
}
#[cfg(feature = "converter")]
impl From<DataListConversionError> for ValueError {
fn from(error: DataListConversionError) -> Self {
let (source_index, source) = error.into_parts();
if source.is_missing()
&& let Some(from) = source.from_type()
{
return Self::Missing(ValueMissing::CollectionItem {
source_index,
from,
to: source.to_type(),
});
}
if source.kind()
== qubit_datatype::DataConversionErrorKind::EmptyCollection
{
return Self::Missing(ValueMissing::EmptyCollectionConversion {
to: source.to_type(),
});
}
Self::ListConversion(DataListConversionError::new(source_index, source))
}
}
pub type ValueResult<T> = Result<T, ValueError>;