mitoo 0.3.0

mitoo is a Rust toolkit library that encapsulates methods such as configuration reading, file operations, encryption and decryption, transcoding, regular expressions, threading, collections, trees, sqlite, rabbitMQ, etc., and customizes or integrates various Util tool classes.
Documentation
use crate::Exception;
use chrono::{Datelike, Local, NaiveDate, NaiveDateTime, Timelike};
use std::collections::HashMap;

/// Basic data objects (including Number, String, bool, none, and time)
#[derive(Debug)]
pub enum Object {
    Integer32(i32),
    Long64(i64),
    String(String),
    Float32(f32),
    Double64(f64),
    Boolean(bool),
    Date(NaiveDate),
    DateTime(NaiveDateTime),
    None,
}

impl From<&str> for Object {
    fn from(s: &str) -> Self {
        Object::String(s.to_string())
    }
}
impl From<i32> for Object {
    fn from(value: i32) -> Self {
        Object::Integer32(value)
    }
}

impl From<i64> for Object {
    fn from(value: i64) -> Self {
        Object::Long64(value)
    }
}

impl From<f32> for Object {
    fn from(value: f32) -> Self {
        Object::Float32(value)
    }
}

impl From<f64> for Object {
    fn from(value: f64) -> Self {
        Object::Double64(value)
    }
}

impl From<bool> for Object {
    fn from(value: bool) -> Self {
        Object::Boolean(value)
    }
}

#[cfg(feature = "db-sqlite")]
impl From<sqlite::Value> for Object {
    fn from(value: sqlite::Value) -> Self {
        match value {
            sqlite::Value::Float(value) => Object::Double64(value),
            sqlite::Value::Integer(value) => Object::Long64(value),
            sqlite::Value::String(value) => Object::String(value),
            _ => Object::None,
        }
    }
}

#[cfg(feature = "db-sqlite")]
impl From<&sqlite::Value> for Object {
    fn from(value: &sqlite::Value) -> Self {
        match value {
            sqlite::Value::Float(value) => Object::Double64(*value),
            sqlite::Value::Integer(value) => Object::Long64(*value),
            sqlite::Value::String(value) => Object::String(value.to_string()),
            _ => Object::None,
        }
    }
}

#[cfg(feature = "db-mysql")]
impl TryFrom<mysql_common::Value> for Object {
    type Error = mysql_common::FromValueError;

    fn try_from(value: mysql_common::Value) -> Result<Self, Self::Error> {
        // TODO 此处有问题,通过这种方式返回的值,全部是Bytes类型,没有根据数据库实际情况返回对应的类型,如int,string,float等
        println!("{:?}", value);

        let res = match value {
            mysql_common::Value::Int(v) => Object::Integer32(v as i32),
            mysql_common::Value::UInt(v) => Object::Long64(v as i64),
            mysql_common::Value::Float(v) => Object::Float32(v),
            mysql_common::Value::Double(v) => Object::Double64(v),
            mysql_common::Value::Bytes(u8_arr) => Object::String(String::from_utf8(u8_arr).unwrap()),
            mysql_common::Value::Date(year, month, day, hour, minute, second, ms) => {
                let dt = Local::now();
                let dt = dt.with_year(year as i32).unwrap()
                    .with_month(month as u32).unwrap()
                    .with_day(day as u32).unwrap()
                    .with_hour(hour as u32).unwrap()
                    .with_minute(minute as u32).unwrap()
                    .with_second(second as u32).unwrap()
                    .with_nanosecond(ms).unwrap();
                Object::DateTime(dt.naive_local())
            },
            _ => Object::None,
        };
        Ok(res)
    }
}

#[cfg(feature = "db-mysql")]
impl mysql_common::value::convert::FromValue for Object {
    type Intermediate = Object;
    // type Intermediate: TryFrom<Value, Error = FromValueError> + Into<Self>;

    fn from_value(value: mysql_common::value::Value) -> Self {
        match value {
            mysql_common::value::Value::Bytes(bytes) => {
                Object::String(String::from_utf8_lossy(&bytes).to_string())
            }
            mysql_common::value::Value::Int(value) => Object::Long64(value),
            mysql_common::value::Value::UInt(value) => Object::Long64(value as i64),
            _ => Object::None,
        }
    }

