use crate::{Error, Result};
use core::{
fmt::{self, Display},
str::FromStr,
};
#[cfg(feature = "password-hash")]
use password_hash::Ident;
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub enum Algorithm {
Balloon,
BalloonM,
}
impl Default for Algorithm {
fn default() -> Algorithm {
Algorithm::BalloonM
}
}
impl Algorithm {
#[cfg(feature = "password-hash")]
#[cfg_attr(docsrs, doc(cfg(feature = "password-hash")))]
pub const BALLOON_IDENT: Ident<'static> = Ident::new_unwrap("balloon");
#[cfg(feature = "password-hash")]
#[cfg_attr(docsrs, doc(cfg(feature = "password-hash")))]
pub const BALLOON_M_IDENT: Ident<'static> = Ident::new_unwrap("balloon-m");
pub fn new(id: impl AsRef<str>) -> Result<Self> {
id.as_ref().parse()
}
pub fn as_str(&self) -> &str {
match self {
Algorithm::Balloon => "balloon",
Algorithm::BalloonM => "balloon-m",
}
}
#[cfg(feature = "password-hash")]
#[cfg_attr(docsrs, doc(cfg(feature = "password-hash")))]
pub fn ident(&self) -> Ident<'static> {
match self {
Algorithm::Balloon => Self::BALLOON_IDENT,
Algorithm::BalloonM => Self::BALLOON_M_IDENT,
}
}
}
impl AsRef<str> for Algorithm {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Display for Algorithm {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for Algorithm {
type Err = Error;
fn from_str(s: &str) -> Result<Algorithm> {
match s {
"balloon" => Ok(Algorithm::Balloon),
"balloon-m" => Ok(Algorithm::BalloonM),
_ => Err(Error::AlgorithmInvalid),
}
}
}
#[cfg(feature = "password-hash")]
#[cfg_attr(docsrs, doc(cfg(feature = "password-hash")))]
impl From<Algorithm> for Ident<'static> {
fn from(alg: Algorithm) -> Ident<'static> {
alg.ident()
}
}
#[cfg(feature = "password-hash")]
#[cfg_attr(docsrs, doc(cfg(feature = "password-hash")))]
impl<'a> TryFrom<Ident<'a>> for Algorithm {
type Error = password_hash::Error;
fn try_from(ident: Ident<'a>) -> password_hash::Result<Algorithm> {
match ident {
Self::BALLOON_IDENT => Ok(Algorithm::Balloon),
Self::BALLOON_M_IDENT => Ok(Algorithm::BalloonM),
_ => Err(password_hash::Error::Algorithm),
}
}
}