dipper 0.5.3

An out-of-the-box modular dependency injection web application framework.
Documentation
//! User identifier

use std::fmt::Display;

use salvo::oapi::ToSchema;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash, ToSchema, Debug)]
#[serde(untagged)]
#[allow(clippy::exhaustive_enums)]
pub enum Uid {
    I64(i64),
    Str(String),
}
impl From<i64> for Uid {
    fn from(value: i64) -> Self {
        Self::I64(value)
    }
}
impl From<String> for Uid {
    fn from(value: String) -> Self {
        Self::Str(value)
    }
}
impl From<&str> for Uid {
    fn from(value: &str) -> Self {
        Self::Str(value.to_owned())
    }
}
impl Display for Uid {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match &self {
            Uid::I64(v) => write!(f, "{v}"),
            Uid::Str(v) => write!(f, "{v}"),
        }
    }
}
impl Uid {
    pub const fn is_i64_item(&self) -> bool {
        if let Self::I64(_) = self {
            return true;
        }
        false
    }
    pub const fn to_i64_item(&self) -> Option<i64> {
        if let Self::I64(v) = self {
            return Some(*v);
        }
        None
    }
    pub const fn to_i64_or_default(&self) -> i64 {
        if let Self::I64(v) = self {
            return *v;
        }
        0
    }
    pub const fn is_str_item(&self) -> bool {
        if let Self::Str(_) = self {
            return true;
        }
        false
    }
    pub fn into_str_item(self) -> Option<String> {
        if let Self::Str(v) = self {
            return Some(v);
        }
        None
    }
    pub fn into_str_or_default(self) -> String {
        if let Self::Str(v) = self {
            return v;
        }
        String::new()
    }
    pub const fn as_str_item(&self) -> Option<&String> {
        if let Self::Str(v) = self {
            return Some(v);
        }
        None
    }
}

#[allow(non_camel_case_types)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Hash, ToSchema, Debug)]
#[serde(tag = "identifier_type", content = "identifier_value")]
pub enum UserIdentifier {
    id(Uid),
    username(String),
    email(String),
    phone(String),
}

impl UserIdentifier {
    pub const fn is_id(&self) -> bool {
        if let Self::id(_) = self {
            return true;
        }
        false
    }
    pub const fn is_username(&self) -> bool {
        if let Self::username(_) = self {
            return true;
        }
        false
    }
    pub const fn is_email(&self) -> bool {
        if let Self::email(_) = self {
            return true;
        }
        false
    }
    pub const fn is_phone(&self) -> bool {
        if let Self::phone(_) = self {
            return true;
        }
        false
    }
    pub const fn id(&self) -> Option<&Uid> {
        if let Self::id(id) = self {
            return Some(id);
        }
        None
    }
    pub fn into_username(self) -> Option<String> {
        if let Self::username(username) = self {
            return Some(username);
        }
        None
    }
    pub fn into_email(self) -> Option<String> {
        if let Self::email(email) = self {
            return Some(email);
        }
        None
    }
    pub fn into_phone(self) -> Option<String> {
        if let Self::phone(phone) = self {
            return Some(phone);
        }
        None
    }
    pub const fn as_username(&self) -> Option<&String> {
        if let Self::username(username) = self {
            return Some(username);
        }
        None
    }
    pub const fn as_email(&self) -> Option<&String> {
        if let Self::email(email) = self {
            return Some(email);
        }
        None
    }
    pub const fn as_phone(&self) -> Option<&String> {
        if let Self::phone(phone) = self {
            return Some(phone);
        }
        None
    }
}

#[cfg(test)]
mod tests {
    use super::UserIdentifier;

    #[test]
    fn test_json() {
        assert_eq!(
            r##"{"identifier_type":"id","identifier_value":"a"}"##,
            serde_json::to_string(&UserIdentifier::id("a".into())).unwrap()
        );
        assert_eq!(
            r##"{"identifier_type":"id","identifier_value":1}"##,
            serde_json::to_string(&UserIdentifier::id(1.into())).unwrap()
        );
    }
}