#
pacman_key/
types.rs

    1use chrono::NaiveDate;
    2
    3/// A GPG key from the pacman keyring.
    4#[derive(Debug, Clone, PartialEq, Eq)]
    5pub struct Key {
    6    pub fingerprint: String,
    7    pub uid: String,
    8    pub created: Option<NaiveDate>,
    9    pub expires: Option<NaiveDate>,
    10    pub validity: KeyValidity,
    11    pub key_type: KeyType,
    12}
    13
    14/// The cryptographic algorithm and key size.
    15#[derive(Debug, Clone, PartialEq, Eq)]
    16pub struct KeyType {
    17    pub algorithm: String,
    18    pub bits: u32,
    19}
    20
    21impl std::fmt::Display for KeyType {
    22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    23        write!(f, "{}{}", self.algorithm.to_lowercase(), self.bits)
    24    }
    25}
    26
    27/// GPG key validity level.
    28///
    29/// Represents how confident GPG is that the key belongs to the claimed identity.
    30/// This is derived from signature verification and the web of trust, not to be
    31/// confused with owner trust (how much we trust the key owner to sign other keys).
    32///
    33/// Values correspond to GPG's validity field in `--with-colons` output.
    34#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
    35#[non_exhaustive]
    36pub enum KeyValidity {
    37    /// Validity unknown (new key or insufficient data)
    38    #[default]
    39    Unknown,
    40    /// Validity undefined (not yet computed)
    41    Undefined,
    42    /// Key is explicitly distrusted
    43    Never,
    44    /// Marginally valid (some trust path exists)
    45    Marginal,
    46    /// Fully valid (strong trust path)
    47    Full,
    48    /// Ultimately valid (user's own key or explicitly trusted)
    49    Ultimate,
    50    /// Key has expired
    51    Expired,
    52    /// Key has been revoked
    53    Revoked,
    54}
    55
    56impl KeyValidity {
    57    pub fn from_gpg_char(c: char) -> Self {
    58        match c {
    59            'o' => Self::Unknown,
    60            'q' => Self::Undefined,
    61            'n' => Self::Never,
    62            'm' => Self::Marginal,
    63            'f' => Self::Full,
    64            'u' => Self::Ultimate,
    65            'e' => Self::Expired,
    66            'r' => Self::Revoked,
    67            _ => Self::Unknown,
    68        }
    69    }
    70}
    71
    72/// A signature on a key.
    73#[derive(Debug, Clone, PartialEq, Eq)]
    74pub struct Signature {
    75    pub keyid: String,
    76    pub uid: String,
    77    pub created: Option<NaiveDate>,
    78    pub expires: Option<NaiveDate>,
    79    pub sig_class: String,
    80}
    81
    82/// Progress updates during key refresh operations.
    83#[derive(Debug, Clone, PartialEq, Eq)]
    84#[non_exhaustive]
    85pub enum RefreshProgress {
    86    Starting {
    87        total_keys: usize,
    88    },
    89    Refreshing {
    90        current: usize,
    91        total: usize,
    92        keyid: String,
    93    },
    94    Completed,
    95    Error {
    96        keyid: String,
    97        message: String,
    98    },
    99}
    100
    101/// Options for the key refresh operation.
    102#[derive(Debug, Clone, Default)]
    103pub struct RefreshOptions {
    104    /// Timeout for the entire refresh operation, in seconds.
    105    /// If None, no timeout is applied.
    106    pub timeout_secs: Option<u64>,
    107}
    108
    109
    110#[cfg(test)]
    111mod tests {
    112    use super::*;
    113
    114    #[test]
    115    fn test_key_validity_from_gpg_char() {
    116        assert_eq!(KeyValidity::from_gpg_char('o'), KeyValidity::Unknown);
    117        assert_eq!(KeyValidity::from_gpg_char('q'), KeyValidity::Undefined);
    118        assert_eq!(KeyValidity::from_gpg_char('n'), KeyValidity::Never);
    119        assert_eq!(KeyValidity::from_gpg_char('m'), KeyValidity::Marginal);
    120        assert_eq!(KeyValidity::from_gpg_char('f'), KeyValidity::Full);
    121        assert_eq!(KeyValidity::from_gpg_char('u'), KeyValidity::Ultimate);
    122        assert_eq!(KeyValidity::from_gpg_char('e'), KeyValidity::Expired);
    123        assert_eq!(KeyValidity::from_gpg_char('r'), KeyValidity::Revoked);
    124        assert_eq!(KeyValidity::from_gpg_char('x'), KeyValidity::Unknown);
    125        assert_eq!(KeyValidity::from_gpg_char('-'), KeyValidity::Unknown);
    126    }
    127}