    fn from_value_opt(_v: mysql_common::Value) -> Result<Self, mysql_common::FromValueError> {
        todo!()
    }

    fn get_intermediate(_v: mysql_common::Value) -> Result<Self::Intermediate, mysql_common::FromValueError> {
        todo!()
    }
}

impl Object {
    pub fn is_null(&self) -> bool {
        match self {
            Object::None => true,
            _ => false,
        }
    }

    /// 将Object枚举转换为String类型
    ///
    /// # 参数
    /// * `self` - Object枚举的引用
    ///
    /// # 返回值
    /// 返回Option<String>,如果Object为None则返回None,否则返回对应值的字符串表示
    pub fn get_string(&self) -> Option<String> {
        match self {
            // 匹配不同的Object类型并转换为字符串
            Object::None => None,
            Object::Integer32(value) => Some(value.to_string()),
            Object::Long64(value) => Some(value.to_string()),
            Object::Float32(value) => Some(value.to_string()),
            Object::Double64(value) => Some(value.to_string()),
            Object::String(value) => Some(value.to_string()),
            Object::Boolean(value) => Some(value.to_string()),
            Object::Date(value) => Some(value.format("%Y-%m-%d").to_string()),
            Object::DateTime(value) => Some(value.format("%Y-%m-%d %H:%M:%S").to_string()),
        }
    }

    /// 将对象转换为整数类型
    ///
    /// 该函数尝试将当前对象转换为i32类型的整数。根据不同对象类型,
    /// 采用相应的转换规则:整数和长整数直接转换,浮点数截断小数部分,
    /// 布尔值转换为0或1,其他类型返回None。
    ///
    /// # 返回值
    /// * `Option<i32>` - 转换成功返回Some(整数值),失败返回None
    pub fn get_integer(&self) -> Option<i32> {
        match self {
            // 数值类型直接转换或截断
            Object::Integer32(value) => Some(*value),
            Object::Long64(value) => Some(*value as i32),
            Object::Float32(value) => Some(*value as i32),
            Object::Double64(value) => Some(*value as i32),
            // 布尔类型转换为数字
            Object::Boolean(value) => {
                if *value {
                    Some(1)
                } else {
                    Some(0)
                }
            }
            // 其他类型无法转换
            _ => None,
        }
    }

    /// 将对象转换为64位整数类型
    ///
    /// 该函数尝试将当前对象转换为i64类型的值。根据不同对象类型,
    /// 会进行相应的类型转换或映射。
    ///
    /// # 返回值
    /// - `Some(i64)` - 转换成功时返回对应的64位整数值
    /// - `None` - 当前对象无法转换为整数类型时返回None
    pub fn get_long(&self) -> Option<i64> {
        match self {
            // 数值类型直接转换为i64
            Object::Integer32(value) => Some(*value as i64),
            Object::Long64(value) => Some(*value),
            Object::Float32(value) => Some(*value as i64),
            Object::Double64(value) => Some(*value as i64),
            // 布尔类型映射:true->1, false->0
            Object::Boolean(value) => {
                if *value {
                    Some(1)
                } else {
                    Some(0)
                }
            }
            // 其他类型无法转换为整数
            _ => None,
        }
    }

    /// Convert the current object to 32-bit float-point number
    ///
    /// # 返回值
    /// * `Option<f32>` - 转换成功时返回Some(f32),否则返回None
    ///
    /// # 转换规则
    /// * Integer32: 直接转换为f32
    /// * Long64: 转换为f32(可能丢失精度)
    /// * Float32: 直接返回
    /// * Double64: 转换为f32(可能丢失精度)
    /// * Boolean: true转为1.0,false转为0.0
    /// * 其他类型: 返回None
    pub fn get_float32(&self) -> Option<f32> {
        match self {
            // 数值类型转换为f32
            Object::Integer32(value) => Some(*value as f32),
            Object::Long64(value) => Some(*value as f32),
            Object::Float32(value) => Some(*value),
            Object::Double64(value) => Some(*value as f32),
            // 布尔类型转换:true=1.0, false=0.0
            Object::Boolean(value) => {
                if *value {
                    Some(1.0)
                } else {
                    Some(0.0)
                }
            }
            // 其他不支持的类型返回None
            _ => None,
        }
    }

