hoicko_lib 0.1.16

Hoicko library
Documentation
use std::time::{SystemTime, UNIX_EPOCH};
use serde::de::DeserializeOwned;
use serde_json::Value;

pub enum JsonParseError {
    ParseError(String),
    EmptyInput,
    InvalidFormat,
}

pub fn parse_json_detailed<T>(json: impl AsRef<str>) -> Result<T, JsonParseError> 
where 
    T: DeserializeOwned,
{
    let json = json.as_ref();
    
    // Check for empty input
    if json.trim().is_empty() {
        return Err(JsonParseError::EmptyInput);
    }

    // First try to parse as generic JSON to validate format
    let value: Value = serde_json::from_str(json).map_err(|e| {
        tracing::error!("Invalid JSON format: {}", e);
        JsonParseError::InvalidFormat
    })?;

    // Then try to parse into specific type
    serde_json::from_value(value).map_err(|e| {
        tracing::error!(
            "Error parsing JSON into specific type: {}, Input: {}", 
            e,
            if json.len() > 100 { 
                format!("{}...(truncated)", &json[..100]) 
            } else { 
                json.to_string() 
            }
        );
        JsonParseError::ParseError(e.to_string())
    })
}

pub fn generate_between(min: i8, max: i8) -> i8 {
    let range = (max - min) as u32;
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .subsec_nanos();
    
    min + (timestamp % range) as i8
}

// Helper function for Option wrapping
pub fn parse_json_optional<T>(json: impl AsRef<str>) -> Option<T> 
where 
    T: DeserializeOwned,
{
    match parse_json_detailed(json) {
        Ok(parsed) => Some(parsed),
        Err(err) => {
            match err {
                JsonParseError::EmptyInput => {
                    tracing::debug!("Empty JSON input received");
                }
                JsonParseError::InvalidFormat => {
                    tracing::warn!("Invalid JSON format");
                }
                JsonParseError::ParseError(e) => {
                    tracing::error!("JSON parse error: {}", e);
                }
            }
            None
        }
    }
}