login_app 0.1.5

A generic login module for web apps
Documentation
// messages.rs
// enum messages are collected here
// each enum key has associated description in messages.json file and this file is
// loaded to access those descriptions

use ::log::*; // external crate for macros such as debug!, info!, so on
use std::collections::HashMap;
use lazy_static::*;
use std::fs::File;
use std::io::Read;
use serde_json;
use serde_derive::{Serialize, Deserialize};

#[derive(Debug, PartialEq, Clone, Copy, Eq, Hash, Serialize, Deserialize)]
pub enum Msg {
    
    Active,

    CancellationFailed,
    CancellationSuccess,
    Cancelled,
    ConfirmationPending,
    
    DbError,
    DBUserRetrievalFailed,
    DeleteExpiredRegistrationSuccess,
    DeleteExpiredRegistrationFailed,
    DeletionFailed,
    DeletionSuccess,
    Dormant,

    EmailExist,
    EmailNotExist,
    EmailSent,
    EmailNotSent,
    EmailSentToCompleteRegistration,
    ExpiryCheckFailed,

    ForgotPasswordFailed,
    ForgotPasswordProcessed,
    ForgotPasswordPending,
    ForgotPasswordTokenExpired,

    GetUnconfirmedUserRecordFailed,
    GetUnconfirmedUserRecordSuccess,
    
    InvalidCredentials,
    InvalidEmailPattern,
    InvalidPasswordPattern,
    InvalidToken,

    LoginSucceeded,

    NewRegistrationFailed,
    NoEmailFoundCancellationFailed,
    NoEmailFoundDeleteFailed,
    NoneFound,
    
    PasswordsDoNotMatch,
    PasswordsMatch,
    
    PasswordHasLowercase,
    PasswordHasNoLowercase,
    
    PasswordHasUppercase,
    PasswordHasNoUppercase,

    PasswordHasNumber,
    PasswordHasNoNumber,

    PasswordHasSplChar,
    PasswordHasNoSplChar,
    
    PasswordLengthOk,
    PasswordLengthNotOk,

    RegexFailedOnEmail,
    RegexFailedOnPassword,

    RegexFailedOnPasswordLowercase,
    RegexFailedOnPasswordUppercase,
    
    RegexFailedOnPasswordNumber,
    RegexFailedOnPasswordSplChar,
    RegexFailedOnPasswordLength,

    RegistrationConfirmed,
    RegistrationAlreadyConfirmed,
    RegistrationConfirmationFailed,
    RegistrationInitialRemarks,
    RegistrationRetrievalFailed,

    ResetPasswordFailed,
    ResetPasswordProcessed,

    StatusUpdated,
    StatusUpdateFailed,

    UserRetrievalFailed,
    
    ValidEmailPattern,
    ValidPasswordPattern,
    ValidationsPassed
}

impl Msg {
    pub fn key_for(description: &str) -> Self {
        debug!("key_for({:?}) ---------------------------<<", description);
        match LMSG.iter().find(|(_key, value)| value.as_str() == description) {
            Some((key, _value)) => key.clone(),
            None => Msg::NoneFound,
        }        
    }
    pub fn description(&self) -> String {
        debug!("description() -------------------------<<");
        match LMSG.get(self) {
            Some(key) => key.to_string(),
            None => String::new(),
        }        
    }
}

impl From<rusqlite::Error> for Msg {
    fn from(error: rusqlite::Error) -> Self {
        debug!("rusqlite error: {:?} occurred", error);
        Msg::DBUserRetrievalFailed
    }
}

#[derive(Serialize, Deserialize, Debug)]
struct Message {
    map: HashMap<Msg, String>,
}

lazy_static!{
    pub static ref LMSG: HashMap<Msg, String> = get_descriptions_map();
}

fn get_descriptions_map() -> HashMap<Msg, String> { // loads descriptions map from an external file; 
    let filename = super::app_config("messages_from");
    let mut message_file = File::open(&filename).unwrap();
    let mut contents = String::new();
    if let Err(message) = message_file.read_to_string(&mut contents) {
        error!("{:?} occurred in messages >> message_lmsg_map() while reading json file", message);
        return HashMap::new();
    };
    let msg: Message = serde_json::from_str(&contents).unwrap_or_else(|e| {
        debug!("error in serde_json::from_str(contents) : {:?}", e);
        Message { map: HashMap::new() }
    });
    msg.map
}