use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct InvariantError(String);
impl InvariantError {
#[inline]
pub fn new(msg: impl Into<String>) -> Self {
Self(msg.into())
}
#[inline]
pub fn message(&self) -> &str {
&self.0
}
}
impl fmt::Display for InvariantError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
impl std::error::Error for InvariantError {}
impl From<String> for InvariantError {
#[inline]
fn from(msg: String) -> Self {
Self(msg)
}
}
impl From<&str> for InvariantError {
#[inline]
fn from(msg: &str) -> Self {
Self(msg.to_owned())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ConfigError(String);
impl ConfigError {
#[inline]
pub fn new(msg: impl Into<String>) -> Self {
Self(msg.into())
}
#[inline]
pub fn message(&self) -> &str {
&self.0
}
}
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
impl std::error::Error for ConfigError {}
impl From<String> for ConfigError {
#[inline]
fn from(msg: String) -> Self {
Self(msg)
}
}
impl From<&str> for ConfigError {
#[inline]
fn from(msg: &str) -> Self {
Self(msg.to_owned())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn invariant_display_shows_message() {
let err = InvariantError::new("queue length mismatch");
assert_eq!(err.to_string(), "queue length mismatch");
}
#[test]
fn invariant_debug_includes_message() {
let err = InvariantError::new("bad pointer");
let dbg = format!("{:?}", err);
assert!(dbg.contains("bad pointer"));
}
#[test]
fn invariant_message_accessor() {
let err = InvariantError::new("test");
assert_eq!(err.message(), "test");
}
#[test]
fn invariant_clone_and_eq() {
let a = InvariantError::new("x");
let b = a.clone();
assert_eq!(a, b);
}
#[test]
fn invariant_implements_std_error() {
fn assert_error<T: std::error::Error>() {}
assert_error::<InvariantError>();
}
#[test]
fn invariant_is_send_and_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<InvariantError>();
}
#[test]
fn invariant_from_string() {
let err = InvariantError::from(String::from("from string"));
assert_eq!(err.message(), "from string");
}
#[test]
fn invariant_from_str() {
let err = InvariantError::from("from str");
assert_eq!(err.message(), "from str");
}
#[test]
fn config_display_shows_message() {
let err = ConfigError::new("capacity must be > 0");
assert_eq!(err.to_string(), "capacity must be > 0");
}
#[test]
fn config_debug_includes_message() {
let err = ConfigError::new("bad ratio");
let dbg = format!("{:?}", err);
assert!(dbg.contains("bad ratio"));
}
#[test]
fn config_message_accessor() {
let err = ConfigError::new("test");
assert_eq!(err.message(), "test");
}
#[test]
fn config_clone_and_eq() {
let a = ConfigError::new("x");
let b = a.clone();
assert_eq!(a, b);
}
#[test]
fn config_implements_std_error() {
fn assert_error<T: std::error::Error>() {}
assert_error::<ConfigError>();
}
#[test]
fn config_is_send_and_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<ConfigError>();
}
#[test]
fn config_from_string() {
let err = ConfigError::from(String::from("from string"));
assert_eq!(err.message(), "from string");
}
#[test]
fn config_from_str() {
let err = ConfigError::from("from str");
assert_eq!(err.message(), "from str");
}
}