titanium_model/
json.rs

1//! JSON serialization abstraction.
2//!
3//! Provides a unified interface for `simd-json` (default) and `serde_json`.
4
5#[cfg(feature = "simd")]
6pub use simd_json::json;
7#[cfg(feature = "simd")]
8pub use simd_json::BorrowedValue;
9#[cfg(feature = "simd")]
10pub use simd_json::Error;
11#[cfg(feature = "simd")]
12pub use simd_json::OwnedValue as Value;
13
14#[cfg(all(not(feature = "simd"), feature = "serde"))]
15pub use serde_json::json;
16#[cfg(all(not(feature = "simd"), feature = "serde"))]
17pub use serde_json::Error;
18#[cfg(all(not(feature = "simd"), feature = "serde"))]
19pub use serde_json::Value;
20
21use serde::de::DeserializeOwned;
22use serde::{Deserialize, Serialize};
23
24#[cfg(feature = "simd")]
25pub fn from_str<T: DeserializeOwned>(json: &str) -> Result<T, Error> {
26    // SIMD-JSON requires mutable access. We clone to ensure safety and compatibility
27    // with immutable generic interfaces, though this incurs a copy cost.
28    // Use `from_mut_str` or `from_string` for zero-copy/in-place performance.
29    let mut buffer = json.as_bytes().to_vec();
30    simd_json::from_slice(&mut buffer)
31}
32
33#[cfg(all(not(feature = "simd"), feature = "serde"))]
34pub fn from_str<T: DeserializeOwned>(json: &str) -> Result<T, Error> {
35    serde_json::from_str(json)
36}
37
38#[cfg(feature = "simd")]
39pub fn to_string<T: Serialize>(value: &T) -> Result<String, Error> {
40    simd_json::to_string(value)
41}
42
43#[cfg(all(not(feature = "simd"), feature = "serde"))]
44pub fn to_string<T: Serialize>(value: &T) -> Result<String, Error> {
45    serde_json::to_string(value)
46}
47
48#[cfg(feature = "simd")]
49pub fn to_value<T: Serialize>(value: T) -> Result<Value, Error> {
50    let mut bytes = simd_json::to_vec(&value)?;
51    simd_json::from_slice(&mut bytes)
52}
53
54#[cfg(feature = "simd")]
55pub fn to_borrowed_value(json: &mut [u8]) -> Result<BorrowedValue<'_>, Error> {
56    simd_json::to_borrowed_value(json)
57}
58
59#[cfg(feature = "simd")]
60pub fn from_value<T: DeserializeOwned>(value: Value) -> Result<T, Error> {
61    T::deserialize(value)
62}
63
64#[cfg(feature = "simd")]
65/// Parse JSON from a mutable slice (Zero-Copy).
66///
67/// This modifies the input buffer in-place to avoid allocations.
68pub fn from_slice_mut<'a, T: Deserialize<'a>>(json: &'a mut [u8]) -> Result<T, Error> {
69    simd_json::from_slice(json)
70}
71
72#[cfg(feature = "simd")]
73pub fn from_borrowed_value<'a, T: Deserialize<'a>>(value: BorrowedValue<'a>) -> Result<T, Error> {
74    T::deserialize(value)
75}
76
77#[cfg(all(not(feature = "simd"), feature = "serde"))]
78pub fn to_value<T: Serialize>(value: T) -> Result<Value, Error> {
79    serde_json::to_value(value)
80}
81
82#[cfg(all(not(feature = "simd"), feature = "serde"))]
83pub fn from_slice_mut<T: DeserializeOwned>(json: &mut [u8]) -> Result<T, Error> {
84    serde_json::from_slice(json)
85}