shared-framework 0.0.17

Reusable building blocks for HTTP services — Hyper routing, SeaORM data layer, validation, OpenAPI docs, jobs, queues, cache.
Documentation
//! JSON, base64, and token helpers.
//!
//! [`DataHelpers`] serializes and deserializes JSON, encodes and decodes base64,
//! creates random alphanumeric tokens, and converts serializable values to
//! `serde_json::Value` (falling back to `Null` on failure).

use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
use rand::distr::{Alphanumeric, SampleString};
use rand::RngExt;
use serde::{de::DeserializeOwned, Serialize};

/// Stateless JSON, base64, and token helpers.
pub struct DataHelpers;

impl DataHelpers {
    /// Serializes a value to a JSON string. Returns an error when serialization fails.
    pub fn serialize<T: Serialize>(value: &T) -> Result<String, serde_json::Error> {
        serde_json::to_string(value)
    }

    /// Deserializes a value from a JSON string. Returns an error on invalid input.
    pub fn deserialize<T: DeserializeOwned>(s: &str) -> Result<T, serde_json::Error> {
        serde_json::from_str(s)
    }

    /// Encodes a UTF-8 string as standard base64.
    pub fn to_base64(s: &str) -> String {
        BASE64.encode(s.as_bytes())
    }

    /// Decodes standard base64 to a string, replacing invalid UTF-8 sequences.
    /// Returns an error when the input is not valid base64.
    pub fn from_base64(s: &str) -> Result<String, base64::DecodeError> {
        let bytes = BASE64.decode(s)?;
        Ok(String::from_utf8_lossy(&bytes).to_string())
    }

    /// Creates a random alphanumeric token of length `len`.
    pub fn create_token(len: usize) -> String {
        Alphanumeric.sample_string(&mut rand::rng(), len)
    }

    /// Creates a random alphanumeric token with a length chosen in `[min, max]`.
    /// Uses `min` when `max <= min`. `_range`, `_prefix`, and `_alphanum` are ignored.
    pub fn create_token_range(min: usize, max: usize, _range: usize, _prefix: &str, _alphanum: bool) -> String {
        let len = if max > min { rand::rng().random_range(min..=max) } else { min };
        Self::create_token(len)
    }

    /// Converts a value to `serde_json::Value`, returning `Null` when conversion fails.
    pub fn to_json<T: Serialize>(v: &T) -> serde_json::Value {
        serde_json::to_value(v).unwrap_or(serde_json::Value::Null)
    }
}