1use serde::{Deserialize, Serialize};
7use std::fmt;
8use std::sync::Arc;
9
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12#[serde(tag = "type", content = "data")]
13#[non_exhaustive]
14pub enum Value {
15 Tensor {
18 values: Arc<Vec<f64>>,
19 shape: Vec<usize>,
20 },
21
22 Json(Arc<serde_json::Value>),
24
25 Bytes(Arc<Vec<u8>>),
27
28 Object(Arc<Vec<u8>>),
33
34 Empty,
36}
37
38impl Value {
39 pub fn tensor(values: Vec<f64>, shape: Vec<usize>) -> Self {
40 Self::Tensor {
41 values: Arc::new(values),
42 shape,
43 }
44 }
45
46 pub fn json(val: serde_json::Value) -> Self {
47 Self::Json(Arc::new(val))
48 }
49
50 pub fn bytes(data: Vec<u8>) -> Self {
51 Self::Bytes(Arc::new(data))
52 }
53
54 pub fn object(data: Vec<u8>) -> Self {
55 Self::Object(Arc::new(data))
56 }
57
58 pub fn is_empty(&self) -> bool {
59 matches!(self, Self::Empty)
60 }
61
62 pub fn as_tensor(&self) -> Option<(&[f64], &[usize])> {
64 match self {
65 Self::Tensor { values, shape } => Some((values, shape)),
66 _ => None,
67 }
68 }
69
70 pub fn as_json(&self) -> Option<&serde_json::Value> {
72 match self {
73 Self::Json(v) => Some(v),
74 _ => None,
75 }
76 }
77
78 pub fn size(&self) -> usize {
80 match self {
81 Self::Tensor { values, .. } => values.len(),
82 Self::Json(v) => v.to_string().len(),
83 Self::Bytes(b) | Self::Object(b) => b.len(),
84 Self::Empty => 0,
85 }
86 }
87}
88
89impl fmt::Display for Value {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 match self {
92 Self::Tensor { shape, values } => {
93 write!(f, "Tensor(shape={shape:?}, len={})", values.len())
94 }
95 Self::Json(v) => write!(f, "Json({v})"),
96 Self::Bytes(b) => write!(f, "Bytes(len={})", b.len()),
97 Self::Object(b) => write!(f, "Object(len={})", b.len()),
98 Self::Empty => write!(f, "Empty"),
99 }
100 }
101}
102
103impl From<Vec<f64>> for Value {
104 fn from(values: Vec<f64>) -> Self {
105 let len = values.len();
106 Self::Tensor {
107 values: Arc::new(values),
108 shape: vec![len],
109 }
110 }
111}
112
113impl From<serde_json::Value> for Value {
114 fn from(v: serde_json::Value) -> Self {
115 Self::Json(Arc::new(v))
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use serde_json::json;
123
124 #[test]
125 fn tensor_creation_and_access() {
126 let v = Value::tensor(vec![1.0, 2.0, 3.0, 4.0], vec![2, 2]);
127 let (data, shape) = v.as_tensor().unwrap();
128 assert_eq!(data, &[1.0, 2.0, 3.0, 4.0]);
129 assert_eq!(shape, &[2, 2]);
130 }
131
132 #[test]
133 fn json_value() {
134 let v = Value::json(json!({"key": "value"}));
135 let j = v.as_json().unwrap();
136 assert_eq!(j["key"], "value");
137 }
138
139 #[test]
140 fn empty_value() {
141 let v = Value::Empty;
142 assert!(v.is_empty());
143 assert_eq!(v.size(), 0);
144 }
145
146 #[test]
147 fn from_vec_f64() {
148 let v: Value = vec![1.0, 2.0, 3.0].into();
149 let (data, shape) = v.as_tensor().unwrap();
150 assert_eq!(data, &[1.0, 2.0, 3.0]);
151 assert_eq!(shape, &[3]);
152 }
153
154 #[test]
155 fn display_formatting() {
156 let t = Value::tensor(vec![1.0, 2.0], vec![2]);
157 assert_eq!(t.to_string(), "Tensor(shape=[2], len=2)");
158
159 let e = Value::Empty;
160 assert_eq!(e.to_string(), "Empty");
161 }
162
163 #[test]
164 fn serde_roundtrip() {
165 let values = vec![
166 Value::tensor(vec![1.0, 2.0, 3.0], vec![3]),
167 Value::json(json!({"a": 1})),
168 Value::bytes(vec![0xDE, 0xAD]),
169 Value::Empty,
170 ];
171
172 for v in values {
173 let serialized = serde_json::to_string(&v).unwrap();
174 let deserialized: Value = serde_json::from_str(&serialized).unwrap();
175 assert_eq!(v, deserialized);
176 }
177 }
178
179 #[test]
180 fn size_returns_correct_values() {
181 assert_eq!(Value::tensor(vec![1.0; 100], vec![10, 10]).size(), 100);
182 assert_eq!(Value::bytes(vec![0; 50]).size(), 50);
183 assert!(Value::json(json!({"key": "val"})).size() > 0);
184 }
185}