1use alloc::string::{String, ToString};
17use alloc::vec::Vec;
18use core::hash::{Hash, Hasher};
19
20use super::varint::encode_varint_simple;
21
22#[derive(Debug, Clone)]
24pub enum Value<S, B> {
25 Null,
27 Integer(i64),
29 Real(f64),
31 Text(S),
33 Blob(B),
35}
36
37impl<S: Copy, B: Copy> Copy for Value<S, B> {}
38
39pub(crate) type MaybeValue<S, B> = Option<Value<S, B>>;
42
43impl<S: AsRef<str> + PartialEq, B: AsRef<[u8]> + PartialEq> PartialEq for Value<S, B> {
45 fn eq(&self, other: &Self) -> bool {
46 match (self, other) {
47 (Value::Integer(a), Value::Integer(b)) => a == b,
48 (Value::Real(a), Value::Real(b)) => a.to_bits() == b.to_bits(),
49 (Value::Text(a), Value::Text(b)) => a == b,
50 (Value::Blob(a), Value::Blob(b)) => a == b,
51 (Value::Null, Value::Null) => true,
52 _ => false,
53 }
54 }
55}
56
57impl<S: AsRef<str> + Eq, B: AsRef<[u8]> + Eq> Eq for Value<S, B> {}
58
59impl<S: AsRef<str> + Hash, B: AsRef<[u8]> + Hash> Hash for Value<S, B> {
60 fn hash<H: Hasher>(&self, state: &mut H) {
61 core::mem::discriminant(self).hash(state);
62 match self {
63 Value::Integer(v) => v.hash(state),
64 Value::Real(v) => v.to_bits().hash(state),
65 Value::Text(v) => v.hash(state),
66 Value::Blob(v) => v.hash(state),
67 Value::Null => {}
68 }
69 }
70}
71
72impl<S: AsRef<str>, B: AsRef<[u8]>> From<i64> for Value<S, B> {
74 #[inline]
75 fn from(v: i64) -> Self {
76 Value::Integer(v)
77 }
78}
79
80impl<S: AsRef<str>, B: AsRef<[u8]>> From<i32> for Value<S, B> {
81 #[inline]
82 fn from(v: i32) -> Self {
83 Value::Integer(i64::from(v))
84 }
85}
86
87impl<B: AsRef<[u8]>> From<String> for Value<String, B> {
88 #[inline]
89 fn from(v: String) -> Self {
90 Value::Text(v)
91 }
92}
93
94impl<B: AsRef<[u8]>> From<&str> for Value<String, B> {
95 #[inline]
96 fn from(v: &str) -> Self {
97 Value::Text(v.to_string())
98 }
99}
100
101impl<S: AsRef<str>, B: AsRef<[u8]>> From<f64> for Value<S, B> {
102 #[inline]
103 fn from(v: f64) -> Self {
104 Value::Real(v)
105 }
106}
107
108impl<S: AsRef<str>> From<Vec<u8>> for Value<S, Vec<u8>> {
109 fn from(v: Vec<u8>) -> Self {
110 Value::Blob(v)
111 }
112}
113
114impl<S: AsRef<str>> From<&[u8]> for Value<S, Vec<u8>> {
115 fn from(v: &[u8]) -> Self {
116 Value::Blob(v.to_vec())
117 }
118}
119
120impl<T: Into<Value<String, Vec<u8>>>> From<Option<T>> for Value<String, Vec<u8>> {
121 fn from(opt: Option<T>) -> Self {
122 match opt {
123 Some(v) => v.into(),
124 None => Value::Null,
125 }
126 }
127}
128
129impl<S: AsRef<str>, B: AsRef<[u8]>> Value<S, B> {
130 pub fn to_owned(&self) -> Value<String, Vec<u8>> {
132 match self {
133 Value::Null => Value::Null,
134 Value::Integer(v) => Value::Integer(*v),
135 Value::Real(v) => Value::Real(*v),
136 Value::Text(s) => Value::Text(s.as_ref().to_string()),
137 Value::Blob(b) => Value::Blob(b.as_ref().to_vec()),
138 }
139 }
140
141 pub fn as_ref(&self) -> Value<&str, &[u8]> {
143 match self {
144 Value::Null => Value::Null,
145 Value::Integer(v) => Value::Integer(*v),
146 Value::Real(v) => Value::Real(*v),
147 Value::Text(s) => Value::Text(s.as_ref()),
148 Value::Blob(b) => Value::Blob(b.as_ref()),
149 }
150 }
151}
152
153mod display;
154
155#[inline]
159pub(crate) fn encode_undefined(out: &mut Vec<u8>) {
160 out.push(0x00);
161}
162
163pub(crate) fn encode_value<S: AsRef<str>, B: AsRef<[u8]>>(
175 out: &mut Vec<u8>,
176 value: Option<&Value<S, B>>,
177) {
178 match value {
179 None => encode_undefined(out),
180 Some(v) => encode_defined_value(out, v),
181 }
182}
183
184pub(crate) fn encode_defined_value<S: AsRef<str>, B: AsRef<[u8]>>(
186 out: &mut Vec<u8>,
187 value: &Value<S, B>,
188) {
189 match value {
190 Value::Null => {
191 out.push(0x05);
193 }
194 Value::Integer(v) => {
195 out.push(0x01);
197 out.extend(v.to_be_bytes());
198 }
199 Value::Real(v) => {
200 if v.is_nan() {
202 out.push(0x05); } else {
204 out.push(0x02);
207 let normalized = if *v == 0.0 { 0.0 } else { *v };
208 out.extend(normalized.to_be_bytes());
209 }
210 }
211 Value::Text(s) => {
212 let s = s.as_ref();
214 out.push(0x03);
215 out.extend(encode_varint_simple(s.len() as u64));
216 out.extend(s.as_bytes());
217 }
218 Value::Blob(b) => {
219 let b = b.as_ref();
221 out.push(0x04);
222 out.extend(encode_varint_simple(b.len() as u64));
223 out.extend(b);
224 }
225 }
226}
227
228#[must_use]
240pub(crate) fn decode_value(data: &[u8]) -> Option<(MaybeValue<String, Vec<u8>>, usize)> {
241 use super::varint::decode_varint;
242
243 if data.is_empty() {
244 return None;
245 }
246
247 let type_code = data[0];
248 let data = &data[1..];
249
250 match type_code {
251 0 => {
252 Some((None, 1))
254 }
255 1 => {
256 if data.len() < 8 {
258 return None;
259 }
260 let v = i64::from_be_bytes([
261 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
262 ]);
263 Some((Some(Value::Integer(v)), 9))
264 }
265 2 => {
266 if data.len() < 8 {
268 return None;
269 }
270 let v = f64::from_be_bytes([
271 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
272 ]);
273 if v.is_nan() {
276 Some((Some(Value::Null), 9))
277 } else {
278 let normalized = if v == 0.0 { 0.0 } else { v };
280 Some((Some(Value::Real(normalized)), 9))
281 }
282 }
283 3 => {
284 let (len, len_bytes) = decode_varint(data)?;
286 let len = usize::try_from(len).ok()?;
287 let data = &data[len_bytes..];
288 if data.len() < len {
289 return None;
290 }
291 let text = String::from_utf8(data[..len].to_vec()).ok()?;
292 Some((Some(Value::Text(text)), 1 + len_bytes + len))
293 }
294 4 => {
295 let (len, len_bytes) = decode_varint(data)?;
297 let len = usize::try_from(len).ok()?;
298 let data = &data[len_bytes..];
299 if data.len() < len {
300 return None;
301 }
302 Some((Some(Value::Blob(data[..len].to_vec())), 1 + len_bytes + len))
303 }
304 5 => {
305 Some((Some(Value::Null), 1))
307 }
308 _ => None,
309 }
310}
311
312#[cfg(test)]
313mod tests {
314 use super::*;
315 use alloc::vec;
316
317 type TestValue = Value<String, Vec<u8>>;
319
320 #[test]
321 fn test_encode_decode_null() {
322 let mut buf = Vec::new();
323 encode_value(&mut buf, Some(&TestValue::Null));
324 let (decoded, len) = decode_value(&buf).unwrap();
325 assert_eq!(decoded, Some(TestValue::Null));
326 assert_eq!(len, buf.len());
327 }
328
329 #[test]
330 fn test_encode_decode_integers() {
331 for v in [
332 0,
333 1,
334 -1,
335 127,
336 -128,
337 32767,
338 -32768,
339 i64::from(i32::MAX),
340 i64::MAX,
341 ] {
342 let mut buf = Vec::new();
343 encode_value(&mut buf, Some(&TestValue::Integer(v)));
344 let (decoded, len) = decode_value(&buf).unwrap();
345 assert_eq!(decoded, Some(TestValue::Integer(v)), "Failed for {v}");
346 assert_eq!(len, buf.len());
347 assert_eq!(buf.len(), 9, "Integer {v} should be 9 bytes");
349 }
350 }
351
352 #[test]
353 fn test_encode_decode_real() {
354 let mut buf = Vec::new();
355 encode_value(&mut buf, Some(&TestValue::Real(6.14159)));
356 let (decoded, len) = decode_value(&buf).unwrap();
357 assert_eq!(decoded, Some(TestValue::Real(6.14159)));
358 assert_eq!(len, buf.len());
359 assert_eq!(buf.len(), 9);
361 }
362
363 #[test]
364 fn test_encode_decode_text() {
365 let mut buf = Vec::new();
366 let ref_value: Value<&str, &[u8]> = Value::Text("hello");
368 encode_value(&mut buf, Some(&ref_value));
369 let (decoded, len) = decode_value(&buf).unwrap();
370 assert_eq!(decoded, Some(TestValue::Text("hello".to_string())));
371 assert_eq!(len, buf.len());
372 assert_eq!(buf.len(), 7);
374 }
375
376 #[test]
377 fn test_encode_decode_blob() {
378 let mut buf = Vec::new();
379 let data: &[u8] = &[1, 2, 3, 4, 5];
381 let ref_value: Value<&str, &[u8]> = Value::Blob(data);
382 encode_value(&mut buf, Some(&ref_value));
383 let (decoded, len) = decode_value(&buf).unwrap();
384 assert_eq!(decoded, Some(TestValue::Blob(vec![1, 2, 3, 4, 5])));
385 assert_eq!(len, buf.len());
386 assert_eq!(buf.len(), 7);
388 }
389
390 #[test]
391 fn test_encode_decode_undefined() {
392 let mut buf = Vec::new();
393 encode_value::<String, Vec<u8>>(&mut buf, None);
394 let (decoded, len) = decode_value(&buf).unwrap();
395 assert_eq!(decoded, None);
396 assert_eq!(len, buf.len());
397 assert_eq!(buf.len(), 1);
399 }
400
401 #[test]
402 fn test_changeset_encoding_matches_rusqlite() {
403 let mut buf = Vec::new();
407 encode_value(&mut buf, Some(&TestValue::Integer(1)));
408 assert_eq!(
409 buf,
410 vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]
411 );
412
413 let mut buf = Vec::new();
415 encode_value(&mut buf, Some(&TestValue::Integer(100)));
416 assert_eq!(
417 buf,
418 vec![0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64]
419 );
420
421 let mut buf = Vec::new();
424 let ref_value: Value<&str, &[u8]> = Value::Text("alice");
425 encode_value(&mut buf, Some(&ref_value));
426 assert_eq!(buf, vec![0x03, 0x05, b'a', b'l', b'i', b'c', b'e']);
427
428 let mut buf = Vec::new();
430 encode_value(&mut buf, Some(&Value::Null::<&str, &[u8]>));
431 assert_eq!(buf, vec![0x05]);
432 }
433
434 #[test]
435 fn test_cross_type_equality() {
436 let owned: Value<String, Vec<u8>> = Value::Text("hello".to_string());
438 let borrowed: Value<&str, &[u8]> = Value::Text("hello");
439 assert_eq!(owned.as_ref(), borrowed);
440 assert_eq!(borrowed.to_owned(), owned);
441
442 let owned_blob: Value<String, Vec<u8>> = Value::Blob(vec![1, 2, 3]);
443 let data: &[u8] = &[1, 2, 3];
444 let borrowed_blob: Value<&str, &[u8]> = Value::Blob(data);
445 assert_eq!(owned_blob.as_ref(), borrowed_blob);
446 }
447
448 #[test]
449 fn test_to_owned_and_as_ref() {
450 let owned: Value<String, Vec<u8>> = Value::Text("hello".to_string());
451 let borrowed = owned.as_ref();
452 assert_eq!(owned.as_ref(), borrowed);
453
454 let back_to_owned = borrowed.to_owned();
455 assert_eq!(owned, back_to_owned);
456 }
457
458 #[test]
459 fn test_value_from_impls() {
460 type V = Value<String, Vec<u8>>;
461
462 let v: V = 42i64.into();
463 assert_eq!(v, Value::Integer(42));
464
465 let v: V = 7i32.into();
466 assert_eq!(v, Value::Integer(7));
467
468 let v: V = 3.5f64.into();
469 assert_eq!(v, Value::Real(3.5));
470
471 let v: V = "hello".into();
472 assert_eq!(v, Value::Text("hello".into()));
473
474 let v: V = String::from("world").into();
475 assert_eq!(v, Value::Text("world".into()));
476
477 let v: V = vec![1u8, 2, 3].into();
478 assert_eq!(v, Value::Blob(vec![1, 2, 3]));
479
480 let slice: &[u8] = &[4, 5, 6];
481 let v: V = slice.into();
482 assert_eq!(v, Value::Blob(vec![4, 5, 6]));
483
484 let v: V = Some(99i64).into();
485 assert_eq!(v, Value::Integer(99));
486
487 let v: V = None::<i64>.into();
488 assert_eq!(v, Value::Null);
489 }
490}