Skip to main content

sha_crypt/
algorithm.rs

1use core::{fmt, str::FromStr};
2use password_hash::Error;
3
4/// SHA-crypt algorithm variants: SHA-256 or SHA-512.
5#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
6#[non_exhaustive]
7pub enum Algorithm {
8    /// SHA-256-crypt: SHA-crypt instantiated with SHA-256.
9    Sha256Crypt,
10
11    /// SHA-512-crypt: SHA-crypt instantiated with SHA-512.
12    Sha512Crypt,
13}
14
15impl Default for Algorithm {
16    /// Recommended default algorithm: SHA-512.
17    fn default() -> Self {
18        Self::RECOMMENDED
19    }
20}
21
22impl Algorithm {
23    /// SHA-256-crypt Modular Crypt Format algorithm identifier
24    pub const SHA256_CRYPT_IDENT: &str = "5";
25
26    /// SHA-512-crypt Modular Crypt Format algorithm identifier
27    pub const SHA512_CRYPT_IDENT: &str = "6";
28
29    /// Recommended default algorithm: SHA-512.
30    const RECOMMENDED: Self = Self::Sha512Crypt;
31
32    /// Parse an [`Algorithm`] from the provided string.
33    ///
34    /// # Errors
35    /// Returns [`Error::Algorithm`] if `id` is not `5` (SHA-256) or `6` (SHA-512).
36    pub fn new(id: impl AsRef<str>) -> password_hash::Result<Self> {
37        id.as_ref().parse()
38    }
39
40    /// Get the Modular Crypt Format algorithm identifier for this algorithm.
41    #[must_use]
42    pub const fn to_str(self) -> &'static str {
43        match self {
44            Algorithm::Sha256Crypt => Self::SHA256_CRYPT_IDENT,
45            Algorithm::Sha512Crypt => Self::SHA512_CRYPT_IDENT,
46        }
47    }
48}
49
50impl AsRef<str> for Algorithm {
51    fn as_ref(&self) -> &str {
52        self.to_str()
53    }
54}
55
56impl fmt::Display for Algorithm {
57    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58        f.write_str(self.to_str())
59    }
60}
61
62impl FromStr for Algorithm {
63    type Err = Error;
64
65    fn from_str(s: &str) -> password_hash::Result<Algorithm> {
66        s.try_into()
67    }
68}
69
70impl<'a> TryFrom<&'a str> for Algorithm {
71    type Error = Error;
72
73    fn try_from(name: &'a str) -> password_hash::Result<Algorithm> {
74        match name {
75            Self::SHA256_CRYPT_IDENT => Ok(Algorithm::Sha256Crypt),
76            Self::SHA512_CRYPT_IDENT => Ok(Algorithm::Sha512Crypt),
77            _ => Err(Error::Algorithm),
78        }
79    }
80}