use std::{error::Error, fmt}; #[derive(Debug)] pub enum ErrorCode { // General Undefined(String), // Cache IDNotFound(String), } impl fmt::Display for ErrorCode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { ErrorCode::Undefined(msg) => write!(f, "{}", msg), ErrorCode::IDNotFound(id) => write!(f, "ID '{}' not found", id), } } } mod errorcodes { use super::*; const ITEMS: [&str; 2] = ["one", "two"]; #[test] fn undefined_display() { for item in ITEMS { let err = ErrorCode::Undefined(item.to_string()); assert_eq!(err.to_string(), item); } } #[test] fn cache_missing() { for item in ITEMS { let err = ErrorCode::IDNotFound(item.to_string()); assert_eq!(err.to_string(), format!("ID '{}' not found", item)); } } } #[derive(Debug)] pub struct MTTError { pub code: ErrorCode, } impl MTTError { pub fn new(msg: S) -> Self where S: Into, { let text = msg.into(); Self { code: ErrorCode::Undefined(text), } } pub fn from_code(code: ErrorCode) -> Self { Self { code: code } } } impl Error for MTTError {} impl fmt::Display for MTTError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.code) } } #[cfg(test)] mod errors { use super::*; #[test] fn create_with_str() { let msgs = ["one", "two"]; for msg in msgs { let err = MTTError::new(msg); assert_eq!(err.to_string(), msg); } } #[test] fn create_with_string() { let msg = "three"; let err = MTTError::new(msg.to_string()); assert_eq!(err.to_string(), msg); } #[test] fn create_from_code() { let code = ErrorCode::Undefined("oops".to_string()); let err = MTTError::from_code(code); match err.code { ErrorCode::Undefined(_) => (), _ => assert!(false, "{:?} is not undefined", err.code), } } #[test] fn create_missing_id_from_code() { let code = ErrorCode::IDNotFound("123".to_string()); let err = MTTError::from_code(code); match err.code { ErrorCode::IDNotFound(_) => (), _ => assert!(false, "{:?} is not undefined", err.code), } } }