1use std::{borrow::Cow, fmt};
2
3use crate::traits::SQLParam;
4
5#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum PlaceholderStyle {
8 Colon,
10 AtSign,
12 Dollar,
14 #[default]
15 Positional,
16}
17
18#[derive(Default, Debug, Clone, Hash, Copy, PartialEq, Eq)]
20pub struct Placeholder {
21 pub name: Option<&'static str>,
23 pub style: PlaceholderStyle,
25}
26
27impl Placeholder {
28 pub const fn with_style(name: &'static str, style: PlaceholderStyle) -> Self {
30 Placeholder {
31 name: Some(name),
32 style,
33 }
34 }
35
36 pub const fn colon(name: &'static str) -> Self {
38 Self::with_style(name, PlaceholderStyle::Colon)
39 }
40
41 pub const fn at(name: &'static str) -> Self {
43 Self::with_style(name, PlaceholderStyle::AtSign)
44 }
45
46 pub const fn dollar(name: &'static str) -> Self {
48 Self::with_style(name, PlaceholderStyle::Dollar)
49 }
50
51 pub const fn positional() -> Self {
53 Placeholder {
54 name: None,
55 style: PlaceholderStyle::Positional,
56 }
57 }
58}
59
60impl fmt::Display for Placeholder {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 match self.style {
63 PlaceholderStyle::Colon => write!(f, ":{}", self.name.unwrap_or_default()),
64 PlaceholderStyle::AtSign => write!(f, "@{}", self.name.unwrap_or_default()),
65 PlaceholderStyle::Dollar => write!(f, "${}", self.name.unwrap_or_default()),
66 PlaceholderStyle::Positional => write!(f, "?"),
67 }
68 }
69}
70
71#[derive(Debug, Clone)]
74pub struct Param<'a, V: SQLParam> {
75 pub placeholder: Placeholder,
77 pub value: Option<Cow<'a, V>>,
79}
80
81impl<'a, V: SQLParam> Param<'a, V> {
82 pub fn new(placeholder: Placeholder, value: Option<Cow<'a, V>>) -> Self {
83 Self { placeholder, value }
84 }
85}
86
87impl<'a, V: SQLParam> From<OwnedParam<V>> for Param<'a, V> {
88 fn from(value: OwnedParam<V>) -> Self {
89 Self {
90 placeholder: value.placeholder,
91 value: value.value.map(|v| Cow::Owned(v)),
92 }
93 }
94}
95
96impl<'a, V: SQLParam> From<&'a OwnedParam<V>> for Param<'a, V> {
97 fn from(value: &'a OwnedParam<V>) -> Self {
98 Self {
99 placeholder: value.placeholder,
100 value: value.value.as_ref().map(|v| Cow::Borrowed(v)),
101 }
102 }
103}
104
105#[derive(Debug, Clone)]
106pub struct OwnedParam<V: SQLParam> {
107 pub placeholder: Placeholder,
109 pub value: Option<V>,
111}
112
113impl<'a, V: SQLParam> From<Param<'a, V>> for OwnedParam<V> {
114 fn from(value: Param<'a, V>) -> Self {
115 Self {
116 placeholder: value.placeholder,
117 value: value.value.map(|v| v.into_owned()),
118 }
119 }
120}
121
122impl<'a, V: SQLParam> From<&Param<'a, V>> for OwnedParam<V> {
123 fn from(value: &Param<'a, V>) -> Self {
124 Self {
125 placeholder: value.placeholder,
126 value: value.value.clone().map(|v| v.into_owned()),
127 }
128 }
129}
130
131impl<'a, T: SQLParam> Param<'a, T> {
132 pub const fn positional(value: T) -> Self {
134 Self {
135 placeholder: Placeholder::positional(),
136 value: Some(Cow::Owned(value)),
137 }
138 }
139
140 pub const fn from_placeholder(placeholder: Placeholder) -> Self {
142 Self {
143 placeholder,
144 value: None,
145 }
146 }
147
148 pub const fn named(name: &'static str, value: T) -> Self {
150 Self {
151 placeholder: Placeholder::colon(name),
152 value: Some(Cow::Owned(value)),
153 }
154 }
155
156 pub const fn with_placeholder(placeholder: Placeholder, value: T) -> Self {
158 Self {
159 placeholder,
160 value: Some(Cow::Owned(value)),
161 }
162 }
163}
164
165#[derive(Debug, Clone)]
166pub struct ParamBind<'a, V: SQLParam> {
167 pub name: &'a str,
168 pub value: V,
169}
170
171impl<'a, V: SQLParam> ParamBind<'a, V> {
172 pub const fn new(name: &'a str, value: V) -> Self {
173 Self { name, value }
174 }
175}
176
177pub mod placeholders {
179 use super::{Placeholder, PlaceholderStyle};
180
181 pub const fn colon(name: &'static str) -> Placeholder {
182 Placeholder::with_style(name, PlaceholderStyle::Colon)
183 }
184
185 pub const fn at(name: &'static str) -> Placeholder {
186 Placeholder::with_style(name, PlaceholderStyle::AtSign)
187 }
188
189 pub const fn dollar(name: &'static str) -> Placeholder {
190 Placeholder::with_style(name, PlaceholderStyle::Dollar)
191 }
192}