#[cfg(doc)]
use crate::options::EipsOptions;
use core::fmt::{self, Debug, Display};
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub enum ChangeError<Id> {
BadParentId(
Id,
),
BadDirection(
Id,
),
MergeConflict(
Id,
),
DuplicateId(
Id,
),
UnsupportedMove(
Id,
),
BadOldLocation(
Id,
),
UnexpectedMove(
Id,
),
OldLocationIsMove(
Id,
),
HiddenMove(
Id,
),
BadMoveTimestamp {
id: Id,
timestamp: crate::MoveTimestamp,
},
#[deprecated(
since = "0.2.2",
note = "replaced by `BadMoveTimestamp`, which is more general"
)]
TimestampOverflow {
id: Id,
timestamp: crate::MoveTimestamp,
},
}
impl<Id> ChangeError<Id> {
pub(crate) fn as_basic(&self) -> Basic<&Self> {
Basic(self)
}
fn fmt_basic(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BadParentId(_) => write!(f, "bad parent id"),
Self::BadDirection(_) => {
write!(f, "change has no parent but its direction is 'before'")
}
Self::MergeConflict(_) => {
write!(f, "conflict between change and existing data")
}
Self::DuplicateId(_) => {
write!(f, "id is already in use with a different parent")
}
Self::UnsupportedMove(_) => {
write!(f, "change has move info but moves are unsupported")
}
Self::BadOldLocation(_) => write!(f, "bad old location"),
Self::UnexpectedMove(_) => {
write!(f, "change has no move info but is a move destination")
}
Self::OldLocationIsMove(_) => {
write!(f, "old location is a move destination")
}
Self::HiddenMove(_) => {
write!(f, "change is a move destination but is hidden")
}
#[allow(deprecated)]
Self::BadMoveTimestamp {
timestamp,
..
}
| Self::TimestampOverflow {
timestamp,
..
} => {
write!(f, "invalid move timestamp: {timestamp}")
}
}
}
}
impl<Id: Display> Display for ChangeError<Id> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let basic = Basic(self);
match self {
Self::BadParentId(id) => write!(f, "{basic}: {id}"),
Self::BadDirection(id) => write!(f, "{basic} (id {id})"),
Self::MergeConflict(id) => write!(f, "{basic} (id {id})"),
Self::DuplicateId(id) => write!(f, "{basic}: {id}"),
Self::UnsupportedMove(id) => write!(f, "{basic} (id {id})"),
Self::BadOldLocation(id) => write!(f, "{basic}: {id}"),
Self::UnexpectedMove(id) => write!(f, "{basic} (id {id})"),
Self::OldLocationIsMove(id) => write!(f, "{basic}: {id}"),
Self::HiddenMove(id) => write!(f, "{basic} (id {id})"),
#[allow(deprecated)]
Self::BadMoveTimestamp {
id,
..
}
| Self::TimestampOverflow {
id,
..
} => {
write!(f, "{basic} (id {id})")
}
}
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "std")))]
impl<Id: Debug + Display> std::error::Error for ChangeError<Id> {}
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub struct IndexError {
pub index: usize,
}
impl Display for IndexError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "bad index: {}", self.index)
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "std")))]
impl std::error::Error for IndexError {}
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub struct IdError<Id> {
pub id: Id,
}
impl<Id: Display> Display for IdError<Id> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "bad id: {}", self.id)
}
}
#[cfg(feature = "std")]
#[cfg_attr(feature = "doc_cfg", doc(cfg(feature = "std")))]
impl<Id: Debug + Display> std::error::Error for IdError<Id> {}
pub(crate) struct Basic<T>(T);
impl<Id> Display for Basic<&ChangeError<Id>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt_basic(f)
}
}
impl<Id> Debug for Basic<&ChangeError<Id>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ChangeError(\"{self}\")")
}
}