age_setup/validation.rs
1use crate::errors::{Error, Result, ValidationError};
2
3/// Validates that a string has the standard age public key prefix.
4///
5/// Checks that `key` is non-empty and starts with `"age1"`. This function
6/// is used internally by [`PublicKey::new`](crate::PublicKey::new).
7///
8/// # Errors
9///
10/// Returns [`Error::Validation`] with:
11///
12/// * [`ValidationError::InvalidPublicKeyFormat`](crate::ValidationError::InvalidPublicKeyFormat)
13/// if the key is empty.
14/// * [`ValidationError::InvalidPublicKeyFormat`](crate::ValidationError::InvalidPublicKeyFormat)
15/// if the key does not start with `"age1"`. The error message includes the
16/// first 10 characters of the offending input.
17///
18/// # Examples
19///
20/// ```rust
21/// use age_setup::validation::validate_age_prefix;
22///
23/// assert!(validate_age_prefix("age1abc").is_ok());
24/// assert!(validate_age_prefix("bad").is_err());
25/// assert!(validate_age_prefix("").is_err());
26/// ```
27pub fn validate_age_prefix(key: &str) -> Result<()> {
28 if key.is_empty() {
29 return Err(Error::from(ValidationError::invalid_public_key(
30 "Key is empty",
31 )));
32 }
33 if !key.starts_with("age1") {
34 return Err(Error::from(ValidationError::invalid_public_key(format!(
35 "Key must start with 'age1', got: {}",
36 &key[..key.len().min(10)]
37 ))));
38 }
39 Ok(())
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::errors::Error;
46
47 #[test]
48 fn empty() {
49 let e = validate_age_prefix("").unwrap_err();
50 assert!(matches!(e, Error::Validation(_)));
51 }
52
53 #[test]
54 fn wrong_prefix() {
55 let e = validate_age_prefix("xxx").unwrap_err();
56 let msg = format!("{}", e);
57 assert!(msg.contains("must start with 'age1'"));
58 }
59
60 #[test]
61 fn valid() {
62 assert!(validate_age_prefix("age1abc").is_ok());
63 }
64}