use puerto_core::RepositoryError;
{%- if local %}
use puerto_core::auth::HashError;
{%- endif %}
use thiserror::Error;
#[derive(Debug, Error)]
pub enum UserError {
#[error("user.not_found")]
NotFound,
#[error("user.duplicate")]
Duplicate,
#[error("user.repository_error")]
RepositoryError,
{%- if local %}
/// `email_invalid`, `password_too_short`.
#[error("user.validation_error.{0}")]
ValidationError(String),
/// An unknown email or a wrong password: the caller is not told which.
#[error("auth.invalid_credentials")]
InvalidCredentials,
/// The password could not be hashed.
#[error("user.unknown")]
Unknown,
{%- endif %}
}
impl From<RepositoryError> for UserError {
/// `RepositoryError` is `#[non_exhaustive]`: one a later version adds is the store's problem
/// (500) until it gets a meaning here.
fn from(err: RepositoryError) -> Self {
match err {
RepositoryError::Duplicate => Self::Duplicate,
RepositoryError::InvalidData | RepositoryError::Unavailable => Self::RepositoryError,
_ => Self::RepositoryError,
}
}
}
{% if local %}impl From<HashError> for UserError {
fn from(_: HashError) -> Self {
Self::Unknown
}
}
{% endif %}#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_convert_a_duplicate_into_the_user_duplicate() {
let err = UserError::from(RepositoryError::Duplicate);
assert_eq!(err.to_string(), "user.duplicate");
}
#[test]
fn should_convert_an_unavailable_store_into_a_repository_error() {
let err = UserError::from(RepositoryError::Unavailable);
assert_eq!(err.to_string(), "user.repository_error");
}
{%- if local %}
#[test]
fn should_say_invalid_credentials_whichever_part_was_wrong() {
assert_eq!(UserError::InvalidCredentials.to_string(), "auth.invalid_credentials");
}
#[test]
fn should_convert_a_failed_hash_into_the_user_unknown() {
assert_eq!(UserError::from(HashError).to_string(), "user.unknown");
}
{%- endif %}
}