Skip to main content

neon_wasi_http/
deserializer.rs

1use crate::QueryResult;
2use anyhow::{Context, Result};
3use serde::de::DeserializeOwned;
4
5impl QueryResult {
6    pub fn deserialize<T>(&mut self) -> Result<Option<T>>
7    where
8        T: DeserializeOwned,
9    {
10        let Some(row) = self.rows.pop() else {
11            return Ok(None);
12        };
13
14        if self.row_count != 1 {
15            anyhow::bail!("Expected 1 row, got {}", self.row_count);
16        }
17
18        if let serde_json::Value::Object(object_row) = row {
19            if let Some(obj) = object_row.get("jsonb_build_object") {
20                if let Some(json_as_string) = obj.as_str() {
21                    let item: T = serde_json::from_str(json_as_string).context(
22                        "Failed to deserialize the inner JSON string into the target struct",
23                    )?;
24                    return Ok(Some(item));
25                } else {
26                    let res =
27                        serde_json::from_value(obj.clone()).context("Failed to deserialize row")?;
28                    return Ok(Some(res));
29                }
30            }
31        }
32
33        Ok(None)
34    }
35
36    pub fn deserialize_multiple<T>(&mut self) -> Result<Vec<T>>
37    where
38        T: DeserializeOwned,
39    {
40        let mut out: Vec<T> = Vec::new();
41        while let Some(row) = self.rows.pop() {
42            if let serde_json::Value::Object(object_row) = row {
43                if let Some(obj) = object_row.get("jsonb_build_object") {
44                    if let Some(json_as_string) = obj.as_str() {
45                        let item: T = serde_json::from_str(json_as_string).context(
46                            "Failed to deserialize the inner JSON string into the target struct",
47                        )?;
48                        out.push(item);
49                    } else {
50                        out.push(serde_json::from_value(obj.clone()).context(
51                            "Failed to deserialize raw JSON object (the value was not a string)",
52                        )?);
53                    }
54                }
55            }
56        }
57        Ok(out)
58    }
59
60    pub fn deserialize_orm<T>(&mut self) -> Result<Option<T>>
61    where
62        T: DeserializeOwned,
63    {
64        let Some(row) = self.rows.pop() else {
65            return Ok(None);
66        };
67
68        if self.row_count != 1 {
69            anyhow::bail!("Expected 1 row, got {}", self.row_count);
70        }
71
72        if let serde_json::Value::Object(object_row) = row {
73            if let Some(obj) = object_row.get("jsonb_build_object") {
74                if let Some(json_as_string) = obj.as_str() {
75                    let item: T = serde_json::from_str(json_as_string).context(
76                        "Failed to deserialize the inner JSON string into the target struct",
77                    )?;
78                    return Ok(Some(item));
79                } else {
80                    let res =
81                        serde_json::from_value(obj.clone()).context("Failed to deserialize row")?;
82                    return Ok(Some(res));
83                }
84            }
85        }
86
87        Ok(None)
88    }
89
90    pub fn deserialize_multiple_orm<T>(&mut self) -> Result<Vec<T>>
91    where
92        T: DeserializeOwned,
93    {
94        let mut out: Vec<T> = Vec::new();
95        while let Some(row) = self.rows.pop() {
96            if let serde_json::Value::Object(object_row) = row {
97                if let Some(obj) = object_row.get("jsonb_build_object") {
98                    if let Some(json_as_string) = obj.as_str() {
99                        let item: T = serde_json::from_str(json_as_string).context(
100                            "Failed to deserialize the inner JSON string into the target struct",
101                        )?;
102                        out.push(item);
103                    } else {
104                        out.push(serde_json::from_value(obj.clone()).context(
105                            "Failed to deserialize raw JSON object (the value was not a string)",
106                        )?);
107                    }
108                }
109            }
110        }
111
112        Ok(out)
113    }
114}