use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum RelError {
UniqueViolation {
constraint: Option<String>,
},
ForeignKeyViolation {
constraint: Option<String>,
},
CheckViolation {
constraint: Option<String>,
},
Serialization,
Deadlock,
Unavailable(String),
Unsupported(String),
Backend(String),
}
impl fmt::Display for RelError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let c = |c: &Option<String>| c.as_deref().unwrap_or("?").to_string();
match self {
RelError::UniqueViolation { constraint } => {
write!(f, "unique violation ({})", c(constraint))
}
RelError::ForeignKeyViolation { constraint } => {
write!(f, "foreign key violation ({})", c(constraint))
}
RelError::CheckViolation { constraint } => {
write!(f, "check violation ({})", c(constraint))
}
RelError::Serialization => f.write_str("serialization failure"),
RelError::Deadlock => f.write_str("deadlock detected"),
RelError::Unavailable(m) => write!(f, "database unavailable: {m}"),
RelError::Unsupported(m) => write!(f, "database does not support: {m}"),
RelError::Backend(m) => write!(f, "database: {m}"),
}
}
}
impl std::error::Error for RelError {}