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