use core::fmt;
use super::Access;
use crate::{ReflectKind, VariantType};
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum AccessErrorKind {
MissingField(ReflectKind),
IncompatibleTypes {
expected: ReflectKind,
actual: ReflectKind,
},
IncompatibleEnumVariantTypes {
expected: VariantType,
actual: VariantType,
},
}
impl AccessErrorKind {
pub(super) fn with_access(self, access: Access, offset: Option<usize>) -> AccessError {
AccessError {
kind: self,
access,
offset,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AccessError<'a> {
pub(super) kind: AccessErrorKind,
pub(super) access: Access<'a>,
pub(super) offset: Option<usize>,
}
impl<'a> AccessError<'a> {
pub const fn kind(&self) -> &AccessErrorKind {
&self.kind
}
pub const fn access(&self) -> &Access<'_> {
&self.access
}
pub const fn offset(&self) -> Option<&usize> {
self.offset.as_ref()
}
}
impl fmt::Display for AccessError<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let AccessError {
kind,
access,
offset,
} = self;
write!(f, "Error accessing element with `{access}` access")?;
if let Some(offset) = offset {
write!(f, "(offset {offset})")?;
}
write!(f, ": ")?;
match kind {
AccessErrorKind::MissingField(type_accessed) => {
match access {
Access::Field(field) => write!(
f,
"The {type_accessed} accessed doesn't have {} `{}` field",
if let Some("a" | "e" | "i" | "o" | "u") = field.get(0..1) {
"an"
} else {
"a"
},
access.display_value()
),
Access::FieldIndex(_) => write!(
f,
"The {type_accessed} accessed doesn't have field index `{}`",
access.display_value(),
),
Access::TupleIndex(_) | Access::ListIndex(_) => write!(
f,
"The {type_accessed} accessed doesn't have index `{}`",
access.display_value()
)
}
}
AccessErrorKind::IncompatibleTypes { expected, actual } => write!(
f,
"Expected {} access to access a {expected}, found a {actual} instead.",
access.kind()
),
AccessErrorKind::IncompatibleEnumVariantTypes { expected, actual } => write!(
f,
"Expected variant {} access to access a {expected:?} variant, found a {actual:?} variant instead.",
access.kind()
),
}
}
}
impl core::error::Error for AccessError<'_> {}