use core::{fmt, str::FromStr};
use password_hash::Error;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
pub enum Algorithm {
Sha256Crypt,
Sha512Crypt,
}
impl Default for Algorithm {
fn default() -> Self {
Self::RECOMMENDED
}
}
impl Algorithm {
pub const SHA256_CRYPT_IDENT: &str = "5";
pub const SHA512_CRYPT_IDENT: &str = "6";
const RECOMMENDED: Self = Self::Sha512Crypt;
pub fn new(id: impl AsRef<str>) -> password_hash::Result<Self> {
id.as_ref().parse()
}
#[must_use]
pub const fn to_str(self) -> &'static str {
match self {
Algorithm::Sha256Crypt => Self::SHA256_CRYPT_IDENT,
Algorithm::Sha512Crypt => Self::SHA512_CRYPT_IDENT,
}
}
}
impl AsRef<str> for Algorithm {
fn as_ref(&self) -> &str {
self.to_str()
}
}
impl fmt::Display for Algorithm {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.to_str())
}
}
impl FromStr for Algorithm {
type Err = Error;
fn from_str(s: &str) -> password_hash::Result<Algorithm> {
s.try_into()
}
}
impl<'a> TryFrom<&'a str> for Algorithm {
type Error = Error;
fn try_from(name: &'a str) -> password_hash::Result<Algorithm> {
match name {
Self::SHA256_CRYPT_IDENT => Ok(Algorithm::Sha256Crypt),
Self::SHA512_CRYPT_IDENT => Ok(Algorithm::Sha512Crypt),
_ => Err(Error::Algorithm),
}
}
}