gearbox 3.0.0

Excessive tooling for Rust, boosting productivity and operations
Documentation
use crate::log::fmt::severity::Severity;
use crate::log::fmt::util::{IntegerConversionError, UtilTryInto};
use crate::time::DateTime;
use alloc::{
    string::{String, ToString},
    vec,
    vec::Vec,
};
use core::fmt::{Debug, Display, Formatter};

pub enum LogValueConvertionError {
    FailedToConvertToDateTimeUtc(String),
    FailedToConvertToU32(String),
    FailedToConvertToI32(String),
    UnableToCreateTimestampFrom(i64),
    IntegerConversionError(IntegerConversionError),
}

impl From<IntegerConversionError> for LogValueConvertionError {
    fn from(e: IntegerConversionError) -> Self {
        Self::IntegerConversionError(e)
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum LogValue {
    I64(i64),
    U64(u64),
    F64(f64),
    Bool(bool),
    String(String),
    TimeStamp(DateTime),
    Severity(Severity),
    Debug(String),
}

impl From<i64> for LogValue {
    fn from(v: i64) -> Self {
        LogValue::I64(v)
    }
}

impl From<u64> for LogValue {
    fn from(v: u64) -> Self {
        LogValue::U64(v)
    }
}

impl From<f64> for LogValue {
    fn from(v: f64) -> Self {
        LogValue::F64(v)
    }
}

impl From<bool> for LogValue {
    fn from(v: bool) -> Self {
        LogValue::Bool(v)
    }
}

impl From<String> for LogValue {
    fn from(v: String) -> Self {
        LogValue::String(v)
    }
}

impl From<&str> for LogValue {
    fn from(v: &str) -> Self {
        LogValue::String(v.to_string())
    }
}

impl Display for LogValue {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        match self {
            LogValue::I64(t) => write!(f, "{}", t),
            LogValue::U64(t) => write!(f, "{}", t),
            LogValue::F64(t) => write!(f, "{}", t),
            LogValue::Bool(t) => write!(f, "{}", t),
            LogValue::String(t) => write!(f, "{}", t),
            LogValue::Debug(t) => write!(f, "{}", t),
            LogValue::TimeStamp(t) => write!(f, "{}", t),
            LogValue::Severity(t) => write!(f, "{}", t),
        }
    }
}

impl TryFrom<LogValue> for DateTime {
    type Error = LogValueConvertionError;

    fn try_from(value: LogValue) -> Result<Self, Self::Error> {
        match value {
            LogValue::I64(i) => Ok(DateTime::from_secs(i).into()),
            LogValue::U64(u) => Ok(DateTime::from_secs(u as i64).into()),
            LogValue::F64(f) => Ok(DateTime::from_secs(f as i64).into()),

            LogValue::Bool(_) => Err(LogValueConvertionError::FailedToConvertToDateTimeUtc(
                "LogValue is a boolean, unable to convert".to_string(),
            )),
            LogValue::String(s) => DateTime::from_str(s.as_str())
                .map_err(|e| LogValueConvertionError::FailedToConvertToDateTimeUtc(e.to_string())),
            LogValue::Debug(s) => DateTime::from_str(s.as_str())
                .map_err(|e| LogValueConvertionError::FailedToConvertToDateTimeUtc(e.to_string())),
            LogValue::TimeStamp(t) => Ok(t),
            LogValue::Severity(_t) => Err(LogValueConvertionError::FailedToConvertToDateTimeUtc(
                "LogValue is a Severity and cannot be convert".to_string(),
            )),
        }
    }
}

impl From<LogValue> for String {
    fn from(value: LogValue) -> Self {
        value.to_string()
    }
}

impl TryFrom<LogValue> for u32 {
    type Error = LogValueConvertionError;

    fn try_from(value: LogValue) -> Result<Self, Self::Error> {
        match value {
            LogValue::I64(i) => i.util_try_into().map_err(LogValueConvertionError::from),
            LogValue::U64(u) => u.util_try_into().map_err(LogValueConvertionError::from),
            LogValue::F64(f) => f.util_try_into().map_err(LogValueConvertionError::from),
            LogValue::Bool(_) => Err(LogValueConvertionError::FailedToConvertToU32(
                "LogValue is a Bool, unable to convert".to_string(),
            )),
            LogValue::String(_s) => Err(LogValueConvertionError::FailedToConvertToU32(
                "LogValue is a String, unable to convert".to_string(),
            )),
            LogValue::Debug(_s) => Err(LogValueConvertionError::FailedToConvertToU32(
                "LogValue is a String, unable to convert".to_string(),
            )),
            LogValue::TimeStamp(t) => Ok(t.to_unix() as u32),
            LogValue::Severity(_t) => Err(LogValueConvertionError::FailedToConvertToU32(
                "LogValue is a Severity and cannot be convert".to_string(),
            )),
        }
    }
}

impl TryFrom<LogValue> for i32 {
    type Error = LogValueConvertionError;

    fn try_from(value: LogValue) -> Result<Self, Self::Error> {
        match value {
            LogValue::I64(i) => i.util_try_into().map_err(LogValueConvertionError::from),
            LogValue::U64(u) => u.util_try_into().map_err(LogValueConvertionError::from),
            LogValue::F64(f) => f.util_try_into().map_err(LogValueConvertionError::from),
            LogValue::Bool(_) => Err(LogValueConvertionError::FailedToConvertToI32(
                "LogValue is a Bool, unable to convert".to_string(),
            )),
            LogValue::String(_s) => Err(LogValueConvertionError::FailedToConvertToI32(
                "LogValue is a String, unable to convert".to_string(),
            )),
            LogValue::Debug(_s) => Err(LogValueConvertionError::FailedToConvertToI32(
                "LogValue is a String, unable to convert".to_string(),
            )),
            LogValue::TimeStamp(t) => Ok(t.to_unix() as i32),
            LogValue::Severity(_t) => Err(LogValueConvertionError::FailedToConvertToI32(
                "LogValue is a Severity and cannot be convert".to_string(),
            )),
        }
    }
}

impl From<LogValue> for Vec<String> {
    fn from(value: LogValue) -> Self {
        vec![value.to_string()]
    }
}

impl From<u32> for LogValue {
    fn from(u: u32) -> Self {
        LogValue::U64(u as u64)
    }
}
impl From<Option<u32>> for LogValue {
    fn from(opt: Option<u32>) -> Self {
        match opt {
            None => LogValue::Debug("".to_string()),
            Some(u) => LogValue::U64(u as u64),
        }
    }
}
impl From<Option<&str>> for LogValue {
    fn from(opt: Option<&str>) -> Self {
        match opt {
            None => LogValue::Debug("".to_string()),
            Some(s) => LogValue::String(s.to_string()),
        }
    }
}

#[cfg(feature = "bunyan")]
impl From<&LogValue> for serde_json::Value {
    fn from(v: &LogValue) -> Self {
        match v {
            LogValue::I64(t) => t.clone().into(),
            LogValue::U64(t) => t.clone().into(),
            LogValue::F64(t) => t.clone().into(),
            LogValue::Bool(t) => t.clone().into(),
            LogValue::String(t) => t.clone().into(),
            LogValue::TimeStamp(t) => t.to_string().into(),
            LogValue::Severity(t) => t.to_string().into(),
            LogValue::Debug(t) => t.clone().into(),
        }
    }
}