Skip to main content

wp_model_core/
raw.rs

1use std::{
2    fmt::{Display, Formatter},
3    sync::Arc,
4};
5
6use bytes::Bytes;
7
8#[derive(Debug, Clone)]
9pub enum RawData {
10    String(String),
11    Bytes(Bytes),
12    ArcBytes(Arc<Vec<u8>>),
13}
14
15impl RawData {
16    pub fn from_string<T: Into<String>>(value: T) -> RawData {
17        RawData::String(value.into())
18    }
19
20    pub fn from_arc_bytes(data: Arc<Vec<u8>>) -> Self {
21        RawData::ArcBytes(data)
22    }
23
24    /// 辅助构造:从 `Arc<[u8]>` 构建。该接口用于兼容旧版(0.4.6 之前)`ArcBytes` 表示,
25    /// 会额外复制一次数据,建议尽快迁移到 `Arc<Vec<u8>>`。
26    pub fn from_arc_slice(data: Arc<[u8]>) -> Self {
27        RawData::ArcBytes(Arc::new(data.as_ref().to_vec()))
28    }
29
30    // 统一的数据访问接口
31    pub fn as_bytes(&self) -> &[u8] {
32        match self {
33            RawData::String(s) => s.as_bytes(),
34            RawData::Bytes(b) => b.as_ref(),
35            RawData::ArcBytes(arc) => arc.as_slice(),
36        }
37    }
38
39    // 向后兼容的 Bytes 转换(仅在需要时,始终复制)
40    pub fn to_bytes(&self) -> Bytes {
41        match self {
42            RawData::String(s) => Bytes::copy_from_slice(s.as_bytes()),
43            RawData::Bytes(b) => b.clone(),
44            RawData::ArcBytes(arc) => Bytes::copy_from_slice(arc.as_slice()),
45        }
46    }
47
48    /// 按需取得 Bytes,消耗自身以在 `String`/`Bytes` 分支复用缓冲区。
49    pub fn into_bytes(self) -> Bytes {
50        match self {
51            RawData::String(s) => Bytes::from(s),
52            RawData::Bytes(b) => b,
53            RawData::ArcBytes(arc) => match Arc::try_unwrap(arc) {
54                Ok(vec) => Bytes::from(vec),
55                Err(shared) => Bytes::copy_from_slice(shared.as_slice()),
56            },
57        }
58    }
59
60    // 零拷贝检测
61    pub fn is_zero_copy(&self) -> bool {
62        matches!(self, RawData::ArcBytes(_))
63    }
64
65    pub fn len(&self) -> usize {
66        self.as_bytes().len()
67    }
68
69    pub fn is_empty(&self) -> bool {
70        match self {
71            RawData::String(value) => value.is_empty(),
72            RawData::Bytes(value) => value.is_empty(),
73            RawData::ArcBytes(arc) => arc.is_empty(),
74        }
75    }
76}
77
78impl Display for RawData {
79    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80        match self {
81            RawData::String(value) => f.write_str(value),
82            // 安全转换:尽量显示为 UTF-8;不可解码时使用替代字符
83            RawData::Bytes(value) => f.write_str(&String::from_utf8_lossy(value)),
84            RawData::ArcBytes(arc) => f.write_str(&String::from_utf8_lossy(arc.as_slice())),
85        }
86    }
87}