cdk_sql_common/
macros.rs

1//! Collection of macros to generate code to digest data from a generic SQL databasex
2
3/// Unpacks a vector of Column, and consumes it, parsing into individual variables, checking the
4/// vector is big enough.
5#[macro_export]
6macro_rules! unpack_into {
7    (let ($($var:ident),+) = $array:expr) => {
8        let ($($var),+) = {
9            let mut vec = $array.to_vec();
10            vec.reverse();
11            let required = 0 $(+ {let _ = stringify!($var); 1})+;
12            if vec.len() < required {
13                 Err($crate::ConversionError::MissingColumn(required, vec.len()))?;
14            }
15            Ok::<_, cdk_common::database::Error>((
16                $(
17                    vec.pop().expect(&format!("Checked length already for {}", stringify!($var)))
18                ),+
19            ))?
20        };
21    };
22}
23
24/// Parses a SQL column as a string or NULL
25#[macro_export]
26macro_rules! column_as_nullable_string {
27    ($col:expr, $callback_str:expr, $callback_bytes:expr) => {
28        (match $col {
29            $crate::stmt::Column::Text(text) => Ok(Some(text).and_then($callback_str)),
30            $crate::stmt::Column::Blob(bytes) => Ok(Some(bytes).and_then($callback_bytes)),
31            $crate::stmt::Column::Null => Ok(None),
32            _ => Err($crate::ConversionError::InvalidType(
33                "String".to_owned(),
34                stringify!($col).to_owned(),
35            )),
36        })?
37    };
38    ($col:expr, $callback_str:expr) => {
39        (match $col {
40            $crate::stmt::Column::Text(text) => Ok(Some(text).and_then($callback_str)),
41            $crate::stmt::Column::Blob(bytes) => {
42                Ok(Some(String::from_utf8_lossy(&bytes)).and_then($callback_str))
43            }
44            $crate::stmt::Column::Null => Ok(None),
45            _ => Err($crate::ConversionError::InvalidType(
46                "String".to_owned(),
47                stringify!($col).to_owned(),
48            )),
49        })?
50    };
51    ($col:expr) => {
52        (match $col {
53            $crate::stmt::Column::Text(text) => Ok(Some(text.to_owned())),
54            $crate::stmt::Column::Blob(bytes) => {
55                Ok(Some(String::from_utf8_lossy(&bytes).to_string()))
56            }
57            $crate::stmt::Column::Null => Ok(None),
58            _ => Err($crate::ConversionError::InvalidType(
59                "String".to_owned(),
60                stringify!($col).to_owned(),
61            )),
62        })?
63    };
64}
65
66/// Parses a column as a number or NULL
67#[macro_export]
68macro_rules! column_as_nullable_number {
69    ($col:expr) => {
70        (match $col {
71            $crate::stmt::Column::Text(text) => Ok(Some(text.parse().map_err(|_| {
72                $crate::ConversionError::InvalidConversion(
73                    stringify!($col).to_owned(),
74                    "Number".to_owned(),
75                )
76            })?)),
77            $crate::stmt::Column::Integer(n) => Ok(Some(n.try_into().map_err(|_| {
78                $crate::ConversionError::InvalidConversion(
79                    stringify!($col).to_owned(),
80                    "Number".to_owned(),
81                )
82            })?)),
83            $crate::stmt::Column::Null => Ok(None),
84            _ => Err($crate::ConversionError::InvalidType(
85                "Number".to_owned(),
86                stringify!($col).to_owned(),
87            )),
88        })?
89    };
90}
91
92/// Parses a column as a number
93#[macro_export]
94macro_rules! column_as_number {
95    ($col:expr) => {
96        (match $col {
97            $crate::stmt::Column::Text(text) => text.parse().map_err(|_| {
98                $crate::ConversionError::InvalidConversion(
99                    stringify!($col).to_owned(),
100                    "Number".to_owned(),
101                )
102            }),
103            $crate::stmt::Column::Integer(n) => n.try_into().map_err(|_| {
104                $crate::ConversionError::InvalidConversion(
105                    stringify!($col).to_owned(),
106                    "Number".to_owned(),
107                )
108            }),
109            _ => Err($crate::ConversionError::InvalidType(
110                "Number".to_owned(),
111                stringify!($col).to_owned(),
112            )),
113        })?
114    };
115}
116
117/// Parses a column as a NULL or Binary
118#[macro_export]
119macro_rules! column_as_nullable_binary {
120    ($col:expr) => {
121        (match $col {
122            $crate::stmt::Column::Text(text) => Ok(Some(text.as_bytes().to_vec())),
123            $crate::stmt::Column::Blob(bytes) => Ok(Some(bytes.to_owned())),
124            $crate::stmt::Column::Null => Ok(None),
125            _ => Err($crate::ConversionError::InvalidType(
126                "String".to_owned(),
127                stringify!($col).to_owned(),
128            )),
129        })?
130    };
131}
132
133/// Parses a SQL column as a binary
134#[macro_export]
135macro_rules! column_as_binary {
136    ($col:expr) => {
137        (match $col {
138            $crate::stmt::Column::Text(text) => Ok(text.as_bytes().to_vec()),
139            $crate::stmt::Column::Blob(bytes) => Ok(bytes.to_owned()),
140            _ => Err($crate::ConversionError::InvalidType(
141                "String".to_owned(),
142                stringify!($col).to_owned(),
143            )),
144        })?
145    };
146}
147
148/// Parses a SQL column as a string
149#[macro_export]
150macro_rules! column_as_string {
151    ($col:expr, $callback_str:expr, $callback_bytes:expr) => {
152        (match $col {
153            $crate::stmt::Column::Text(text) => {
154                $callback_str(&text).map_err($crate::ConversionError::from)
155            }
156            $crate::stmt::Column::Blob(bytes) => {
157                $callback_bytes(&bytes).map_err($crate::ConversionError::from)
158            }
159            _ => Err($crate::ConversionError::InvalidType(
160                "String".to_owned(),
161                stringify!($col).to_owned(),
162            )),
163        })?
164    };
165    ($col:expr, $callback:expr) => {
166        (match $col {
167            $crate::stmt::Column::Text(text) => {
168                $callback(&text).map_err($crate::ConversionError::from)
169            }
170            $crate::stmt::Column::Blob(bytes) => {
171                $callback(&String::from_utf8_lossy(&bytes)).map_err($crate::ConversionError::from)
172            }
173            _ => Err($crate::ConversionError::InvalidType(
174                "String".to_owned(),
175                stringify!($col).to_owned(),
176            )),
177        })?
178    };
179    ($col:expr) => {
180        (match $col {
181            $crate::stmt::Column::Text(text) => Ok(text.to_owned()),
182            $crate::stmt::Column::Blob(bytes) => Ok(String::from_utf8_lossy(&bytes).to_string()),
183            _ => Err($crate::ConversionError::InvalidType(
184                "String".to_owned(),
185                stringify!($col).to_owned(),
186            )),
187        })?
188    };
189}