rkik_nts/
error.rs

1//! Error types for the NTS client library.
2
3use std::io;
4use thiserror::Error;
5
6/// Result type for NTS operations.
7pub type Result<T> = std::result::Result<T, Error>;
8
9/// Errors that can occur during NTS client operations.
10#[derive(Error, Debug)]
11pub enum Error {
12    /// Network I/O error.
13    #[error("I/O error: {0}")]
14    Io(#[from] io::Error),
15
16    /// TLS/connection error during NTS key exchange.
17    #[error("TLS error: {0}")]
18    Tls(String),
19
20    /// NTS key exchange failed.
21    #[error("NTS key exchange failed: {0}")]
22    KeyExchange(String),
23
24    /// NTP protocol error.
25    #[error("NTP protocol error: {0}")]
26    Protocol(String),
27
28    /// Invalid server response.
29    #[error("Invalid server response: {0}")]
30    InvalidResponse(String),
31
32    /// Timeout occurred during operation.
33    #[error("Operation timed out")]
34    Timeout,
35
36    /// Invalid configuration.
37    #[error("Invalid configuration: {0}")]
38    InvalidConfig(String),
39
40    /// Server not available or unreachable.
41    #[error("Server unreachable: {0}")]
42    ServerUnavailable(String),
43
44    /// Authentication failed.
45    #[error("Authentication failed: {0}")]
46    AuthenticationFailed(String),
47
48    /// Missing NTS cookie.
49    #[error("Missing NTS cookie")]
50    MissingNtsCookie,
51
52    /// Missing NTS authenticator.
53    #[error("Missing NTS authenticator")]
54    MissingAuthenticator,
55
56    /// AEAD verification failed.
57    #[error("AEAD verification failed: {0}")]
58    AeadVerificationFailed(String),
59
60    /// Malformed NTS extension fields.
61    #[error("Malformed NTS extension fields: {0}")]
62    MalformedNtsExtension(String),
63
64    /// No cookies returned when requested.
65    #[error("No NTS cookies returned by server")]
66    NoCookiesReturned,
67
68    /// Generic error.
69    #[error("{0}")]
70    Other(String),
71}
72
73impl From<rustls::Error> for Error {
74    fn from(err: rustls::Error) -> Self {
75        Error::Tls(err.to_string())
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn test_error_display() {
85        let err = Error::Timeout;
86        assert_eq!(err.to_string(), "Operation timed out");
87
88        let err = Error::InvalidConfig("test error".to_string());
89        assert_eq!(err.to_string(), "Invalid configuration: test error");
90
91        let err = Error::ServerUnavailable("server down".to_string());
92        assert_eq!(err.to_string(), "Server unreachable: server down");
93
94        let err = Error::MissingNtsCookie;
95        assert_eq!(err.to_string(), "Missing NTS cookie");
96
97        let err = Error::MissingAuthenticator;
98        assert_eq!(err.to_string(), "Missing NTS authenticator");
99
100        let err = Error::AeadVerificationFailed("bad tag".to_string());
101        assert_eq!(err.to_string(), "AEAD verification failed: bad tag");
102
103        let err = Error::MalformedNtsExtension("bad field".to_string());
104        assert_eq!(err.to_string(), "Malformed NTS extension fields: bad field");
105
106        let err = Error::NoCookiesReturned;
107        assert_eq!(err.to_string(), "No NTS cookies returned by server");
108    }
109
110    #[test]
111    fn test_io_error_conversion() {
112        let io_err = io::Error::new(io::ErrorKind::ConnectionRefused, "refused");
113        let err: Error = io_err.into();
114        assert!(matches!(err, Error::Io(_)));
115    }
116
117    #[test]
118    fn test_error_is_send_sync() {
119        fn assert_send_sync<T: Send + Sync>() {}
120        assert_send_sync::<Error>();
121    }
122}