nodedb_types/json_msgpack/
writer.rs1use zerompk::Write;
12
13use super::instant_ext::InstantKind;
14use super::json_value::JsonValue;
15
16#[inline]
18pub fn json_to_msgpack(value: &serde_json::Value) -> zerompk::Result<Vec<u8>> {
19 zerompk::to_msgpack_vec(&JsonValue(value.clone()))
20}
21
22#[inline]
29pub fn json_to_msgpack_or_empty(value: &serde_json::Value) -> Vec<u8> {
30 json_to_msgpack(value).unwrap_or_else(|_| vec![0x80])
31}
32
33pub fn value_to_msgpack(value: &crate::Value) -> zerompk::Result<Vec<u8>> {
38 zerompk::to_msgpack_vec(&NativeRef(value))
39}
40
41struct NativeRef<'a>(&'a crate::Value);
43
44impl zerompk::ToMessagePack for NativeRef<'_> {
45 fn write<W: Write>(&self, writer: &mut W) -> zerompk::Result<()> {
46 write_native_value(writer, self.0)
47 }
48}
49
50pub(crate) fn write_native_value<W: Write>(
57 writer: &mut W,
58 value: &crate::Value,
59) -> zerompk::Result<()> {
60 match value {
61 crate::Value::Null => writer.write_nil(),
62 crate::Value::Bool(b) => writer.write_boolean(*b),
63 crate::Value::Integer(i) => writer.write_i64(*i),
64 crate::Value::Float(f) => writer.write_f64(*f),
65 crate::Value::String(s)
66 | crate::Value::Uuid(s)
67 | crate::Value::Ulid(s)
68 | crate::Value::Regex(s) => writer.write_string(s),
69 crate::Value::Bytes(b) => writer.write_binary(b),
70 crate::Value::Array(arr) | crate::Value::Set(arr) => {
71 writer.write_array_len(arr.len())?;
72 for v in arr {
73 write_native_value(writer, v)?;
74 }
75 Ok(())
76 }
77 crate::Value::Object(map) => {
78 writer.write_map_len(map.len())?;
79 for (k, v) in map {
80 writer.write_string(k)?;
81 write_native_value(writer, v)?;
82 }
83 Ok(())
84 }
85 crate::Value::DateTime(dt) => write_instant_ext(writer, InstantKind::Utc, dt.micros),
86 crate::Value::NaiveDateTime(dt) => write_instant_ext(writer, InstantKind::Naive, dt.micros),
87 crate::Value::Duration(d) => writer.write_string(&d.to_string()),
88 crate::Value::Decimal(d) => match crate::Value::decimal_as_wide_u64(d) {
89 Some(u) => writer.write_u64(u),
90 None => writer.write_string(&d.to_string()),
91 },
92 crate::Value::Geometry(g) => match sonic_rs::to_string(g) {
93 Ok(s) => writer.write_string(&s),
94 Err(_) => writer.write_nil(),
95 },
96 crate::Value::Range { .. } | crate::Value::Record { .. } => writer.write_nil(),
97 crate::Value::Vector(v) => {
98 writer.write_array_len(v.len())?;
101 for f in v.iter() {
102 writer.write_f64(f64::from(*f))?;
103 }
104 Ok(())
105 }
106 crate::Value::ArrayCell(cell) => {
112 let map_len = if cell.system_time.is_some() { 3 } else { 2 };
113 writer.write_map_len(map_len)?;
114 writer.write_string("coords")?;
115 writer.write_array_len(cell.coords.len())?;
116 for v in &cell.coords {
117 write_native_value(writer, v)?;
118 }
119 writer.write_string("attrs")?;
120 writer.write_array_len(cell.attrs.len())?;
121 for v in &cell.attrs {
122 write_native_value(writer, v)?;
123 }
124 if let Some(ts) = cell.system_time {
125 writer.write_string("_ts_system")?;
126 writer.write_i64(ts)?;
127 }
128 Ok(())
129 }
130 }
131}
132
133fn write_instant_ext<W: Write>(
135 writer: &mut W,
136 kind: InstantKind,
137 micros: i64,
138) -> zerompk::Result<()> {
139 writer.write_ext(kind.ext_type(), µs.to_be_bytes())
140}