Skip to main content

khive_types/
error.rs

1//! Unified error types for khive-types.
2//!
3//! All parse/validation errors from closed taxonomies (EntityKind, NoteKind,
4//! EdgeRelation, SubstrateKind) and ID parsing converge here.
5
6extern crate alloc;
7use alloc::string::String;
8use core::fmt;
9
10/// A variant string was not recognized in a closed taxonomy.
11///
12/// Carries the rejected input, the domain name, and the list of valid values
13/// so callers get actionable error messages without re-matching.
14#[derive(Clone, Debug, PartialEq, Eq)]
15pub struct UnknownVariant {
16    /// Name of the closed taxonomy (e.g. `"entity_kind"`, `"edge_relation"`).
17    pub domain: &'static str,
18    /// The rejected input string.
19    pub value: String,
20    /// Exhaustive list of valid values for this taxonomy.
21    pub valid: &'static [&'static str],
22}
23
24impl UnknownVariant {
25    /// Construct an `UnknownVariant` error for the given `domain`, rejected `value`, and `valid` list.
26    pub fn new(
27        domain: &'static str,
28        value: impl Into<String>,
29        valid: &'static [&'static str],
30    ) -> Self {
31        Self {
32            domain,
33            value: value.into(),
34            valid,
35        }
36    }
37}
38
39impl fmt::Display for UnknownVariant {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        write!(
42            f,
43            "unknown {}: {:?}. Valid: {}",
44            self.domain,
45            self.value,
46            ValidList(self.valid),
47        )
48    }
49}
50
51#[cfg(feature = "std")]
52impl std::error::Error for UnknownVariant {}
53
54struct ValidList(&'static [&'static str]);
55
56impl fmt::Display for ValidList {
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        for (i, v) in self.0.iter().enumerate() {
59            if i > 0 {
60                f.write_str(" | ")?;
61            }
62            f.write_str(v)?;
63        }
64        Ok(())
65    }
66}
67
68/// Unified error for all type-level validation in khive-types.
69///
70/// Consolidates ID parse errors, namespace validation errors, and unknown
71/// closed-taxonomy variants under a single public error type (coding-standards
72/// §one-public-error-enum).
73#[derive(Clone, Debug, PartialEq, Eq)]
74pub enum TypeError {
75    /// A UUID string could not be parsed.
76    Id(crate::id::ParseIdError),
77    /// An unrecognized closed-taxonomy variant was received.
78    Variant(UnknownVariant),
79    /// A namespace string failed validation.
80    Namespace(crate::namespace::NamespaceError),
81}
82
83impl fmt::Display for TypeError {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        match self {
86            Self::Id(e) => write!(f, "id error: {e}"),
87            Self::Variant(e) => fmt::Display::fmt(e, f),
88            Self::Namespace(e) => write!(f, "namespace error: {e}"),
89        }
90    }
91}
92
93#[cfg(feature = "std")]
94impl std::error::Error for TypeError {
95    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
96        match self {
97            Self::Id(e) => Some(e),
98            Self::Variant(e) => Some(e),
99            Self::Namespace(e) => Some(e),
100        }
101    }
102}
103
104impl From<crate::id::ParseIdError> for TypeError {
105    fn from(e: crate::id::ParseIdError) -> Self {
106        Self::Id(e)
107    }
108}
109
110impl From<UnknownVariant> for TypeError {
111    fn from(e: UnknownVariant) -> Self {
112        Self::Variant(e)
113    }
114}
115
116impl From<crate::namespace::NamespaceError> for TypeError {
117    fn from(e: crate::namespace::NamespaceError) -> Self {
118        Self::Namespace(e)
119    }
120}