nodedb_types/value/
raw_bytes.rs1use crate::value::core::Value;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
15#[error("{kind} has no raw KV body form; only a scalar does")]
16pub struct NotScalar {
17 pub kind: &'static str,
19}
20
21pub fn scalar_to_raw_bytes(value: &Value) -> Result<Vec<u8>, NotScalar> {
29 match value {
30 Value::Null => Ok(Vec::new()),
31 Value::Bool(b) => Ok(b.to_string().into_bytes()),
32 Value::Integer(i) => Ok(i.to_string().into_bytes()),
33 Value::Float(f) => Ok(f.to_string().into_bytes()),
34 Value::Decimal(d) => Ok(d.to_string().into_bytes()),
35 Value::String(s) | Value::Uuid(s) | Value::Ulid(s) => Ok(s.as_bytes().to_vec()),
36 Value::Bytes(b) => Ok(b.clone()),
37 Value::DateTime(dt) | Value::NaiveDateTime(dt) => Ok(dt.to_iso8601().into_bytes()),
38 Value::Duration(_)
39 | Value::Array(_)
40 | Value::Object(_)
41 | Value::Set(_)
42 | Value::Regex(_)
43 | Value::Geometry(_)
44 | Value::Range { .. }
45 | Value::Record { .. }
46 | Value::ArrayCell(_)
47 | Value::Vector(_) => Err(NotScalar {
48 kind: value.type_name(),
49 }),
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use std::collections::HashMap;
57
58 #[test]
59 fn string_is_its_utf8_bytes() {
60 assert_eq!(
61 scalar_to_raw_bytes(&Value::String("v1".into())).unwrap(),
62 b"v1".to_vec()
63 );
64 }
65
66 #[test]
67 fn integer_is_decimal_text() {
68 assert_eq!(
69 scalar_to_raw_bytes(&Value::Integer(-42)).unwrap(),
70 b"-42".to_vec()
71 );
72 }
73
74 #[test]
75 fn bool_and_null() {
76 assert_eq!(
77 scalar_to_raw_bytes(&Value::Bool(true)).unwrap(),
78 b"true".to_vec()
79 );
80 assert!(scalar_to_raw_bytes(&Value::Null).unwrap().is_empty());
81 }
82
83 #[test]
84 fn object_is_not_scalar() {
85 let err = scalar_to_raw_bytes(&Value::Object(HashMap::new())).unwrap_err();
86 assert_eq!(err.kind, Value::Object(HashMap::new()).type_name());
87 }
88}