Skip to main content

acorn/
error.rs

1//! Error contracts for portable domain code and host integrations.
2//! Use [`AcornError`] for small, owned domain failures that must compile without host services, and [`AcornResult`] as its result shorthand.
3//! Under `std`, use `ApiResult` at I/O, API, and application boundaries that need a `color_eyre::eyre::Report` with rich diagnostic context.
4use crate::prelude::String;
5use core::fmt;
6
7/// Result returned by portable ACORN domain operations
8pub type AcornResult<T> = core::result::Result<T, AcornError>;
9/// Result returned by host operations with rich diagnostic context
10#[cfg(feature = "std")]
11pub type ApiResult<T> = core::result::Result<T, color_eyre::eyre::Report>;
12/// Error returned by portable ACORN domain operations
13#[derive(Clone, Debug, Eq, PartialEq)]
14pub struct AcornError {
15    message: String,
16}
17impl AcornError {
18    /// Create an error with a user-facing message
19    pub fn new(message: impl Into<String>) -> Self {
20        Self { message: message.into() }
21    }
22    /// Return the error message
23    pub fn message(&self) -> &str {
24        &self.message
25    }
26}
27impl fmt::Display for AcornError {
28    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
29        formatter.write_str(&self.message)
30    }
31}
32impl core::error::Error for AcornError {}
33impl From<&str> for AcornError {
34    fn from(message: &str) -> Self {
35        Self::new(message)
36    }
37}
38impl From<String> for AcornError {
39    fn from(message: String) -> Self {
40        Self::new(message)
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    #[test]
48    fn error_preserves_message() {
49        let error = AcornError::new("portable failure");
50        assert_eq!(error.message(), "portable failure");
51        assert_eq!(error.to_string(), "portable failure");
52    }
53}