1use crate::prim::EdgedbPrim;
2use crate::EdgedbValue;
3use crate::Result;
4use edgedb_protocol::query_arg::QueryArgs;
5use edgedb_protocol::value::Value;
6
7pub trait EdgedbQueryArgs {
9 type EdgedbArgsType: QueryArgs;
10
11 fn to_query_args(self) -> Result<Self::EdgedbArgsType>;
12}
13
14impl EdgedbQueryArgs for () {
15 type EdgedbArgsType = ();
16
17 fn to_query_args(self) -> Result<Self::EdgedbArgsType> {
18 Ok(self)
19 }
20}
21
22macro_rules! ignore_first {
23 ($a:ident, $b:ident) => {
24 $b
25 };
26}
27
28macro_rules! impl_tuple {
29 ( $count:expr, ($($name:ident,)+), ($($small_name:ident,)+) ) => (
30
31 impl<$($name:EdgedbPrim),+> EdgedbQueryArgs for ($($name,)+) {
32 type EdgedbArgsType = ($(ignore_first!($name, Value),)+);
33
34 fn to_query_args(self) -> Result<Self::EdgedbArgsType> {
35 let ($($small_name,)+) = self;
36
37 Ok(($($small_name.to_edgedb_val()?,)+))
38 }
39 }
40
41 )
42}
43
44impl_tuple! {1, (T0,), (t0,)}
45impl_tuple! {2, (T0, T1,), (t0, t1,)}
46impl_tuple! {3, (T0, T1, T2,), (t0, t1, t2,)}
47impl_tuple! {4, (T0, T1, T2, T3,), (t0, t1, t2, t3,)}
48impl_tuple! {5, (T0, T1, T2, T3, T4,), (t0, t1, t2, t3, t4,)}
49impl_tuple! {6, (T0, T1, T2, T3, T4, T5,), (t0, t1, t2, t3, t4, t5,)}
50
51#[cfg(test)]
52mod test {
53 use serde_json::json;
54
55 use crate::{prim::EdgedbJson, query, value::EdgedbSetValue, EdgedbObject};
56
57 #[derive(Debug, PartialEq)]
58 struct ExamplImplStruct {
59 a: String,
60 b: Option<String>,
61 }
62
63 impl EdgedbObject for ExamplImplStruct {
64 fn from_edgedb_object(
65 shape: edgedb_protocol::codec::ObjectShape,
66 mut fields: Vec<Option<edgedb_protocol::value::Value>>,
67 ) -> anyhow::Result<Self> {
68 let mut a = None;
69 let mut b = None;
70
71 for (i, s) in shape.elements.iter().enumerate() {
72 match s.name.as_str() {
73 "a" => {
74 a = fields[i]
75 .take()
76 .map(EdgedbSetValue::from_edgedb_set_value)
77 .transpose()?;
78 }
79 "b" => {
80 b = fields[i]
81 .take()
82 .map(EdgedbSetValue::from_edgedb_set_value)
83 .transpose()?;
84 }
85 _ => {}
86 }
87 }
88
89 Ok(Self {
90 a: EdgedbSetValue::interpret_possibly_missing_required_value(a)?,
91 b: EdgedbSetValue::interpret_possibly_missing_required_value(b)?,
92 })
93 }
94
95 }
104
105 #[tokio::test]
106 async fn some_queries() -> anyhow::Result<()> {
107 let conn = edgedb_tokio::create_client().await?;
108
109 assert_eq!(
110 query::<ExamplImplStruct, _>(
111 &conn,
112 "select { a := <str>$0, b := <str><int32>$1 }",
113 ("hi".to_owned(), 3)
114 )
115 .await?,
116 ExamplImplStruct {
117 a: "hi".to_string(),
118 b: Some("3".to_string())
119 }
120 );
121
122 assert_eq!(
123 query::<ExamplImplStruct, _>(
124 &conn,
125 "select { a := <str>(<json>$0)['a'], b := <str><int32>(<json>$0)['b'] }",
126 (EdgedbJson(json!({"a": "hello", "b": 3})),)
127 )
128 .await?,
129 ExamplImplStruct {
130 a: "hello".to_string(),
131 b: Some("3".to_string())
132 }
133 );
134
135 Ok(())
136 }
137}