Skip to main content

age_setup/
errors.rs

1use thiserror::Error;
2
3/// Top-level error type for the `age-authenticator` library.
4///
5/// All fallible operations return this error type, which categorizes failures
6/// into two groups:
7///
8/// * [`Generation`](Error::Generation) – Errors during key pair generation.
9/// * [`Validation`](Error::Validation) – Errors during key format validation.
10///
11/// # Conversions
12///
13/// Both [`GenerationError`] and [`ValidationError`] automatically convert into
14/// `Error` via their respective [`From`] implementations, allowing the `?`
15/// operator to be used seamlessly.
16///
17/// # Examples
18///
19/// ```rust
20/// use age_setup::Error;
21///
22/// let err = Error::Generation(
23///     age_setup::GenerationError::IdentityCreationFailed,
24/// );
25/// assert!(matches!(err, Error::Generation(_)));
26/// ```
27#[derive(Debug, Error)]
28pub enum Error {
29    /// A key generation operation failed.
30    #[error("Key generation failed: {0}")]
31    Generation(#[from] GenerationError),
32
33    /// A validation check failed.
34    #[error("Validation failed: {0}")]
35    Validation(#[from] ValidationError),
36}
37
38/// Convenience type alias for `Result<T, Error>`.
39///
40/// # Examples
41///
42/// ```rust
43/// use age_setup::Result;
44///
45/// fn fallible() -> Result<()> {
46///     Ok(())
47/// }
48/// assert!(fallible().is_ok());
49/// ```
50pub type Result<T> = std::result::Result<T, Error>;
51
52/// Errors that occur during key pair generation.
53///
54/// # Variants
55///
56/// * [`IdentityCreationFailed`](GenerationError::IdentityCreationFailed) –
57///   The underlying age identity could not be generated.
58#[derive(Debug, Error)]
59pub enum GenerationError {
60    /// The age X25519 identity generation failed.
61    #[error("Identity generation failed")]
62    IdentityCreationFailed,
63}
64
65/// Errors that occur during key format validation.
66///
67/// # Variants
68///
69/// * [`InvalidPublicKeyFormat`](ValidationError::InvalidPublicKeyFormat) –
70///   A public key did not meet the required format.
71/// * [`InvalidSecretKeyFormat`](ValidationError::InvalidSecretKeyFormat) –
72///   A secret key did not meet the required format.
73#[derive(Debug, Error)]
74pub enum ValidationError {
75    /// The public key format is invalid.
76    #[error("Invalid public key format: {reason}")]
77    InvalidPublicKeyFormat {
78        /// Human-readable reason for the validation failure.
79        reason: String,
80    },
81
82    /// The secret key format is invalid.
83    #[error("Invalid secret key format: {reason}")]
84    InvalidSecretKeyFormat {
85        /// Human-readable reason for the validation failure.
86        reason: String,
87    },
88}
89
90impl ValidationError {
91    /// Creates a public key validation error with the given reason.
92    ///
93    /// This is a crate-internal convenience constructor.
94    pub(crate) fn invalid_public_key(reason: impl Into<String>) -> Self {
95        Self::InvalidPublicKeyFormat {
96            reason: reason.into(),
97        }
98    }
99
100    /// Creates a secret key validation error with the given reason.
101    ///
102    /// This is a crate-internal convenience constructor.
103    pub(crate) fn invalid_secret_key(reason: impl Into<String>) -> Self {
104        Self::InvalidSecretKeyFormat {
105            reason: reason.into(),
106        }
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn generation_error_conversion() {
116        let gen_err = GenerationError::IdentityCreationFailed;
117        let err: Error = gen_err.into();
118        assert!(matches!(err, Error::Generation(_)));
119    }
120
121    #[test]
122    fn validation_error_conversion() {
123        let val_err = ValidationError::invalid_public_key("test");
124        let err: Error = val_err.into();
125        assert!(matches!(err, Error::Validation(_)));
126    }
127
128    #[test]
129    fn generation_error_display() {
130        let e = GenerationError::IdentityCreationFailed;
131        assert_eq!(format!("{}", e), "Identity generation failed");
132    }
133
134    #[test]
135    fn validation_error_display_public() {
136        let e = ValidationError::invalid_public_key("too short");
137        assert_eq!(format!("{}", e), "Invalid public key format: too short");
138    }
139
140    #[test]
141    fn validation_error_display_secret() {
142        let e = ValidationError::invalid_secret_key("empty");
143        assert_eq!(format!("{}", e), "Invalid secret key format: empty");
144    }
145
146    #[test]
147    fn result_type_alias() {
148        fn returns_ok() -> Result<()> {
149            Ok(())
150        }
151        fn returns_err() -> Result<()> {
152            Err(Error::Generation(GenerationError::IdentityCreationFailed))
153        }
154        assert!(returns_ok().is_ok());
155        assert!(returns_err().is_err());
156    }
157}