Skip to main content

tank_core/query/
dyn_query.rs

1use crate::{Driver, Prepared, Query, RawQuery};
2use std::{
3    any::Any,
4    borrow::Cow,
5    fmt::{self, Write},
6    mem,
7};
8
9/// Dyn compatible version of `Query`
10pub enum DynQuery {
11    Raw(RawQuery),
12    Prepared(Box<dyn Prepared>),
13}
14
15impl DynQuery {
16    pub fn new(value: String) -> Self {
17        Self::Raw(RawQuery(value))
18    }
19    pub fn with_capacity(capacity: usize) -> Self {
20        Self::new(String::with_capacity(capacity))
21    }
22    pub fn buffer(&mut self) -> &mut String {
23        if !matches!(self, Self::Raw(..)) {
24            log::error!("DynQuery::buffer changed the query to raw, deleting the previous content");
25            *self = Self::Raw(Default::default())
26        }
27        let Self::Raw(RawQuery(value)) = self else {
28            unreachable!();
29        };
30        value
31    }
32    pub fn as_prepared<D: Driver>(&mut self) -> Option<&mut D::Prepared> {
33        if let Self::Prepared(prepared) = self {
34            return (&mut **prepared as &mut dyn Any).downcast_mut::<D::Prepared>();
35        }
36        None
37    }
38    pub fn as_str<'s>(&'s self) -> Cow<'s, str> {
39        match self {
40            Self::Raw(RawQuery(sql)) => Cow::Borrowed(sql),
41            Self::Prepared(v) => Cow::Owned(format!("{:?}", *v)),
42        }
43    }
44    pub fn push_str(&mut self, s: &str) {
45        self.buffer().push_str(s);
46    }
47    pub fn push(&mut self, c: char) {
48        self.buffer().push(c);
49    }
50    pub fn len(&self) -> usize {
51        match self {
52            Self::Raw(RawQuery(sql)) => sql.len(),
53            Self::Prepared(..) => 0,
54        }
55    }
56    pub fn is_empty(&self) -> bool {
57        match self {
58            Self::Raw(RawQuery(sql)) => sql.is_empty(),
59            Self::Prepared(..) => true,
60        }
61    }
62
63    pub fn into_query<D: Driver>(self, _driver: D) -> Query<D> {
64        self.into()
65    }
66}
67
68impl Default for DynQuery {
69    fn default() -> Self {
70        Self::Raw(Default::default())
71    }
72}
73
74impl Write for DynQuery {
75    fn write_char(&mut self, c: char) -> fmt::Result {
76        self.push(c);
77        Ok(())
78    }
79    fn write_str(&mut self, s: &str) -> fmt::Result {
80        self.push_str(s);
81        Ok(())
82    }
83}
84
85impl<D: Driver> From<Query<D>> for DynQuery {
86    fn from(value: Query<D>) -> Self {
87        match value {
88            Query::Raw(v) => Self::Raw(v),
89            Query::Prepared(p) => Self::Prepared(Box::new(p)),
90        }
91    }
92}
93
94impl<D: Driver> From<DynQuery> for Query<D> {
95    fn from(value: DynQuery) -> Self {
96        match value {
97            DynQuery::Raw(r) => Self::Raw(r),
98            DynQuery::Prepared(p) => match p.as_any().downcast::<D::Prepared>() {
99                Ok(p) => Query::Prepared(*p),
100                Err(..) => Query::raw(Default::default()),
101            },
102        }
103    }
104}
105
106impl From<DynQuery> for String {
107    fn from(mut value: DynQuery) -> Self {
108        mem::take(value.buffer())
109    }
110}