tank_core/query/
dyn_query.rs

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