1use core::{fmt, str::FromStr};
2use password_hash::Error;
3
4#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
6#[non_exhaustive]
7pub enum Algorithm {
8 Sha256Crypt,
10
11 Sha512Crypt,
13}
14
15impl Default for Algorithm {
16 fn default() -> Self {
18 Self::RECOMMENDED
19 }
20}
21
22impl Algorithm {
23 pub const SHA256_CRYPT_IDENT: &str = "5";
25
26 pub const SHA512_CRYPT_IDENT: &str = "6";
28
29 const RECOMMENDED: Self = Self::Sha512Crypt;
31
32 pub fn new(id: impl AsRef<str>) -> password_hash::Result<Self> {
34 id.as_ref().parse()
35 }
36
37 pub const fn ident(&self) -> &'static str {
39 match self {
40 Algorithm::Sha256Crypt => Self::SHA256_CRYPT_IDENT,
41 Algorithm::Sha512Crypt => Self::SHA512_CRYPT_IDENT,
42 }
43 }
44
45 pub fn as_str(&self) -> &'static str {
47 self.ident()
48 }
49}
50
51impl AsRef<str> for Algorithm {
52 fn as_ref(&self) -> &str {
53 self.as_str()
54 }
55}
56
57impl fmt::Display for Algorithm {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 f.write_str(self.as_str())
60 }
61}
62
63impl FromStr for Algorithm {
64 type Err = Error;
65
66 fn from_str(s: &str) -> password_hash::Result<Algorithm> {
67 s.try_into()
68 }
69}
70
71impl<'a> TryFrom<&'a str> for Algorithm {
72 type Error = Error;
73
74 fn try_from(name: &'a str) -> password_hash::Result<Algorithm> {
75 match name {
76 Self::SHA256_CRYPT_IDENT => Ok(Algorithm::Sha256Crypt),
77 Self::SHA512_CRYPT_IDENT => Ok(Algorithm::Sha512Crypt),
78 _ => Err(Error::Algorithm),
79 }
80 }
81}