1#[allow(dead_code)]
2#[rustfmt::skip]
3#[allow(clippy::all)]
4pub mod bindings {
5 use wit_bindgen::generate;
6
7 generate!({
8 world: "row-world",
9 path: "wit",
10 generate_all,
11 });
12}
13
14use std::collections::HashMap;
15
16use anyhow::{Result, Context};
17
18use bindings::sdf::row_state::row::{Dvalue, RowValue};
19use serde::de::DeserializeOwned;
20
21impl Dvalue {
22 fn value(&self) -> Result<serde_json::Value> {
23 use serde_json::Value;
24 let val = match self {
25 Dvalue::String(s) => Value::String(s.clone()),
26 Dvalue::U8(i) => Value::Number((*i).into()),
27 Dvalue::U16(i) => Value::Number((*i).into()),
28 Dvalue::U32(i) => Value::Number((*i).into()),
29 Dvalue::U64(i) => Value::Number((*i).into()),
30 Dvalue::I8(i) => Value::Number((*i).into()),
31 Dvalue::I16(i) => Value::Number((*i).into()),
32 Dvalue::I32(i) => Value::Number((*i).into()),
33 Dvalue::I64(i) => Value::Number((*i).into()),
34 Dvalue::Float32(i) => Value::Number(
35 serde_json::Number::from_f64(*i as f64).context("failed to parse f64")?,
36 ),
37 Dvalue::Float64(i) => {
38 Value::Number(serde_json::Number::from_f64(*i).context("failed to parse f64")?)
39 }
40
41 Dvalue::Bool(i) => Value::Bool(*i),
42 Dvalue::Timestamp(i) => Value::Number((*i).into()),
43 };
44 Ok(val)
45 }
46}
47
48#[derive(Default)]
50pub struct RowSerde;
51
52impl RowSerde {
53 pub fn deserialize_from<T: DeserializeOwned>(row: &RowValue) -> Result<T> {
54 let map_values: HashMap<String, serde_json::Value> = row
55 .get()
56 .into_iter()
57 .map(|(key, value)| value.value().map(|value| (key.replace('-', "_"), value)))
58 .collect::<Result<_>>()?;
59 let value = serde_json::to_value(map_values)?;
60
61 let output: T = serde_json::from_value(value)?;
62 Ok(output)
63 }
64}