    /// 将对象转换为双精度浮点数
    ///
    /// 该函数尝试将当前对象转换为f64类型的值。支持的类型包括:
    /// - 整数类型(Integer32、Long64):直接转换为对应的浮点数
    /// - 浮点数类型(Float32、Double64):Float32转换为f64,Double64直接返回
    /// - 布尔类型:true转换为1.0,false转换为0.0
    /// - 其他类型:返回None
    ///
    /// # 返回值
    /// * `Option<f64>` - 转换成功返回Some(f64值),否则返回None
    pub fn get_double(&self) -> Option<f64> {
        match self {
            // 数值类型直接转换为f64
            Object::Integer32(value) => Some(*value as f64),
            Object::Long64(value) => Some(*value as f64),
            Object::Float32(value) => Some(*value as f64),
            Object::Double64(value) => Some(*value),
            // 布尔类型转换为对应的数值
            Object::Boolean(value) => {
                if *value {
                    Some(1.0)
                } else {
                    Some(0.0)
                }
            }
            // 其他类型无法转换,返回None
            _ => None,
        }
    }
}

/// Database operation interface definition (conventional CRUD)
pub trait SqlCrud {
    /// 向数据库中插入数据
    ///
    /// # 参数
    /// * `sql` - 要执行的SQL插入语句
    ///
    /// # 返回值
    /// * `Result<bool, Exception>` - 操作结果
    ///   - 成功时返回布尔值,表示插入操作是否成功执行
    ///   - 失败时返回Exception错误信息
    fn insert(&self, sql: &str) -> Result<bool, Exception>;

    /// 执行SQL更新操作
    ///
    /// 该函数用于执行给定的SQL语句,通常用于INSERT、UPDATE或DELETE操作
    ///
    /// # 参数
    /// * `sql` - 要执行的SQL语句字符串引用
    ///
    /// # 返回值
    /// * `Result<bool, Exception>` - 操作结果
    /// - 成功时返回布尔值,表示操作是否成功执行
    /// - 失败时返回Exception错误信息
    fn update(&self, sql: &str) -> Result<bool, Exception>;

    /// 删除数据库中的记录
    ///
    /// 执行指定的DELETE SQL语句来删除数据库中的记录
    ///
    /// # 参数
    /// * `sql` - 要执行的DELETE SQL语句字符串引用
    ///
    /// # 返回值
    /// * `Result<bool, Exception>` - 操作结果
    ///   - 成功时返回`Ok(true)`表示删除成功
    ///   - 失败时返回`Err(Exception)`包含具体的异常信息
    fn delete(&self, sql: &str) -> Result<bool, Exception>;

    /// 从数据库中执行SELECT查询并返回单行结果
    ///
    /// 该函数执行传入的SQL SELECT语句,期望返回单行数据。
    /// 如果查询成功,将结果转换为键值对形式的HashMap返回,
    /// 其中键为列名,值为对应的数据库字段值。
    ///
    /// # 参数
    /// * `sql` - 要执行的SQL SELECT查询语句
    ///
    /// # 返回值
    /// * `Ok(HashMap<String, Object>)` - 查询成功,返回包含列名和对应值的映射
    /// * `Err(Exception)` - 查询失败,返回异常信息
    ///
    /// # 错误处理
    /// 当SQL语句执行失败、连接数据库出错或结果解析异常时,会返回相应的错误信息
    fn select_one(&self, sql: &str) -> Result<HashMap<String, Object>, Exception>;

    /// 执行SQL查询语句并返回结果集
    ///
    /// 该函数用于执行SELECT类型的SQL查询,将查询结果转换为键值对的向量形式返回。
    ///
    /// # 参数
    /// * `sql` - 要执行的SQL查询语句字符串引用
    ///
    /// # 返回值
    /// * `Result<Vec<HashMap<String, Object>>, Exception>` - 执行结果
    ///   - 成功时返回包含查询结果的向量,每个元素是一个HashMap,表示一行数据,键为列名,值为对应的数据值
    ///   - 失败时返回Exception错误信息
    fn select(&self, sql: &str) -> Result<Vec<HashMap<String, Object>>, Exception>;
}