use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum CocoanutError {
#[error("Application not initialized")]
NotInitialized,
#[error("No root view specified")]
NoRootView,
#[error("Invalid view configuration: {0}")]
InvalidView(String),
#[error("AppKit error: {0}")]
AppKit(String),
#[error("String conversion error: {0}")]
StringConversion(#[from] std::ffi::NulError),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("Rendering error: {0}")]
Rendering(String),
#[error("Layout error: {0}")]
Layout(String),
#[error("Delegate error: {0}")]
Delegate(String),
#[error("Invalid view tag: {0}")]
InvalidTag(isize),
#[error("Window error: {0}")]
Window(String),
#[error("Event error: {0}")]
Event(String),
#[error("Resource not found: {0}")]
ResourceNotFound(String),
#[error("Thread error: {0}")]
Thread(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
}
pub type Result<T> = std::result::Result<T, CocoanutError>;
impl From<&str> for CocoanutError {
fn from(s: &str) -> Self {
CocoanutError::AppKit(s.to_string())
}
}
impl From<String> for CocoanutError {
fn from(s: String) -> Self {
CocoanutError::AppKit(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let e = CocoanutError::NotInitialized;
assert_eq!(e.to_string(), "Application not initialized");
}
#[test]
fn test_error_from_str() {
let e: CocoanutError = "test error".into();
assert_eq!(e.to_string(), "AppKit error: test error");
}
#[test]
fn test_error_from_string() {
let e: CocoanutError = String::from("test").into();
assert_eq!(e.to_string(), "AppKit error: test");
}
#[test]
fn all_variants_display() {
assert_eq!(
CocoanutError::InvalidView("bad".into()).to_string(),
"Invalid view configuration: bad"
);
assert_eq!(
CocoanutError::Rendering("r".into()).to_string(),
"Rendering error: r"
);
assert_eq!(
CocoanutError::NoRootView.to_string(),
"No root view specified"
);
}
#[test]
fn string_conversion_from_nul_error() {
let err = std::ffi::CString::new("a\0b").unwrap_err();
let e: CocoanutError = err.into();
assert!(e.to_string().contains("String conversion"));
}
#[test]
fn serialization_from_json_error() {
let err = serde_json::from_str::<serde_json::Value>("not json").unwrap_err();
let e: CocoanutError = err.into();
assert!(e.to_string().contains("Serialization"));
}
}