sqlx_xugu/
arguments.rs

1use crate::{Xugu, XuguTypeInfo};
2pub(crate) use sqlx_core::arguments::*;
3use sqlx_core::encode::{Encode, IsNull};
4use sqlx_core::error::BoxDynError;
5use sqlx_core::types::Type;
6use std::borrow::Cow;
7
8#[derive(Debug, Clone)]
9pub enum XuguArgumentValue<'q> {
10    Null,
11    Str(Cow<'q, str>),
12    Bin(Cow<'q, [u8]>),
13}
14
15/// Implementation of [`Arguments`] for Xugu.
16#[derive(Debug, Default, Clone)]
17pub struct XuguArguments<'q> {
18    pub(crate) values: Vec<XuguArgumentValue<'q>>,
19    pub(crate) types: Vec<XuguTypeInfo>,
20}
21
22impl<'q> XuguArguments<'q> {
23    pub(crate) fn add<T>(&mut self, value: T) -> Result<(), BoxDynError>
24    where
25        T: Encode<'q, Xugu> + Type<Xugu>,
26    {
27        let ty = value.produces().unwrap_or_else(T::type_info);
28
29        let value_length_before_encoding = self.values.len();
30        match value.encode(&mut self.values) {
31            Ok(IsNull::Yes) => self.values.push(XuguArgumentValue::Null),
32            Ok(IsNull::No) => {}
33            Err(error) => {
34                // reset the value buffer to its previous value if encoding failed so we don't leave a half-encoded value behind
35                self.values.truncate(value_length_before_encoding);
36                return Err(error);
37            }
38        };
39
40        self.types.push(ty);
41
42        Ok(())
43    }
44}
45
46impl<'q> Arguments<'q> for XuguArguments<'q> {
47    type Database = Xugu;
48
49    fn reserve(&mut self, len: usize, size: usize) {
50        self.types.reserve(len);
51        self.values.reserve(size);
52    }
53
54    fn add<T>(&mut self, value: T) -> Result<(), BoxDynError>
55    where
56        T: Encode<'q, Self::Database> + Type<Self::Database>,
57    {
58        self.add(value)
59    }
60
61    fn len(&self) -> usize {
62        self.types.len()
63    }
64}