tdm_server_rust/utils/fast_json.rs
1//! simd-json / serde_json 双路径 JSON 工具
2//!
3//! 优先使用 simd-json 加速解析(需 CPU 支持 AVX2 或 aarch64),
4//! 不可用时自动回退到 serde_json。对调用方完全透明。
5//!
6//! ## 性能
7//!
8//! simd-json 在支持 AVX2 的 x86_64 CPU 上可比 serde_json 快 2-3 倍,
9//! 适用于高吞吐 API 响应的序列化热点路径。
10//!
11//! ## 回退策略
12//!
13//! `simd_available()` 运行时检测 CPU 特性,编译时判断目标架构:
14//!
15//! | 架构 | simd-json 可用性 |
16//! |------|-----------------|
17//! | x86_64 + AVX2 | 可用 |
18//! | aarch64 (ARM Mac) | 可用 |
19//! | 其他 | 不可用,回退 serde_json |
20
21use serde::{de::DeserializeOwned, Serialize};
22use thiserror::Error;
23
24/// JSON 序列化/反序列化统一错误类型
25#[derive(Debug, Error)]
26pub enum FastJsonError {
27 /// 底层 simd-json 或 serde_json 的原始错误信息
28 #[error("{0}")]
29 Msg(String),
30}
31
32/// 运行时检测 simd-json 是否可用
33///
34/// x86_64 检测 AVX2 特性,aarch64 始终可用。
35fn simd_available() -> bool {
36 #[cfg(target_arch = "x86_64")]
37 {
38 return std::arch::is_x86_feature_detected!("avx2");
39 }
40 #[cfg(target_arch = "aarch64")]
41 {
42 return true;
43 }
44 #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
45 {
46 false
47 }
48}
49
50/// 将 Rust 值序列化为 JSON 字节数组
51///
52/// 优先使用 simd-json(若 CPU 支持),否则回退 serde_json。
53/// 用于 `ResultBody::into_response()` 等热点路径。
54///
55/// # 参数
56///
57/// - `value`: 任意实现了 `Serialize` 的类型
58///
59/// # 返回值
60///
61/// 成功返回 JSON 字节数组(`Vec<u8>`)。
62///
63/// # Errors
64///
65/// 序列化失败时返回 `FastJsonError::Msg`,包含底层错误描述。
66#[tracing::instrument(name = "json::serialize_response", skip(value), level = "debug")]
67pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, FastJsonError> {
68 if simd_available() {
69 let mut buf = Vec::new();
70 simd_json::serde::to_writer(&mut buf, value).map_err(|e| FastJsonError::Msg(e.to_string()))?;
71 return Ok(buf);
72 }
73 serde_json::to_vec(value).map_err(|e| FastJsonError::Msg(e.to_string()))
74}
75
76/// 从 JSON 字节数组反序列化为 Rust 类型
77///
78/// 优先使用 simd-json(若 CPU 支持),否则回退 serde_json。
79/// 用于 `AppJson` 请求体提取器等场景。
80///
81/// # 参数
82///
83/// - `bytes`: JSON 字节切片
84///
85/// # 返回值
86///
87/// 成功返回反序列化后的目标类型实例。
88///
89/// # Errors
90///
91/// 解析失败时返回 `FastJsonError::Msg`。
92pub fn from_slice<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, FastJsonError> {
93 if simd_available() {
94 let mut buf = bytes.to_vec();
95 return simd_json::serde::from_slice(&mut buf).map_err(|e| FastJsonError::Msg(e.to_string()));
96 }
97 serde_json::from_slice(bytes).map_err(|e| FastJsonError::Msg(e.to_string()))
98}