edgedb_sdk/
client.rs

1//! Client to the EdgeDB
2//!
3//! This is a major way to contact the database. Database credentials always
4//! come preconfigured to connect to the specific database that this WebAssembly
5//! file was run from.
6use std::collections::HashMap;
7use std::sync::Arc;
8
9use bytes::Bytes;
10
11pub use edgedb_errors::{self as errors, Error, ErrorKind};
12pub use edgedb_protocol::QueryResult;
13pub use edgedb_protocol::common::Cardinality;
14pub use edgedb_protocol::features::ProtocolVersion;
15pub use edgedb_protocol::query_arg::{QueryArgs, Encoder};
16pub use edgedb_protocol::server_message::CommandDataDescription;
17use edgedb_errors::{ClientError, ProtocolEncodingError, NoResultExpected};
18use edgedb_errors::{NoDataError};
19use edgedb_protocol::model::Json;
20
21use bytes::BytesMut;
22
23#[allow(dead_code)]
24#[allow(unused_parens)]
25// wit_bindgen_rust::import!("../wit/edgedb-client-v1.wit");
26mod edgedb_client_v1 {
27  #[repr(u8)]
28  #[derive(Clone, Copy, PartialEq, Eq)]
29  pub enum IoFormat{
30    Binary,
31    Json,
32    JsonElements,
33  }
34  impl std::fmt::Debug for IoFormat {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36      match self {
37        IoFormat::Binary => {
38          f.debug_tuple("IoFormat::Binary").finish()
39        }
40        IoFormat::Json => {
41          f.debug_tuple("IoFormat::Json").finish()
42        }
43        IoFormat::JsonElements => {
44          f.debug_tuple("IoFormat::JsonElements").finish()
45        }
46      }
47    }
48  }
49  #[repr(u8)]
50  #[derive(Clone, Copy, PartialEq, Eq)]
51  pub enum Cardinality{
52    NoResult,
53    AtMostOne,
54    One,
55    Many,
56    AtLeastOne,
57  }
58  impl std::fmt::Debug for Cardinality {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60      match self {
61        Cardinality::NoResult => {
62          f.debug_tuple("Cardinality::NoResult").finish()
63        }
64        Cardinality::AtMostOne => {
65          f.debug_tuple("Cardinality::AtMostOne").finish()
66        }
67        Cardinality::One => {
68          f.debug_tuple("Cardinality::One").finish()
69        }
70        Cardinality::Many => {
71          f.debug_tuple("Cardinality::Many").finish()
72        }
73        Cardinality::AtLeastOne => {
74          f.debug_tuple("Cardinality::AtLeastOne").finish()
75        }
76      }
77    }
78  }
79  #[derive(Clone)]
80  pub struct Error {
81    pub code: u32,
82    pub messages: Vec<String>,
83    pub error: Option<String>,
84    pub headers: Vec<(u16,Vec<u8>,)>,
85  }
86  impl std::fmt::Debug for Error {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88      f.debug_struct("Error").field("code", &self.code).field("messages", &self.messages).field("error", &self.error).field("headers", &self.headers).finish()}
89  }
90  bitflags::bitflags! {
91    pub struct Capabilities: u8 {
92      const MODIFICATIONS = 1 << 0;
93      const SESSION_CONFIG = 1 << 1;
94      const TRANSACTION = 1 << 2;
95      const DDL = 1 << 3;
96      const PERSISTENT_CONFIG = 1 << 4;
97    }
98  }
99  impl Capabilities {
100        /// Convert from a raw integer, preserving any unknown bits. See
101        /// <https://github.com/bitflags/bitflags/issues/263#issuecomment-957088321>
102        pub fn from_bits_preserve(bits: u8) -> Self {
103              Self { bits }
104        }
105  }
106  impl crate::bindgen::AsI32 for Capabilities {
107        #[inline]    fn as_i32(self) -> i32 {
108              self.bits() as i32
109        }}
110  #[repr(C)]
111  #[derive(Copy, Clone)]
112  pub struct CompilationFlags {
113    pub implicit_limit: Option<u64>,
114    pub implicit_typenames: bool,
115    pub implicit_typeids: bool,
116    pub allow_capabilities: Capabilities,
117    pub explicit_objectids: bool,
118    pub io_format: IoFormat,
119    pub expected_cardinality: Cardinality,
120  }
121  impl std::fmt::Debug for CompilationFlags {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123      f.debug_struct("CompilationFlags").field("implicit-limit", &self.implicit_limit).field("implicit-typenames", &self.implicit_typenames).field("implicit-typeids", &self.implicit_typeids).field("allow-capabilities", &self.allow_capabilities).field("explicit-objectids", &self.explicit_objectids).field("io-format", &self.io_format).field("expected-cardinality", &self.expected_cardinality).finish()}
124  }
125  #[derive(Clone)]
126  pub struct PrepareComplete {
127    pub capabilities: Capabilities,
128    pub cardinality: Cardinality,
129    pub input_typedesc_id: String,
130    pub output_typedesc_id: String,
131  }
132  impl std::fmt::Debug for PrepareComplete {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134      f.debug_struct("PrepareComplete").field("capabilities", &self.capabilities).field("cardinality", &self.cardinality).field("input-typedesc-id", &self.input_typedesc_id).field("output-typedesc-id", &self.output_typedesc_id).finish()}
135  }
136  #[derive(Clone)]
137  pub struct DataDescription {
138    pub proto: (u16,u16,),
139    pub result_cardinality: Cardinality,
140    pub input_typedesc_id: String,
141    pub input_typedesc: Vec<u8>,
142    pub output_typedesc_id: String,
143    pub output_typedesc: Vec<u8>,
144  }
145  impl std::fmt::Debug for DataDescription {
146    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147      f.debug_struct("DataDescription").field("proto", &self.proto).field("result-cardinality", &self.result_cardinality).field("input-typedesc-id", &self.input_typedesc_id).field("input-typedesc", &self.input_typedesc).field("output-typedesc-id", &self.output_typedesc_id).field("output-typedesc", &self.output_typedesc).finish()}
148  }
149  #[derive(Clone)]
150  pub struct Data {
151    pub chunks: Vec<Vec<u8>>,
152  }
153  impl std::fmt::Debug for Data {
154    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155      f.debug_struct("Data").field("chunks", &self.chunks).finish()}
156  }
157  #[derive(Debug)]
158  #[repr(transparent)]
159  pub struct Query(i32);
160  impl Query{
161    pub unsafe fn from_raw(raw: i32) -> Self {
162      Self(raw)
163    }
164    
165    pub fn into_raw(self) -> i32 {
166      let ret = self.0;
167      core::mem::forget(self);
168      return ret;
169    }
170    
171    pub fn as_raw(&self) -> i32 {
172      self.0
173    }
174  }
175  impl Drop for Query{
176    fn drop(&mut self) {
177      #[link(wasm_import_module = "canonical_abi")]
178      extern "C" {
179        #[link_name = "resource_drop_query"]
180        fn close(fd: i32);
181      }
182      unsafe {
183        close(self.0);
184      }
185    }
186  }
187  impl Clone for Query{
188    fn clone(&self) -> Self {
189      #[link(wasm_import_module = "canonical_abi")]
190      extern "C" {
191        #[link_name = "resource_clone_query"]
192        fn clone(val: i32) -> i32;
193      }
194      unsafe {
195        Self(clone(self.0))
196      }
197    }
198  }
199  #[derive(Debug)]
200  #[repr(transparent)]
201  pub struct Client(i32);
202  impl Client{
203    pub unsafe fn from_raw(raw: i32) -> Self {
204      Self(raw)
205    }
206    
207    pub fn into_raw(self) -> i32 {
208      let ret = self.0;
209      core::mem::forget(self);
210      return ret;
211    }
212    
213    pub fn as_raw(&self) -> i32 {
214      self.0
215    }
216  }
217  impl Drop for Client{
218    fn drop(&mut self) {
219      #[link(wasm_import_module = "canonical_abi")]
220      extern "C" {
221        #[link_name = "resource_drop_client"]
222        fn close(fd: i32);
223      }
224      unsafe {
225        close(self.0);
226      }
227    }
228  }
229  impl Clone for Client{
230    fn clone(&self) -> Self {
231      #[link(wasm_import_module = "canonical_abi")]
232      extern "C" {
233        #[link_name = "resource_clone_client"]
234        fn clone(val: i32) -> i32;
235      }
236      unsafe {
237        Self(clone(self.0))
238      }
239    }
240  }
241  #[derive(Debug)]
242  #[repr(transparent)]
243  pub struct Transaction(i32);
244  impl Transaction{
245    pub unsafe fn from_raw(raw: i32) -> Self {
246      Self(raw)
247    }
248    
249    pub fn into_raw(self) -> i32 {
250      let ret = self.0;
251      core::mem::forget(self);
252      return ret;
253    }
254    
255    pub fn as_raw(&self) -> i32 {
256      self.0
257    }
258  }
259  impl Drop for Transaction{
260    fn drop(&mut self) {
261      #[link(wasm_import_module = "canonical_abi")]
262      extern "C" {
263        #[link_name = "resource_drop_transaction"]
264        fn close(fd: i32);
265      }
266      unsafe {
267        close(self.0);
268      }
269    }
270  }
271  impl Clone for Transaction{
272    fn clone(&self) -> Self {
273      #[link(wasm_import_module = "canonical_abi")]
274      extern "C" {
275        #[link_name = "resource_clone_transaction"]
276        fn clone(val: i32) -> i32;
277      }
278      unsafe {
279        Self(clone(self.0))
280      }
281    }
282  }
283  impl Query {
284    pub fn describe_data(&self,) -> Result<DataDescription,Error>{
285      unsafe {
286        let ptr0 = RET_AREA.as_mut_ptr() as i32;
287        #[link(wasm_import_module = "edgedb-client-v1")]
288        extern "C" {
289          #[cfg_attr(target_arch = "wasm32", link_name = "query::describe-data")]
290          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_query::describe-data")]
291          fn wit_import(_: i32, _: i32, );
292        }
293        wit_import(self.0, ptr0);
294        match *((ptr0 + 0) as *const i32) {
295          0 => Ok({
296            let len1 = *((ptr0 + 40) as *const i32) as usize;
297            let len2 = *((ptr0 + 56) as *const i32) as usize;
298            let len3 = *((ptr0 + 72) as *const i32) as usize;
299            let len4 = *((ptr0 + 88) as *const i32) as usize;
300            
301            DataDescription{proto:(*((ptr0 + 8) as *const i32) as u16, *((ptr0 + 16) as *const i32) as u16), result_cardinality:match *((ptr0 + 24) as *const i32) {
302              0 => Cardinality::NoResult,
303              1 => Cardinality::AtMostOne,
304              2 => Cardinality::One,
305              3 => Cardinality::Many,
306              4 => Cardinality::AtLeastOne,
307              _ => panic!("invalid enum discriminant"),
308            }, input_typedesc_id:String::from_utf8(Vec::from_raw_parts(*((ptr0 + 32) as *const i32) as *mut _, len1, len1)).unwrap(), input_typedesc:Vec::from_raw_parts(*((ptr0 + 48) as *const i32) as *mut _, len2, len2), output_typedesc_id:String::from_utf8(Vec::from_raw_parts(*((ptr0 + 64) as *const i32) as *mut _, len3, len3)).unwrap(), output_typedesc:Vec::from_raw_parts(*((ptr0 + 80) as *const i32) as *mut _, len4, len4), }
309          }),
310          1 => Err({
311            let base6 = *((ptr0 + 16) as *const i32);
312            let len6 = *((ptr0 + 24) as *const i32);
313            let mut result6 = Vec::with_capacity(len6 as usize);
314            for i in 0..len6 {
315              let base = base6 + i *8;
316              result6.push({
317                let len5 = *((base + 4) as *const i32) as usize;
318                
319                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len5, len5)).unwrap()
320              });
321            }
322            std::alloc::dealloc(
323            base6 as *mut _,
324            std::alloc::Layout::from_size_align_unchecked(
325            (len6 as usize) * 8,
326            4,
327            ),
328            );
329            let base9 = *((ptr0 + 56) as *const i32);
330            let len9 = *((ptr0 + 64) as *const i32);
331            let mut result9 = Vec::with_capacity(len9 as usize);
332            for i in 0..len9 {
333              let base = base9 + i *12;
334              result9.push({
335                let len8 = *((base + 8) as *const i32) as usize;
336                
337                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len8, len8))
338              });
339            }
340            std::alloc::dealloc(
341            base9 as *mut _,
342            std::alloc::Layout::from_size_align_unchecked(
343            (len9 as usize) * 12,
344            4,
345            ),
346            );
347            
348            Error{code:*((ptr0 + 8) as *const i32) as u32, messages:result6, error:match *((ptr0 + 32) as *const i32) {
349              0 => None,
350              1 => Some({
351                let len7 = *((ptr0 + 48) as *const i32) as usize;
352                
353                String::from_utf8(Vec::from_raw_parts(*((ptr0 + 40) as *const i32) as *mut _, len7, len7)).unwrap()
354              }),
355              _ => panic!("invalid enum discriminant"),
356            }, headers:result9, }
357          }),
358          _ => panic!("invalid enum discriminant"),
359        }
360      }
361    }
362  }
363  impl Query {
364    pub fn execute(&self,arguments: &[u8],) -> Result<Data,Error>{
365      unsafe {
366        let vec0 = arguments;
367        let ptr0 = vec0.as_ptr() as i32;
368        let len0 = vec0.len() as i32;
369        let ptr1 = RET_AREA.as_mut_ptr() as i32;
370        #[link(wasm_import_module = "edgedb-client-v1")]
371        extern "C" {
372          #[cfg_attr(target_arch = "wasm32", link_name = "query::execute")]
373          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_query::execute")]
374          fn wit_import(_: i32, _: i32, _: i32, _: i32, );
375        }
376        wit_import(self.0, ptr0, len0, ptr1);
377        match *((ptr1 + 0) as *const i32) {
378          0 => Ok({
379            let base3 = *((ptr1 + 8) as *const i32);
380            let len3 = *((ptr1 + 16) as *const i32);
381            let mut result3 = Vec::with_capacity(len3 as usize);
382            for i in 0..len3 {
383              let base = base3 + i *8;
384              result3.push({
385                let len2 = *((base + 4) as *const i32) as usize;
386                
387                Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len2, len2)
388              });
389            }
390            std::alloc::dealloc(
391            base3 as *mut _,
392            std::alloc::Layout::from_size_align_unchecked(
393            (len3 as usize) * 8,
394            4,
395            ),
396            );
397            
398            Data{chunks:result3, }
399          }),
400          1 => Err({
401            let base5 = *((ptr1 + 16) as *const i32);
402            let len5 = *((ptr1 + 24) as *const i32);
403            let mut result5 = Vec::with_capacity(len5 as usize);
404            for i in 0..len5 {
405              let base = base5 + i *8;
406              result5.push({
407                let len4 = *((base + 4) as *const i32) as usize;
408                
409                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len4, len4)).unwrap()
410              });
411            }
412            std::alloc::dealloc(
413            base5 as *mut _,
414            std::alloc::Layout::from_size_align_unchecked(
415            (len5 as usize) * 8,
416            4,
417            ),
418            );
419            let base8 = *((ptr1 + 56) as *const i32);
420            let len8 = *((ptr1 + 64) as *const i32);
421            let mut result8 = Vec::with_capacity(len8 as usize);
422            for i in 0..len8 {
423              let base = base8 + i *12;
424              result8.push({
425                let len7 = *((base + 8) as *const i32) as usize;
426                
427                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len7, len7))
428              });
429            }
430            std::alloc::dealloc(
431            base8 as *mut _,
432            std::alloc::Layout::from_size_align_unchecked(
433            (len8 as usize) * 12,
434            4,
435            ),
436            );
437            
438            Error{code:*((ptr1 + 8) as *const i32) as u32, messages:result5, error:match *((ptr1 + 32) as *const i32) {
439              0 => None,
440              1 => Some({
441                let len6 = *((ptr1 + 48) as *const i32) as usize;
442                
443                String::from_utf8(Vec::from_raw_parts(*((ptr1 + 40) as *const i32) as *mut _, len6, len6)).unwrap()
444              }),
445              _ => panic!("invalid enum discriminant"),
446            }, headers:result8, }
447          }),
448          _ => panic!("invalid enum discriminant"),
449        }
450      }
451    }
452  }
453  impl Client {
454    pub fn connect() -> Client{
455      unsafe {
456        #[link(wasm_import_module = "edgedb-client-v1")]
457        extern "C" {
458          #[cfg_attr(target_arch = "wasm32", link_name = "client::connect")]
459          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_client::connect")]
460          fn wit_import() -> i32;
461        }
462        let ret = wit_import();
463        Client(ret)
464      }
465    }
466  }
467  impl Client {
468    pub fn transaction(&self,) -> Result<Transaction,Error>{
469      unsafe {
470        let ptr0 = RET_AREA.as_mut_ptr() as i32;
471        #[link(wasm_import_module = "edgedb-client-v1")]
472        extern "C" {
473          #[cfg_attr(target_arch = "wasm32", link_name = "client::transaction")]
474          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_client::transaction")]
475          fn wit_import(_: i32, _: i32, );
476        }
477        wit_import(self.0, ptr0);
478        match *((ptr0 + 0) as *const i32) {
479          0 => Ok(Transaction(*((ptr0 + 8) as *const i32))),
480          1 => Err({
481            let base2 = *((ptr0 + 16) as *const i32);
482            let len2 = *((ptr0 + 24) as *const i32);
483            let mut result2 = Vec::with_capacity(len2 as usize);
484            for i in 0..len2 {
485              let base = base2 + i *8;
486              result2.push({
487                let len1 = *((base + 4) as *const i32) as usize;
488                
489                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len1, len1)).unwrap()
490              });
491            }
492            std::alloc::dealloc(
493            base2 as *mut _,
494            std::alloc::Layout::from_size_align_unchecked(
495            (len2 as usize) * 8,
496            4,
497            ),
498            );
499            let base5 = *((ptr0 + 56) as *const i32);
500            let len5 = *((ptr0 + 64) as *const i32);
501            let mut result5 = Vec::with_capacity(len5 as usize);
502            for i in 0..len5 {
503              let base = base5 + i *12;
504              result5.push({
505                let len4 = *((base + 8) as *const i32) as usize;
506                
507                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len4, len4))
508              });
509            }
510            std::alloc::dealloc(
511            base5 as *mut _,
512            std::alloc::Layout::from_size_align_unchecked(
513            (len5 as usize) * 12,
514            4,
515            ),
516            );
517            
518            Error{code:*((ptr0 + 8) as *const i32) as u32, messages:result2, error:match *((ptr0 + 32) as *const i32) {
519              0 => None,
520              1 => Some({
521                let len3 = *((ptr0 + 48) as *const i32) as usize;
522                
523                String::from_utf8(Vec::from_raw_parts(*((ptr0 + 40) as *const i32) as *mut _, len3, len3)).unwrap()
524              }),
525              _ => panic!("invalid enum discriminant"),
526            }, headers:result5, }
527          }),
528          _ => panic!("invalid enum discriminant"),
529        }
530      }
531    }
532  }
533  impl Client {
534    pub fn prepare(&self,compilation_flags: CompilationFlags,query: & str,) -> Result<(Query,PrepareComplete,),Error>{
535      unsafe {
536        let CompilationFlags{ implicit_limit:implicit_limit0, implicit_typenames:implicit_typenames0, implicit_typeids:implicit_typeids0, allow_capabilities:allow_capabilities0, explicit_objectids:explicit_objectids0, io_format:io_format0, expected_cardinality:expected_cardinality0, } = compilation_flags;
537        let (result1_0,result1_1,) = match implicit_limit0{
538          None => { (0i32, 0i64)}
539          Some(e) => { (1i32, crate::bindgen::as_i64(e))}
540        };
541        let flags2 = allow_capabilities0;
542        let vec3 = query;
543        let ptr3 = vec3.as_ptr() as i32;
544        let len3 = vec3.len() as i32;
545        let ptr4 = RET_AREA.as_mut_ptr() as i32;
546        #[link(wasm_import_module = "edgedb-client-v1")]
547        extern "C" {
548          #[cfg_attr(target_arch = "wasm32", link_name = "client::prepare")]
549          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_client::prepare")]
550          fn wit_import(_: i32, _: i32, _: i64, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, );
551        }
552        wit_import(self.0, result1_0, result1_1, match implicit_typenames0 { true => 1, false => 0 }, match implicit_typeids0 { true => 1, false => 0 }, (flags2.bits() >> 0) as i32, match explicit_objectids0 { true => 1, false => 0 }, io_format0 as i32, expected_cardinality0 as i32, ptr3, len3, ptr4);
553        match *((ptr4 + 0) as *const i32) {
554          0 => Ok({
555            let len5 = *((ptr4 + 40) as *const i32) as usize;
556            let len6 = *((ptr4 + 56) as *const i32) as usize;
557            
558            (Query(*((ptr4 + 8) as *const i32)), PrepareComplete{capabilities:Capabilities::empty() | Capabilities::from_bits_preserve(((*((ptr4 + 16) as *const i32) as u32) << 0) as _), cardinality:match *((ptr4 + 24) as *const i32) {
559              0 => Cardinality::NoResult,
560              1 => Cardinality::AtMostOne,
561              2 => Cardinality::One,
562              3 => Cardinality::Many,
563              4 => Cardinality::AtLeastOne,
564              _ => panic!("invalid enum discriminant"),
565            }, input_typedesc_id:String::from_utf8(Vec::from_raw_parts(*((ptr4 + 32) as *const i32) as *mut _, len5, len5)).unwrap(), output_typedesc_id:String::from_utf8(Vec::from_raw_parts(*((ptr4 + 48) as *const i32) as *mut _, len6, len6)).unwrap(), })
566          }),
567          1 => Err({
568            let base8 = *((ptr4 + 16) as *const i32);
569            let len8 = *((ptr4 + 24) as *const i32);
570            let mut result8 = Vec::with_capacity(len8 as usize);
571            for i in 0..len8 {
572              let base = base8 + i *8;
573              result8.push({
574                let len7 = *((base + 4) as *const i32) as usize;
575                
576                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len7, len7)).unwrap()
577              });
578            }
579            std::alloc::dealloc(
580            base8 as *mut _,
581            std::alloc::Layout::from_size_align_unchecked(
582            (len8 as usize) * 8,
583            4,
584            ),
585            );
586            let base11 = *((ptr4 + 56) as *const i32);
587            let len11 = *((ptr4 + 64) as *const i32);
588            let mut result11 = Vec::with_capacity(len11 as usize);
589            for i in 0..len11 {
590              let base = base11 + i *12;
591              result11.push({
592                let len10 = *((base + 8) as *const i32) as usize;
593                
594                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len10, len10))
595              });
596            }
597            std::alloc::dealloc(
598            base11 as *mut _,
599            std::alloc::Layout::from_size_align_unchecked(
600            (len11 as usize) * 12,
601            4,
602            ),
603            );
604            
605            Error{code:*((ptr4 + 8) as *const i32) as u32, messages:result8, error:match *((ptr4 + 32) as *const i32) {
606              0 => None,
607              1 => Some({
608                let len9 = *((ptr4 + 48) as *const i32) as usize;
609                
610                String::from_utf8(Vec::from_raw_parts(*((ptr4 + 40) as *const i32) as *mut _, len9, len9)).unwrap()
611              }),
612              _ => panic!("invalid enum discriminant"),
613            }, headers:result11, }
614          }),
615          _ => panic!("invalid enum discriminant"),
616        }
617      }
618    }
619  }
620  impl Transaction {
621    pub fn prepare(&self,compilation_flags: CompilationFlags,query: & str,) -> Result<(Query,PrepareComplete,),Error>{
622      unsafe {
623        let CompilationFlags{ implicit_limit:implicit_limit0, implicit_typenames:implicit_typenames0, implicit_typeids:implicit_typeids0, allow_capabilities:allow_capabilities0, explicit_objectids:explicit_objectids0, io_format:io_format0, expected_cardinality:expected_cardinality0, } = compilation_flags;
624        let (result1_0,result1_1,) = match implicit_limit0{
625          None => { (0i32, 0i64)}
626          Some(e) => { (1i32, crate::bindgen::as_i64(e))}
627        };
628        let flags2 = allow_capabilities0;
629        let vec3 = query;
630        let ptr3 = vec3.as_ptr() as i32;
631        let len3 = vec3.len() as i32;
632        let ptr4 = RET_AREA.as_mut_ptr() as i32;
633        #[link(wasm_import_module = "edgedb-client-v1")]
634        extern "C" {
635          #[cfg_attr(target_arch = "wasm32", link_name = "transaction::prepare")]
636          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_transaction::prepare")]
637          fn wit_import(_: i32, _: i32, _: i64, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, _: i32, );
638        }
639        wit_import(self.0, result1_0, result1_1, match implicit_typenames0 { true => 1, false => 0 }, match implicit_typeids0 { true => 1, false => 0 }, (flags2.bits() >> 0) as i32, match explicit_objectids0 { true => 1, false => 0 }, io_format0 as i32, expected_cardinality0 as i32, ptr3, len3, ptr4);
640        match *((ptr4 + 0) as *const i32) {
641          0 => Ok({
642            let len5 = *((ptr4 + 40) as *const i32) as usize;
643            let len6 = *((ptr4 + 56) as *const i32) as usize;
644            
645            (Query(*((ptr4 + 8) as *const i32)), PrepareComplete{capabilities:Capabilities::empty() | Capabilities::from_bits_preserve(((*((ptr4 + 16) as *const i32) as u32) << 0) as _), cardinality:match *((ptr4 + 24) as *const i32) {
646              0 => Cardinality::NoResult,
647              1 => Cardinality::AtMostOne,
648              2 => Cardinality::One,
649              3 => Cardinality::Many,
650              4 => Cardinality::AtLeastOne,
651              _ => panic!("invalid enum discriminant"),
652            }, input_typedesc_id:String::from_utf8(Vec::from_raw_parts(*((ptr4 + 32) as *const i32) as *mut _, len5, len5)).unwrap(), output_typedesc_id:String::from_utf8(Vec::from_raw_parts(*((ptr4 + 48) as *const i32) as *mut _, len6, len6)).unwrap(), })
653          }),
654          1 => Err({
655            let base8 = *((ptr4 + 16) as *const i32);
656            let len8 = *((ptr4 + 24) as *const i32);
657            let mut result8 = Vec::with_capacity(len8 as usize);
658            for i in 0..len8 {
659              let base = base8 + i *8;
660              result8.push({
661                let len7 = *((base + 4) as *const i32) as usize;
662                
663                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len7, len7)).unwrap()
664              });
665            }
666            std::alloc::dealloc(
667            base8 as *mut _,
668            std::alloc::Layout::from_size_align_unchecked(
669            (len8 as usize) * 8,
670            4,
671            ),
672            );
673            let base11 = *((ptr4 + 56) as *const i32);
674            let len11 = *((ptr4 + 64) as *const i32);
675            let mut result11 = Vec::with_capacity(len11 as usize);
676            for i in 0..len11 {
677              let base = base11 + i *12;
678              result11.push({
679                let len10 = *((base + 8) as *const i32) as usize;
680                
681                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len10, len10))
682              });
683            }
684            std::alloc::dealloc(
685            base11 as *mut _,
686            std::alloc::Layout::from_size_align_unchecked(
687            (len11 as usize) * 12,
688            4,
689            ),
690            );
691            
692            Error{code:*((ptr4 + 8) as *const i32) as u32, messages:result8, error:match *((ptr4 + 32) as *const i32) {
693              0 => None,
694              1 => Some({
695                let len9 = *((ptr4 + 48) as *const i32) as usize;
696                
697                String::from_utf8(Vec::from_raw_parts(*((ptr4 + 40) as *const i32) as *mut _, len9, len9)).unwrap()
698              }),
699              _ => panic!("invalid enum discriminant"),
700            }, headers:result11, }
701          }),
702          _ => panic!("invalid enum discriminant"),
703        }
704      }
705    }
706  }
707  impl Transaction {
708    pub fn commit(&self,) -> Result<(),Error>{
709      unsafe {
710        let ptr0 = RET_AREA.as_mut_ptr() as i32;
711        #[link(wasm_import_module = "edgedb-client-v1")]
712        extern "C" {
713          #[cfg_attr(target_arch = "wasm32", link_name = "transaction::commit")]
714          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_transaction::commit")]
715          fn wit_import(_: i32, _: i32, );
716        }
717        wit_import(self.0, ptr0);
718        match *((ptr0 + 0) as *const i32) {
719          0 => Ok(()),
720          1 => Err({
721            let base2 = *((ptr0 + 16) as *const i32);
722            let len2 = *((ptr0 + 24) as *const i32);
723            let mut result2 = Vec::with_capacity(len2 as usize);
724            for i in 0..len2 {
725              let base = base2 + i *8;
726              result2.push({
727                let len1 = *((base + 4) as *const i32) as usize;
728                
729                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len1, len1)).unwrap()
730              });
731            }
732            std::alloc::dealloc(
733            base2 as *mut _,
734            std::alloc::Layout::from_size_align_unchecked(
735            (len2 as usize) * 8,
736            4,
737            ),
738            );
739            let base5 = *((ptr0 + 56) as *const i32);
740            let len5 = *((ptr0 + 64) as *const i32);
741            let mut result5 = Vec::with_capacity(len5 as usize);
742            for i in 0..len5 {
743              let base = base5 + i *12;
744              result5.push({
745                let len4 = *((base + 8) as *const i32) as usize;
746                
747                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len4, len4))
748              });
749            }
750            std::alloc::dealloc(
751            base5 as *mut _,
752            std::alloc::Layout::from_size_align_unchecked(
753            (len5 as usize) * 12,
754            4,
755            ),
756            );
757            
758            Error{code:*((ptr0 + 8) as *const i32) as u32, messages:result2, error:match *((ptr0 + 32) as *const i32) {
759              0 => None,
760              1 => Some({
761                let len3 = *((ptr0 + 48) as *const i32) as usize;
762                
763                String::from_utf8(Vec::from_raw_parts(*((ptr0 + 40) as *const i32) as *mut _, len3, len3)).unwrap()
764              }),
765              _ => panic!("invalid enum discriminant"),
766            }, headers:result5, }
767          }),
768          _ => panic!("invalid enum discriminant"),
769        }
770      }
771    }
772  }
773  impl Transaction {
774    pub fn rollback(&self,) -> Result<(),Error>{
775      unsafe {
776        let ptr0 = RET_AREA.as_mut_ptr() as i32;
777        #[link(wasm_import_module = "edgedb-client-v1")]
778        extern "C" {
779          #[cfg_attr(target_arch = "wasm32", link_name = "transaction::rollback")]
780          #[cfg_attr(not(target_arch = "wasm32"), link_name = "edgedb-client-v1_transaction::rollback")]
781          fn wit_import(_: i32, _: i32, );
782        }
783        wit_import(self.0, ptr0);
784        match *((ptr0 + 0) as *const i32) {
785          0 => Ok(()),
786          1 => Err({
787            let base2 = *((ptr0 + 16) as *const i32);
788            let len2 = *((ptr0 + 24) as *const i32);
789            let mut result2 = Vec::with_capacity(len2 as usize);
790            for i in 0..len2 {
791              let base = base2 + i *8;
792              result2.push({
793                let len1 = *((base + 4) as *const i32) as usize;
794                
795                String::from_utf8(Vec::from_raw_parts(*((base + 0) as *const i32) as *mut _, len1, len1)).unwrap()
796              });
797            }
798            std::alloc::dealloc(
799            base2 as *mut _,
800            std::alloc::Layout::from_size_align_unchecked(
801            (len2 as usize) * 8,
802            4,
803            ),
804            );
805            let base5 = *((ptr0 + 56) as *const i32);
806            let len5 = *((ptr0 + 64) as *const i32);
807            let mut result5 = Vec::with_capacity(len5 as usize);
808            for i in 0..len5 {
809              let base = base5 + i *12;
810              result5.push({
811                let len4 = *((base + 8) as *const i32) as usize;
812                
813                (i32::from(*((base + 0) as *const u16)) as u16, Vec::from_raw_parts(*((base + 4) as *const i32) as *mut _, len4, len4))
814              });
815            }
816            std::alloc::dealloc(
817            base5 as *mut _,
818            std::alloc::Layout::from_size_align_unchecked(
819            (len5 as usize) * 12,
820            4,
821            ),
822            );
823            
824            Error{code:*((ptr0 + 8) as *const i32) as u32, messages:result2, error:match *((ptr0 + 32) as *const i32) {
825              0 => None,
826              1 => Some({
827                let len3 = *((ptr0 + 48) as *const i32) as usize;
828                
829                String::from_utf8(Vec::from_raw_parts(*((ptr0 + 40) as *const i32) as *mut _, len3, len3)).unwrap()
830              }),
831              _ => panic!("invalid enum discriminant"),
832            }, headers:result5, }
833          }),
834          _ => panic!("invalid enum discriminant"),
835        }
836      }
837    }
838  }
839  static mut RET_AREA: [i64; 12] = [0; 12];
840}
841
842mod transaction;
843
844use edgedb_client_v1 as v1;
845use transaction::{Transaction, transaction};
846
847/// EdgeDB Client
848///
849/// Internally it contains a connection pool.
850///
851/// To create client, use [`create_client`] function.
852#[derive(Debug, Clone)]
853pub struct Client {
854    client: Arc<v1::Client>,
855}
856
857/// Create a connection to the database that this WebAssembly app is attached to
858pub fn create_client() -> Client {
859    Client {
860        client: Arc::new(v1::Client::connect()),
861    }
862}
863
864trait StartQuery {
865    fn prepare(self, flags: v1::CompilationFlags, query: &str)
866        -> Result<(v1::Query, v1::PrepareComplete), v1::Error>;
867}
868
869impl v1::Error {
870    fn into_err(self) -> Error {
871        let mut err = Error::from_code(self.code);
872        for msg in self.messages {
873            err = err.context(msg);
874        }
875        // TODO(tailhook) headers
876        return err;
877    }
878}
879
880impl StartQuery for &'_ Client {
881    fn prepare(self, flags: v1::CompilationFlags, query: &str)
882        -> Result<(v1::Query, v1::PrepareComplete), v1::Error>
883    {
884        self.client.prepare(flags, query)
885    }
886}
887
888fn execute_query<T: StartQuery, R, A>(target: T, query: &str, arguments: &A)
889    -> Result<Vec<R>, Error>
890    where A: QueryArgs,
891          R: QueryResult,
892{
893    let flags = v1::CompilationFlags {
894        implicit_limit: None,
895        implicit_typenames: false,
896        implicit_typeids: false,
897        explicit_objectids: true,
898        // host app will remove everything else anyway
899        allow_capabilities: v1::Capabilities::MODIFICATIONS,
900        io_format: v1::IoFormat::Binary,
901        expected_cardinality: v1::Cardinality::Many,
902    };
903    let (query, _prepare_info) = target.prepare(flags, query)
904        .map_err(|e| e.into_err())?;
905    let desc = query.describe_data().map_err(|e| e.into_err())?;
906    let desc = CommandDataDescription::try_from(desc)?;
907    let inp_desc = desc.input()
908        .map_err(ProtocolEncodingError::with_source)?;
909
910    let mut arg_buf = BytesMut::with_capacity(8);
911    arguments.encode(&mut Encoder::new(
912        &inp_desc.as_query_arg_context(),
913        &mut arg_buf,
914    ))?;
915
916    let data = query.execute(&arg_buf).map_err(|e| e.into_err())?;
917
918    let out_desc = desc.output()
919        .map_err(ProtocolEncodingError::with_source)?;
920    match out_desc.root_pos() {
921        Some(root_pos) => {
922            let ctx = out_desc.as_queryable_context();
923            let mut state = R::prepare(&ctx, root_pos)?;
924            let rows = data.chunks.into_iter()
925               .map(|chunk| R::decode(&mut state, &chunk.into()))
926               .collect::<Result<_, _>>()?;
927            Ok(rows)
928        }
929        None => Err(NoResultExpected::build()),
930    }
931}
932
933fn execute_query_single<T: StartQuery, R, A>(target: T,
934                                             query: &str, arguments: &A)
935    -> Result<Option<R>, Error>
936    where A: QueryArgs,
937          R: QueryResult,
938{
939    let flags = v1::CompilationFlags {
940        implicit_limit: None,
941        implicit_typenames: false,
942        implicit_typeids: false,
943        explicit_objectids: true,
944        // host app will remove everything else anyway
945        allow_capabilities: v1::Capabilities::MODIFICATIONS,
946        io_format: v1::IoFormat::Binary,
947        expected_cardinality: v1::Cardinality::AtMostOne,
948    };
949    let (query, _prepare_info) = target.prepare(flags, query)
950        .map_err(|e| e.into_err())?;
951    let desc = query.describe_data().map_err(|e| e.into_err())?;
952    let desc = CommandDataDescription::try_from(desc)?;
953    let inp_desc = desc.input()
954        .map_err(ProtocolEncodingError::with_source)?;
955
956    let mut arg_buf = BytesMut::with_capacity(8);
957    arguments.encode(&mut Encoder::new(
958        &inp_desc.as_query_arg_context(),
959        &mut arg_buf,
960    ))?;
961
962    let data = query.execute(&arg_buf).map_err(|e| e.into_err())?;
963
964    let out_desc = desc.output()
965        .map_err(ProtocolEncodingError::with_source)?;
966    match out_desc.root_pos() {
967        Some(root_pos) => {
968            let ctx = out_desc.as_queryable_context();
969            let mut state = R::prepare(&ctx, root_pos)?;
970            let bytes = data.chunks.into_iter().next();
971            if let Some(bytes) = bytes {
972                Ok(Some(R::decode(&mut state, &Bytes::from(bytes))?))
973            } else {
974                Ok(None)
975            }
976        }
977        None => Err(NoResultExpected::build()),
978    }
979}
980
981fn execute_query_json<T: StartQuery>(target: T,
982                                     query: &str, arguments: &impl QueryArgs)
983    -> Result<Json, Error>
984{
985    let flags = v1::CompilationFlags {
986        implicit_limit: None,
987        implicit_typenames: false,
988        implicit_typeids: false,
989        explicit_objectids: true,
990        // host app will remove everything else anyway
991        allow_capabilities: v1::Capabilities::MODIFICATIONS,
992        io_format: v1::IoFormat::Json,
993        expected_cardinality: v1::Cardinality::Many,
994    };
995    let (query, _prepare_info) = target.prepare(flags, query)
996        .map_err(|e| e.into_err())?;
997    let desc = query.describe_data().map_err(|e| e.into_err())?;
998    let desc = CommandDataDescription::try_from(desc)?;
999    let inp_desc = desc.input()
1000        .map_err(ProtocolEncodingError::with_source)?;
1001
1002    let mut arg_buf = BytesMut::with_capacity(8);
1003    arguments.encode(&mut Encoder::new(
1004        &inp_desc.as_query_arg_context(),
1005        &mut arg_buf,
1006    ))?;
1007
1008    let data = query.execute(&arg_buf).map_err(|e| e.into_err())?;
1009
1010    let out_desc = desc.output()
1011        .map_err(ProtocolEncodingError::with_source)?;
1012    match out_desc.root_pos() {
1013        Some(root_pos) => {
1014            let ctx = out_desc.as_queryable_context();
1015            // JSON objects are returned as strings :(
1016            let mut state = String::prepare(&ctx, root_pos)?;
1017            let bytes = data.chunks.into_iter().next();
1018            if let Some(bytes) = bytes {
1019                // we trust database to produce valid json
1020                let s = String::decode(&mut state, &Bytes::from(bytes))?;
1021                Ok(unsafe { Json::new_unchecked(s) })
1022            } else {
1023                Err(NoDataError::with_message(
1024                    "query row returned zero results"))
1025            }
1026        }
1027        None => Err(NoResultExpected::build()),
1028    }
1029}
1030
1031fn execute_query_single_json<T: StartQuery>(target: T,
1032    query: &str, arguments: &impl QueryArgs)
1033    -> Result<Option<Json>, Error>
1034{
1035    let flags = v1::CompilationFlags {
1036        implicit_limit: None,
1037        implicit_typenames: false,
1038        implicit_typeids: false,
1039        explicit_objectids: true,
1040        // host app will remove everything else anyway
1041        allow_capabilities: v1::Capabilities::MODIFICATIONS,
1042        io_format: v1::IoFormat::Json,
1043        expected_cardinality: v1::Cardinality::AtMostOne,
1044    };
1045    let (query, _prepare_info) = target.prepare(flags, query)
1046        .map_err(|e| e.into_err())?;
1047    let desc = query.describe_data().map_err(|e| e.into_err())?;
1048    let desc = CommandDataDescription::try_from(desc)?;
1049    let inp_desc = desc.input()
1050        .map_err(ProtocolEncodingError::with_source)?;
1051
1052    let mut arg_buf = BytesMut::with_capacity(8);
1053    arguments.encode(&mut Encoder::new(
1054        &inp_desc.as_query_arg_context(),
1055        &mut arg_buf,
1056    ))?;
1057
1058    let data = query.execute(&arg_buf).map_err(|e| e.into_err())?;
1059
1060    let out_desc = desc.output()
1061        .map_err(ProtocolEncodingError::with_source)?;
1062    match out_desc.root_pos() {
1063        Some(root_pos) => {
1064            let ctx = out_desc.as_queryable_context();
1065            // JSON objects are returned as strings :(
1066            let mut state = String::prepare(&ctx, root_pos)?;
1067            let bytes = data.chunks.into_iter().next();
1068            if let Some(bytes) = bytes {
1069                // we trust database to produce valid json
1070                let s = String::decode(&mut state, &Bytes::from(bytes))?;
1071                Ok(Some(unsafe { Json::new_unchecked(s) }))
1072            } else {
1073                Ok(None)
1074            }
1075        }
1076        None => Err(NoResultExpected::build()),
1077    }
1078}
1079
1080impl Client {
1081    /// Execute a query and return a collection of results.
1082    ///
1083    /// You will usually have to specify the return type for the query:
1084    ///
1085    /// ```rust,ignore
1086    /// let greeting = pool.query::<String, _>("SELECT 'hello'", &());
1087    /// // or
1088    /// let greeting: Vec<String> = pool.query("SELECT 'hello'", &());
1089    /// ```
1090    ///
1091    /// This method can be used with both static arguments, like a tuple of
1092    /// scalars, and with dynamic arguments [`edgedb_protocol::value::Value`].
1093    /// Similarly, dynamically typed results are also supported.
1094    pub fn query<R, A>(&self, query: &str, arguments: &A)
1095        -> Result<Vec<R>, Error>
1096        where A: QueryArgs,
1097              R: QueryResult,
1098    {
1099        execute_query(self, query, arguments)
1100    }
1101
1102    /// Execute a query and return a single result
1103    ///
1104    /// You will usually have to specify the return type for the query:
1105    ///
1106    /// ```rust,ignore
1107    /// let greeting = pool.query_single::<String, _>("SELECT 'hello'", &());
1108    /// // or
1109    /// let greeting: Option<String> = pool.query_single(
1110    ///     "SELECT 'hello'",
1111    ///     &()
1112    /// );
1113    /// ```
1114    ///
1115    /// This method can be used with both static arguments, like a tuple of
1116    /// scalars, and with dynamic arguments [`edgedb_protocol::value::Value`].
1117    /// Similarly, dynamically typed results are also supported.
1118    pub fn query_single<R, A>(&self, query: &str, arguments: &A)
1119        -> Result<Option<R>, Error>
1120        where A: QueryArgs,
1121              R: QueryResult,
1122    {
1123        execute_query_single(self, query, arguments)
1124    }
1125
1126    /// Execute a query and return a single result
1127    ///
1128    /// The query must return exactly one element. If the query returns more
1129    /// than one element, a
1130    /// [`ResultCardinalityMismatchError`][crate::client::errors::ResultCardinalityMismatchError]
1131    /// is raised. If the query returns an empty set, a
1132    /// [`NoDataError`][crate::client::errors::NoDataError] is raised.
1133    ///
1134    /// You will usually have to specify the return type for the query:
1135    ///
1136    /// ```rust,ignore
1137    /// let greeting = pool.query_required_single::<String, _>(
1138    ///     "SELECT 'hello'",
1139    ///     &(),
1140    /// );
1141    /// // or
1142    /// let greeting: String = pool.query_required_single(
1143    ///     "SELECT 'hello'",
1144    ///     &(),
1145    /// );
1146    /// ```
1147    ///
1148    /// This method can be used with both static arguments, like a tuple of
1149    /// scalars, and with dynamic arguments [`edgedb_protocol::value::Value`].
1150    /// Similarly, dynamically typed results are also supported.
1151    pub fn query_required_single<R, A>(&self, query: &str, arguments: &A)
1152        -> Result<R, Error>
1153        where A: QueryArgs,
1154              R: QueryResult,
1155    {
1156        self.query_single(query, arguments)?
1157            .ok_or_else(|| NoDataError::with_message(
1158                        "query row returned zero results"))
1159    }
1160
1161    /// Execute a query and return the result as JSON.
1162    pub fn query_json(&self, query: &str, arguments: &impl QueryArgs)
1163        -> Result<Json, Error>
1164    {
1165        execute_query_json(self, query, arguments)
1166    }
1167
1168    /// Execute a query and return a single result as JSON.
1169    ///
1170    /// The query must return exactly one element. If the query returns more
1171    /// than one element, a
1172    /// [`ResultCardinalityMismatchError`][crate::client::errors::ResultCardinalityMismatchError]
1173    /// is raised.
1174    pub fn query_single_json(&self,
1175                                   query: &str, arguments: &impl QueryArgs)
1176        -> Result<Option<Json>, Error>
1177    {
1178        execute_query_single_json(self, query, arguments)
1179    }
1180
1181    /// Execute a query and return a single result as JSON.
1182    ///
1183    /// The query must return exactly one element. If the query returns more
1184    /// than one element, a
1185    /// [`ResultCardinalityMismatchError`][crate::client::errors::ResultCardinalityMismatchError]
1186    /// is raised. If the query returns an empty set, a
1187    /// [`NoDataError`][crate::client::errors::NoDataError] is raised.
1188    pub fn query_required_single_json(&self,
1189                                   query: &str, arguments: &impl QueryArgs)
1190        -> Result<Json, Error>
1191    {
1192        self.query_single_json(query, arguments)?
1193            .ok_or_else(|| NoDataError::with_message(
1194                        "query row returned zero results"))
1195    }
1196
1197    /// Execute a transaction
1198    ///
1199    /// Transaction body must be encompassed in the closure. The closure **may
1200    /// be executed multiple times**. This includes not only database queries
1201    /// but also executing the whole function, so the transaction code must be
1202    /// prepared to be idempotent.
1203    ///
1204    /// # Example
1205    ///
1206    /// ```rust,no_run
1207    /// # fn transaction() -> Result<(), edgedb_sdk::client::Error> {
1208    /// let conn = edgedb_sdk::client::create_client();
1209    /// let val = conn.transaction(|mut tx| {
1210    ///     // TODO(tailhook) query_required_single
1211    ///     tx.query_required_single::<i64, _>("
1212    ///         WITH C := UPDATE Counter SET { value := .value + 1}
1213    ///         SELECT C.value LIMIT 1
1214    ///     ", &()
1215    ///     )
1216    /// })?;
1217    /// # Ok(())
1218    /// # }
1219    /// ```
1220    pub fn transaction<T, F>(&self, body: F) -> Result<T, Error>
1221        where F: FnMut(&mut Transaction) -> Result<T, Error>,
1222    {
1223        transaction(&self, body)
1224    }
1225}
1226
1227impl TryFrom<v1::DataDescription> for CommandDataDescription {
1228    type Error = Error;
1229    fn try_from(src: v1::DataDescription)
1230        -> Result<CommandDataDescription, Error>
1231    {
1232        Ok(CommandDataDescription {
1233            proto: ProtocolVersion::new(src.proto.0, src.proto.1),
1234            headers: HashMap::new(),
1235            result_cardinality: src.result_cardinality.into(),
1236            input_typedesc_id: src.input_typedesc_id.parse()
1237                .map_err(ClientError::with_source)?,
1238            input_typedesc: src.input_typedesc.into(),
1239            output_typedesc_id: src.output_typedesc_id.parse()
1240                .map_err(ClientError::with_source)?,
1241            output_typedesc: src.output_typedesc.into(),
1242        })
1243    }
1244}
1245
1246impl From<v1::Cardinality> for Cardinality {
1247    fn from(src: v1::Cardinality) -> Cardinality {
1248        match src {
1249            v1::Cardinality::NoResult => Cardinality::NoResult,
1250            v1::Cardinality::AtMostOne => Cardinality::AtMostOne,
1251            v1::Cardinality::One => Cardinality::One,
1252            v1::Cardinality::Many => Cardinality::Many,
1253            v1::Cardinality::AtLeastOne => Cardinality::AtLeastOne,
1254        }
1255    }
1256}