Skip to main content

systemprompt_identifiers/
error.rs

1//! Error types raised by identifier validation and database value conversion.
2//!
3//! The crate exposes two error enums:
4//!
5//! - `IdValidationError` — produced when a `try_new` constructor on a typed
6//!   identifier rejects its input (empty string, malformed shape, etc.).
7//! - `DbValueError` — produced when `FromDbValue` cannot convert a `DbValue`
8//!   variant into the requested target type (NULL where a value is required,
9//!   type mismatch, parse failure, numeric overflow).
10//!
11//! Both implement `std::error::Error` so callers can compose them into
12//! larger `thiserror`-derived enums via `#[from]`.
13
14use std::fmt;
15
16use thiserror::Error;
17
18#[derive(Debug, Clone)]
19pub enum IdValidationError {
20    Empty {
21        id_type: &'static str,
22    },
23    Invalid {
24        id_type: &'static str,
25        message: String,
26    },
27}
28
29impl fmt::Display for IdValidationError {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            Self::Empty { id_type } => write!(f, "{} cannot be empty", id_type),
33            Self::Invalid { id_type, message } => write!(f, "{}: {}", id_type, message),
34        }
35    }
36}
37
38impl std::error::Error for IdValidationError {}
39
40impl IdValidationError {
41    #[must_use]
42    pub const fn empty(id_type: &'static str) -> Self {
43        Self::Empty { id_type }
44    }
45
46    #[must_use]
47    pub fn invalid(id_type: &'static str, message: impl Into<String>) -> Self {
48        Self::Invalid {
49            id_type,
50            message: message.into(),
51        }
52    }
53}
54
55#[derive(Debug, Clone, Error)]
56pub enum DbValueError {
57    #[error("cannot convert NULL to {target}")]
58    Null { target: &'static str },
59    #[error("cannot convert {from} to {target}")]
60    Incompatible {
61        from: &'static str,
62        target: &'static str,
63    },
64    #[error("cannot parse {value:?} as {target}")]
65    Parse { value: String, target: &'static str },
66    #[error("value out of range for {target}")]
67    OutOfRange { target: &'static str },
68}
69
70impl DbValueError {
71    #[must_use]
72    pub const fn null_for(target: &'static str) -> Self {
73        Self::Null { target }
74    }
75
76    #[must_use]
77    pub const fn incompatible(from: &'static str, target: &'static str) -> Self {
78        Self::Incompatible { from, target }
79    }
80
81    #[must_use]
82    pub fn parse(value: impl Into<String>, target: &'static str) -> Self {
83        Self::Parse {
84            value: value.into(),
85            target,
86        }
87    }
88
89    #[must_use]
90    pub const fn out_of_range(target: &'static str) -> Self {
91        Self::OutOfRange { target }
92    }
93}