toasty_sql/serializer/
params.rs

1use crate::serializer::ExprContext;
2
3use super::{Flavor, Formatter, ToSql};
4
5use toasty_core::stmt;
6
7pub trait Params {
8    fn push(&mut self, param: &stmt::Value, type_hint: Option<&stmt::Type>) -> Placeholder;
9}
10
11pub struct Placeholder(pub usize);
12
13#[derive(Debug, Clone)]
14pub struct TypedValue {
15    pub value: stmt::Value,
16    pub type_hint: Option<stmt::Type>,
17}
18
19impl TypedValue {
20    /// Infers the type of this value, using the type hint if available
21    pub fn infer_ty(&self) -> stmt::Type {
22        self.type_hint
23            .clone()
24            .unwrap_or_else(|| self.value.infer_ty())
25    }
26}
27
28impl Params for Vec<stmt::Value> {
29    fn push(&mut self, value: &stmt::Value, _type_hint: Option<&stmt::Type>) -> Placeholder {
30        self.push(value.clone());
31        Placeholder(self.len())
32    }
33}
34
35impl Params for Vec<TypedValue> {
36    fn push(&mut self, value: &stmt::Value, type_hint: Option<&stmt::Type>) -> Placeholder {
37        self.push(TypedValue {
38            value: value.clone(),
39            type_hint: type_hint.cloned(),
40        });
41        Placeholder(self.len())
42    }
43}
44
45impl ToSql for Placeholder {
46    fn to_sql<P: Params>(self, _cx: &ExprContext<'_>, f: &mut Formatter<'_, P>) {
47        use std::fmt::Write;
48
49        match f.serializer.flavor {
50            Flavor::Mysql => write!(&mut f.dst, "?").unwrap(),
51            Flavor::Postgresql => write!(&mut f.dst, "${}", self.0).unwrap(),
52            Flavor::Sqlite => write!(&mut f.dst, "?{}", self.0).unwrap(),
53        }
54    }
55}