mycommon-utils 0.2.2

Common utilities library for database operations, Redis caching and system utilities
Documentation
use serde::de::{Error, Visitor};
use std::fmt;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use redis::{FromRedisValue, RedisWrite, ToRedisArgs, Value as RedisValue};
use sea_orm::{DbErr, DeriveValueType, TryFromU64};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub mod config;
pub mod redis_util;
pub mod database_util;
pub mod common;


// 自定义数据库组件,主要是解决网页前端解析19位数字精度问题
// 自定义主键对外序列化是字符串,内部使用的i64类型
#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType, Copy, PartialOrd, Default)]
pub struct BigIntPrimaryKey(pub i64);

impl BigIntPrimaryKey {
    pub fn new (inner: i64) ->Self{
        BigIntPrimaryKey(inner)
    }
    pub fn inner (&self) ->i64{
        self.0
    }
}

impl Display for BigIntPrimaryKey {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl TryFromU64 for BigIntPrimaryKey {
    fn try_from_u64(n: u64) -> Result<Self, DbErr> {
        Ok(Self::new(n as i64))
    }
}

struct BigKeyVisitor;
impl<'de> Visitor<'de> for BigKeyVisitor {
    type Value = i64;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("Parsing parameters failed")
    }
    fn visit_i8<E>(self, s: i8) -> Result<Self::Value, E>
    where E: Error
    {
        Ok(s as i64)
    }
    fn visit_i16<E>(self, s: i16) -> Result<Self::Value, E>
    where E: Error
    {
        Ok(s as i64)
    }
    fn visit_i32<E>(self, s: i32) -> Result<Self::Value, E>
    where E: Error
    {
        Ok(s as i64)
    }
    fn visit_i64<E>(self, s: i64) -> Result<Self::Value, E>
    where E: Error
    {
        Ok(s)
    }
    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E> where E: Error {
        Ok(v as i64)
    }
    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E> where E: Error {
        Ok(v as i64)
    }
    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E> where E: Error {
        Ok(v as i64)
    }
    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E> where E: Error {
        Ok(v as i64)
    }
    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> where E: Error {
        Ok(v as i64)
    }
    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> where E: Error {
        Ok(v as i64)
    }
    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
    where E: Error
    {
        i64::from_str(s).map_err(Error::custom)
    }
    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> where E: Error {
        i64::from_str(v.as_str()).map_err(Error::custom)
    }
}

impl<'de> Deserialize<'de> for BigIntPrimaryKey {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
        let inner = deserializer.deserialize_any(BigKeyVisitor)?;
        return  Ok(Self(inner))
    }
}

impl Serialize for BigIntPrimaryKey {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
        let j = format!("{}",self.inner());
        j.serialize(serializer)
    }
}

impl From<String> for BigIntPrimaryKey {
    fn from(arg: String) -> Self {
        let result = arg.parse::<i64>();
        if let Ok(i) = result {
            return Self(i);
        }
        return Self(-1);
    }
}

impl From<i64> for BigIntPrimaryKey {
    fn from(i: i64) -> Self {
        return Self(i)
    }
}


impl ToRedisArgs for BigIntPrimaryKey {
    fn write_redis_args<W>(&self, out: &mut W) where W: ?Sized + RedisWrite,
    {
        out.write_arg(self.0.to_string().as_bytes())
    }
}
impl FromRedisValue for BigIntPrimaryKey {
    fn from_redis_value(v: RedisValue) -> std::result::Result<BigIntPrimaryKey, redis::ParsingError> {
        match v {
            RedisValue::BulkString(bytes) => {
                let data = String::from_utf8(bytes.to_vec())?;
                let id = data.parse::<i64>().map_err(|_| redis::ParsingError::from("Invalid i64"))?;
                Ok(BigIntPrimaryKey(id))
            }
            _ => Err(redis::ParsingError::from("Unexpected value type")),
        }
    }
}