Skip to main content

ito_domain/
errors.rs

1//! Domain-layer error types.
2
3use std::io;
4
5use thiserror::Error;
6
7/// Result alias for domain-layer operations.
8pub type DomainResult<T> = Result<T, DomainError>;
9
10/// Error type used by domain ports and domain utilities.
11#[derive(Debug, Error)]
12pub enum DomainError {
13    /// Filesystem or other IO failure.
14    #[error("I/O failure while {context}: {source}")]
15    Io {
16        /// Short operation context.
17        context: &'static str,
18        /// Source error.
19        #[source]
20        source: io::Error,
21    },
22
23    /// Requested entity was not found.
24    #[error("{entity} not found: {id}")]
25    NotFound {
26        /// Entity kind.
27        entity: &'static str,
28        /// Requested identifier.
29        id: String,
30    },
31
32    /// Target was ambiguous and matched multiple entities.
33    #[error("Ambiguous {entity} target '{input}'. Matches: {matches}")]
34    AmbiguousTarget {
35        /// Entity kind.
36        entity: &'static str,
37        /// User-provided target.
38        input: String,
39        /// Comma-separated matching candidates.
40        matches: String,
41    },
42}
43
44impl DomainError {
45    /// Build an IO-flavored domain error with a static context string.
46    pub fn io(context: &'static str, source: io::Error) -> Self {
47        Self::Io { context, source }
48    }
49
50    /// Build a not-found error for an entity.
51    pub fn not_found(entity: &'static str, id: impl Into<String>) -> Self {
52        Self::NotFound {
53            entity,
54            id: id.into(),
55        }
56    }
57
58    /// Build an ambiguity error for an entity target.
59    pub fn ambiguous_target(entity: &'static str, input: &str, matches: &[String]) -> Self {
60        Self::AmbiguousTarget {
61            entity,
62            input: input.to_string(),
63            matches: matches.join(", "),
64        }
65    }
66}