Skip to main content

shared_framework/utils/
data_helpers.rs

1//! JSON, base64, and token helpers.
2//!
3//! [`DataHelpers`] serializes and deserializes JSON, encodes and decodes base64,
4//! creates random alphanumeric tokens, and converts serializable values to
5//! `serde_json::Value` (falling back to `Null` on failure).
6
7use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
8use rand::distr::{Alphanumeric, SampleString};
9use rand::RngExt;
10use serde::{de::DeserializeOwned, Serialize};
11
12/// Stateless JSON, base64, and token helpers.
13pub struct DataHelpers;
14
15impl DataHelpers {
16    /// Serializes a value to a JSON string. Returns an error when serialization fails.
17    pub fn serialize<T: Serialize>(value: &T) -> Result<String, serde_json::Error> {
18        serde_json::to_string(value)
19    }
20
21    /// Deserializes a value from a JSON string. Returns an error on invalid input.
22    pub fn deserialize<T: DeserializeOwned>(s: &str) -> Result<T, serde_json::Error> {
23        serde_json::from_str(s)
24    }
25
26    /// Encodes a UTF-8 string as standard base64.
27    pub fn to_base64(s: &str) -> String {
28        BASE64.encode(s.as_bytes())
29    }
30
31    /// Decodes standard base64 to a string, replacing invalid UTF-8 sequences.
32    /// Returns an error when the input is not valid base64.
33    pub fn from_base64(s: &str) -> Result<String, base64::DecodeError> {
34        let bytes = BASE64.decode(s)?;
35        Ok(String::from_utf8_lossy(&bytes).to_string())
36    }
37
38    /// Creates a random alphanumeric token of length `len`.
39    pub fn create_token(len: usize) -> String {
40        Alphanumeric.sample_string(&mut rand::rng(), len)
41    }
42
43    /// Creates a random alphanumeric token with a length chosen in `[min, max]`.
44    /// Uses `min` when `max <= min`. `_range`, `_prefix`, and `_alphanum` are ignored.
45    pub fn create_token_range(min: usize, max: usize, _range: usize, _prefix: &str, _alphanum: bool) -> String {
46        let len = if max > min { rand::rng().random_range(min..=max) } else { min };
47        Self::create_token(len)
48    }
49
50    /// Converts a value to `serde_json::Value`, returning `Null` when conversion fails.
51    pub fn to_json<T: Serialize>(v: &T) -> serde_json::Value {
52        serde_json::to_value(v).unwrap_or(serde_json::Value::Null)
53    }
54}