1use serde::de::DeserializeOwned;
4use serde_json::Value as JsonValue;
5
6use crate::error::{DuckDbError, DuckDbResult};
7
8pub trait FromDuckDbRow: Sized {
10 fn from_json(json: JsonValue) -> DuckDbResult<Self>;
12}
13
14impl<T: DeserializeOwned> FromDuckDbRow for T {
15 fn from_json(json: JsonValue) -> DuckDbResult<Self> {
16 serde_json::from_value(json)
17 .map_err(|e| DuckDbError::deserialization(format!("Failed to deserialize row: {}", e)))
18 }
19}
20
21pub trait JsonRowExt {
23 fn to_row<T: FromDuckDbRow>(&self) -> DuckDbResult<T>;
25}
26
27impl JsonRowExt for JsonValue {
28 fn to_row<T: FromDuckDbRow>(&self) -> DuckDbResult<T> {
29 T::from_json(self.clone())
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use serde::Deserialize;
37
38 #[derive(Debug, Deserialize, PartialEq)]
39 struct User {
40 id: i64,
41 name: String,
42 }
43
44 #[test]
45 fn test_from_json() {
46 let json = serde_json::json!({
47 "id": 1,
48 "name": "Alice"
49 });
50
51 let user: User = User::from_json(json).unwrap();
52 assert_eq!(user.id, 1);
53 assert_eq!(user.name, "Alice");
54 }
55
56 #[test]
57 fn test_json_row_ext() {
58 let json = serde_json::json!({
59 "id": 2,
60 "name": "Bob"
61 });
62
63 let user: User = json.to_row().unwrap();
64 assert_eq!(user.id, 2);
65 assert_eq!(user.name, "Bob");
66 }
67
68 #[test]
69 fn test_from_json_error() {
70 let json = serde_json::json!({
71 "id": "not a number",
72 "name": "Alice"
73 });
74
75 let result: DuckDbResult<User> = User::from_json(json);
76 assert!(result.is_err());
77 }
78}