let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
argon2.hash_password(password.as_bytes(), &salt).map(|h| h.to_string()).map_err(|e| e.into())
+}
+
+pub fn verify_password(password: &str, hashed_password: &str) -> Result<bool, Box<dyn std::error::Error>> {
+ let argon2 = Argon2::default();
+ let parsed_hash = PasswordHash::new(hashed_password)?;
+ Ok(argon2.verify_password(password.as_bytes(), &parsed_hash).is_ok())
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn simple_case() -> Result<(), Box<dyn std::error::Error>> {
+ let password = "12345";
+ let hash = hash(password)?;
+ println!("hash: {}", &hash);
+ assert!(verify_password(password, &hash)?);
+ assert!(!verify_password("54321", &hash)?);
+ Ok(())
+ }
+
+ #[test]
+ fn password_with_special_characters() -> Result<(), Box<dyn std::error::Error>> {
+ let password = "éà ä_\\😺🎮🇨🇭";
+ let hash = hash(password)?;
+ println!("hash: {}", &hash);
+ assert!(verify_password(password, &hash)?);
+ Ok(())
+ }
}
\ No newline at end of file