Skip to main content

age_setup/types/
public_key.rs

1//! Public key type with validation and display.
2
3use crate::errors::Result;
4use crate::types::validation::validate_age_prefix;
5use std::fmt;
6
7/// An age public key, guaranteed to start with "age1".
8///
9/// Constructed via `PublicKey::new`, which validates the format.
10/// Can be displayed or converted to a string using `expose()`.
11#[derive(Debug, Clone)]
12pub struct PublicKey(String);
13
14impl PublicKey {
15    /// Creates a new public key after validating the prefix.
16    ///
17    /// # Errors
18    /// Returns `ValidationError` if the string is empty or doesn't start with "age1".
19    pub(crate) fn new(raw: String) -> Result<Self> {
20        validate_age_prefix(&raw)?;
21        Ok(Self(raw))
22    }
23
24    /// Returns the raw string representation of the public key.
25    ///
26    /// # Example
27    /// ```
28    /// # use age_setup::types::PublicKey;
29    /// # let pk = PublicKey::new("age1example".to_string()).unwrap();
30    /// assert_eq!(pk.expose(), "age1example");
31    /// ```
32    #[must_use]
33    pub fn expose(&self) -> &str {
34        &self.0
35    }
36}
37
38impl fmt::Display for PublicKey {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        write!(f, "{}", self.0)
41    }
42}
43
44impl AsRef<str> for PublicKey {
45    fn as_ref(&self) -> &str {
46        &self.0
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_public_key_new_valid() {
56        let pk = PublicKey::new("age1valid".to_string());
57        assert!(pk.is_ok());
58        assert_eq!(pk.unwrap().expose(), "age1valid");
59    }
60
61    #[test]
62    fn test_public_key_new_invalid() {
63        let pk = PublicKey::new("invalid".to_string());
64        assert!(pk.is_err());
65    }
66
67    #[test]
68    fn test_public_key_display() {
69        let pk = PublicKey::new("age1test".to_string()).unwrap();
70        assert_eq!(format!("{}", pk), "age1test");
71    }
72
73    #[test]
74    fn test_public_key_asref() {
75        let pk = PublicKey::new("age1asref".to_string()).unwrap();
76        let s: &str = pk.as_ref();
77        assert_eq!(s, "age1asref");
78    }
79
80    #[test]
81    fn test_public_key_clone() {
82        let pk1 = PublicKey::new("age1clone".to_string()).unwrap();
83        let pk2 = pk1.clone();
84        assert_eq!(pk1.expose(), pk2.expose());
85    }
86}