1use serde::{Deserialize, Serialize};
8use std::fmt;
9use std::sync::Arc;
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
13#[serde(tag = "type", content = "data")]
14#[non_exhaustive]
15pub enum Value {
16 Tensor {
19 values: Arc<Vec<f64>>,
21 shape: Vec<usize>,
23 },
24
25 Text(Arc<str>),
32
33 Json(Arc<serde_json::Value>),
35
36 Bytes(Arc<Vec<u8>>),
38
39 Object(Arc<Vec<u8>>),
44
45 Empty,
47}
48
49impl Value {
50 pub fn tensor(values: Vec<f64>, shape: Vec<usize>) -> Self {
52 Self::Tensor {
53 values: Arc::new(values),
54 shape,
55 }
56 }
57
58 pub fn text(s: impl AsRef<str>) -> Self {
60 Self::Text(Arc::from(s.as_ref()))
61 }
62
63 pub fn json(val: serde_json::Value) -> Self {
65 Self::Json(Arc::new(val))
66 }
67
68 pub fn bytes(data: Vec<u8>) -> Self {
70 Self::Bytes(Arc::new(data))
71 }
72
73 pub fn object(data: Vec<u8>) -> Self {
75 Self::Object(Arc::new(data))
76 }
77
78 pub fn is_empty(&self) -> bool {
80 matches!(self, Self::Empty)
81 }
82
83 pub fn as_tensor(&self) -> Option<(&[f64], &[usize])> {
85 match self {
86 Self::Tensor { values, shape } => Some((values, shape)),
87 _ => None,
88 }
89 }
90
91 pub fn as_text(&self) -> Option<&str> {
96 match self {
97 Self::Text(s) => Some(s),
98 Self::Json(v) => v.as_str(),
99 _ => None,
100 }
101 }
102
103 pub fn as_json(&self) -> Option<&serde_json::Value> {
105 match self {
106 Self::Json(v) => Some(v),
107 _ => None,
108 }
109 }
110
111 pub fn to_plain_json(&self) -> serde_json::Value {
116 fn nest(values: &[f64], shape: &[usize]) -> serde_json::Value {
117 if shape.len() <= 1 {
118 return serde_json::Value::Array(
119 values.iter().map(|v| serde_json::json!(v)).collect(),
120 );
121 }
122 let rows = shape[0];
123 let row_len: usize = shape[1..].iter().product::<usize>().max(1);
124 serde_json::Value::Array(
125 (0..rows)
126 .map(|r| {
127 let start = r * row_len;
128 let end = (start + row_len).min(values.len());
129 nest(&values[start..end.max(start)], &shape[1..])
130 })
131 .collect(),
132 )
133 }
134 match self {
135 Self::Tensor { values, shape } => nest(values, shape),
136 Self::Text(s) => serde_json::Value::String(s.to_string()),
137 Self::Json(v) => (**v).clone(),
138 Self::Empty => serde_json::Value::Null,
139 other => serde_json::to_value(other).unwrap_or(serde_json::Value::Null),
140 }
141 }
142
143 pub fn type_name(&self) -> &'static str {
148 match self {
149 Self::Tensor { .. } => "Tensor",
150 Self::Text(_) => "Text",
151 Self::Json(_) => "Json",
152 Self::Bytes(_) => "Bytes",
153 Self::Object(_) => "Object",
154 Self::Empty => "Empty",
155 }
156 }
157
158 pub fn size(&self) -> usize {
160 match self {
161 Self::Tensor { values, .. } => values.len(),
162 Self::Text(s) => s.len(),
163 Self::Json(v) => v.to_string().len(),
164 Self::Bytes(b) | Self::Object(b) => b.len(),
165 Self::Empty => 0,
166 }
167 }
168}
169
170impl fmt::Display for Value {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 match self {
173 Self::Tensor { shape, values } => {
174 write!(f, "Tensor(shape={shape:?}, len={})", values.len())
175 }
176 Self::Text(s) => write!(f, "Text(len={})", s.len()),
177 Self::Json(v) => write!(f, "Json({v})"),
178 Self::Bytes(b) => write!(f, "Bytes(len={})", b.len()),
179 Self::Object(b) => write!(f, "Object(len={})", b.len()),
180 Self::Empty => write!(f, "Empty"),
181 }
182 }
183}
184
185impl From<Vec<f64>> for Value {
186 fn from(values: Vec<f64>) -> Self {
187 let len = values.len();
188 Self::Tensor {
189 values: Arc::new(values),
190 shape: vec![len],
191 }
192 }
193}
194
195impl From<serde_json::Value> for Value {
196 fn from(v: serde_json::Value) -> Self {
197 Self::Json(Arc::new(v))
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204 use serde_json::json;
205
206 #[test]
207 fn tensor_creation_and_access() {
208 let v = Value::tensor(vec![1.0, 2.0, 3.0, 4.0], vec![2, 2]);
209 let (data, shape) = v.as_tensor().unwrap();
210 assert_eq!(data, &[1.0, 2.0, 3.0, 4.0]);
211 assert_eq!(shape, &[2, 2]);
212 }
213
214 #[test]
215 fn json_value() {
216 let v = Value::json(json!({"key": "value"}));
217 let j = v.as_json().unwrap();
218 assert_eq!(j["key"], "value");
219 }
220
221 #[test]
222 fn empty_value() {
223 let v = Value::Empty;
224 assert!(v.is_empty());
225 assert_eq!(v.size(), 0);
226 }
227
228 #[test]
229 fn from_vec_f64() {
230 let v: Value = vec![1.0, 2.0, 3.0].into();
231 let (data, shape) = v.as_tensor().unwrap();
232 assert_eq!(data, &[1.0, 2.0, 3.0]);
233 assert_eq!(shape, &[3]);
234 }
235
236 #[test]
237 fn display_formatting() {
238 let t = Value::tensor(vec![1.0, 2.0], vec![2]);
239 assert_eq!(t.to_string(), "Tensor(shape=[2], len=2)");
240
241 let e = Value::Empty;
242 assert_eq!(e.to_string(), "Empty");
243 }
244
245 #[test]
246 fn serde_roundtrip() {
247 let values = vec![
248 Value::tensor(vec![1.0, 2.0, 3.0], vec![3]),
249 Value::json(json!({"a": 1})),
250 Value::bytes(vec![0xDE, 0xAD]),
251 Value::Empty,
252 ];
253
254 for v in values {
255 let serialized = serde_json::to_string(&v).unwrap();
256 let deserialized: Value = serde_json::from_str(&serialized).unwrap();
257 assert_eq!(v, deserialized);
258 }
259 }
260
261 #[test]
262 fn size_returns_correct_values() {
263 assert_eq!(Value::tensor(vec![1.0; 100], vec![10, 10]).size(), 100);
264 assert_eq!(Value::bytes(vec![0; 50]).size(), 50);
265 assert!(Value::json(json!({"key": "val"})).size() > 0);
266 }
267}