1#![forbid(unsafe_code)]
54#[allow(clippy::single_component_path_imports)]
55use sqlx_type_macro;
56
57pub use crate::sqlx_type_macro::{query, query_as};
58
59#[doc(hidden)]
61pub struct Integer;
62
63#[doc(hidden)]
65pub struct Float;
66
67#[doc(hidden)]
69pub struct Timestamp;
70
71#[doc(hidden)]
73pub struct DateTime;
74
75#[doc(hidden)]
77pub struct Date;
78
79#[doc(hidden)]
81pub struct Time;
82
83#[doc(hidden)]
85pub struct Any;
86
87
88#[doc(hidden)]
90pub trait ArgIn<T> {}
91pub trait ArgOut<T, const IDX: usize> {}
92
93macro_rules! arg_io {
94 ( $dst: ty, $t: ty ) => {
95 impl ArgIn<$dst> for $t {}
96 impl ArgIn<$dst> for &$t {}
97 impl ArgIn<Option<$dst>> for $t {}
98 impl ArgIn<Option<$dst>> for &$t {}
99 impl ArgIn<Option<$dst>> for Option<$t> {}
100 impl ArgIn<Option<$dst>> for Option<&$t> {}
101 impl ArgIn<Option<$dst>> for &Option<$t> {}
102 impl ArgIn<Option<$dst>> for &Option<&$t> {}
103
104 impl<const IDX: usize> ArgOut<$dst, IDX> for $t {}
105 impl<const IDX: usize> ArgOut<Option<$dst>, IDX> for Option<$t> {}
106 impl<const IDX: usize> ArgOut<$dst, IDX> for Option<$t> {}
107 };
108}
109
110
111arg_io!(Any, u64);
112arg_io!(Any, i64);
113arg_io!(Any, u32);
114arg_io!(Any, i32);
115arg_io!(Any, u16);
116arg_io!(Any, i16);
117arg_io!(Any, u8);
118arg_io!(Any, i8);
119arg_io!(Any, String);
120arg_io!(Any, f64);
121arg_io!(Any, f32);
122arg_io!(Any, &str);
123
124arg_io!(Integer, u64);
125arg_io!(Integer, i64);
126arg_io!(Integer, u32);
127arg_io!(Integer, i32);
128arg_io!(Integer, u16);
129arg_io!(Integer, i16);
130arg_io!(Integer, u8);
131arg_io!(Integer, i8);
132
133arg_io!(String, String);
134
135arg_io!(Float, f64);
136arg_io!(Float, f32);
137
138arg_io!(u64, u64);
139arg_io!(i64, i64);
140arg_io!(u32, u32);
141arg_io!(i32, i32);
142arg_io!(u16, u16);
143arg_io!(i16, i16);
144arg_io!(u8, u8);
145arg_io!(i8, i8);
146arg_io!(bool, bool);
147arg_io!(f32, f32);
148arg_io!(f64, f64);
149
150arg_io!(&str, &str);
151arg_io!(&str, String);
152arg_io!(&str, std::borrow::Cow<'_, str>);
153
154arg_io!(&[u8], &[u8]);
155arg_io!(&[u8], Vec<u8>);
156arg_io!(Vec<u8>, Vec<u8>);
157
158arg_io!(Timestamp, chrono::NaiveDateTime);
159arg_io!(DateTime, chrono::NaiveDateTime);
160arg_io!(chrono::DateTime<chrono::Utc>, chrono::DateTime<chrono::Utc>);
161arg_io!(Timestamp, chrono::DateTime<chrono::Utc>);
162
163#[doc(hidden)]
164pub fn check_arg<T, T2: ArgIn<T>>(_: &T2) {}
165
166#[doc(hidden)]
167pub fn check_arg_list_hack<T, T2: ArgIn<T>>(_: &[T2]) {}
168
169#[doc(hidden)]
170pub fn arg_out<T, T2: ArgOut<T, IDX>, const IDX: usize>(v: T2) -> T2 {
171 v
172}
173
174#[doc(hidden)]
175pub fn convert_list_query(query: &str, list_sizes: &[usize]) -> String {
176 let mut query_iter = query.split("_LIST_");
177 let mut query = query_iter.next().expect("None empty query").to_string();
178 for size in list_sizes {
179 if *size == 0 {
180 query.push_str("NULL");
181 } else {
182 for i in 0..*size {
183 if i == 0 {
184 query.push('?');
185 } else {
186 query.push_str(", ?");
187 }
188 }
189 }
190 query.push_str(query_iter.next().expect("More _LIST_ in query"));
191 }
192 if query_iter.next().is_some() {
193 panic!("Too many _LIST_ in query");
194 }
195 query
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201
202 #[test]
203 fn test_convert_list_query() {
204 assert_eq!(
207 &convert_list_query("FOO (_LIST_) X _LIST_ O _LIST_ BAR (_LIST_)", &[0, 1, 2, 3]),
208 "FOO (NULL) X ? O ?, ? BAR (?, ?, ?)"
209 );
210 }
211}