1#[macro_export]
2macro_rules! query_values {
3 ($($value:expr),*) => {
4 {
5 use cdrs::types::value::Value;
6 use cdrs::query::QueryValues;
7 let mut values: Vec<Value> = Vec::new();
8 $(
9 values.push($value.into());
10 )*
11 QueryValues::SimpleValues(values)
12 }
13 };
14 ($($name:expr => $value:expr),*) => {
15 {
16 use cdrs::types::value::Value;
17 use cdrs::query::QueryValues;
18 use std::collections::HashMap;
19 let mut values: HashMap<String, Value> = HashMap::new();
20 $(
21 values.insert($name.to_string(), $value.into());
22 )*
23 QueryValues::NamedValues(values)
24 }
25 };
26}
27
28#[macro_export]
29macro_rules! builder_opt_field {
30 ($field:ident, $field_type:ty) => {
31 pub fn $field(mut self,
32 $field: $field_type) -> Self {
33 self.$field = Some($field);
34 self
35 }
36 };
37}
38
39#[macro_export]
40macro_rules! list_as_rust {
41 ($($into_type:tt)+) => (
42 impl AsRustType<Vec<$($into_type)+>> for List {
43 fn as_rust_type(&self) -> Result<Option<Vec<$($into_type)+>>> {
44 match self.metadata.value {
45 Some(ColTypeOptionValue::CList(ref type_option)) |
46 Some(ColTypeOptionValue::CSet(ref type_option)) => {
47 let type_option_ref = type_option.as_ref();
48 let convert = self
49 .map(|bytes| {
50 as_rust_type!(type_option_ref, bytes, $($into_type)+)
51 .unwrap()
52 .unwrap()
55 });
56
57 Ok(Some(convert))
58 },
59 _ => Err(Error::General(format!("Invalid conversion. \
60 Cannot convert {:?} into List (valid types: List, Set).",
61 self.metadata.value)))
62 }
63 }
64 }
65 );
66}
67
68#[macro_export]
69macro_rules! map_as_rust {
70 ({ $($key_type:tt)+ }, { $($val_type:tt)+ }) => (
71 impl AsRustType<HashMap<$($key_type)+, $($val_type)+>> for Map {
72 fn as_rust_type(&self) -> Result<Option<HashMap<$($key_type)+, $($val_type)+>>> {
74 match self.metadata.value {
75 Some(ColTypeOptionValue::CMap((ref key_type_option, ref val_type_option))) => {
76 let mut map = HashMap::with_capacity(self.data.len());
77
78 for &(ref key, ref val) in self.data.iter() {
79 let key_type_option = key_type_option.as_ref();
80 let val_type_option = val_type_option.as_ref();
81 let key = as_rust_type!(key_type_option, key, $($key_type)+)?;
82 let val = as_rust_type!(val_type_option, val, $($val_type)+)?;
83 if val.is_some() && key.is_some() {
84 map.insert(key.unwrap(), val.unwrap());
85 }
86 }
87
88 Ok(Some(map))
89 }
90 _ => unreachable!()
91 }
92 }
93 }
94 );
95}
96
97#[macro_export]
98macro_rules! into_rust_by_name {
99 (Row, $($into_type:tt)+) => (
100 impl IntoRustByName<$($into_type)+> for Row {
101 fn get_by_name(&self, name: &str) -> Result<Option<$($into_type)+>> {
102 self.get_col_spec_by_name(name)
103 .ok_or(column_is_empty_err(name))
104 .and_then(|(col_spec, cbytes)| {
105 let ref col_type = col_spec.col_type;
106 as_rust_type!(col_type, cbytes, $($into_type)+)
107 })
108 }
109 }
110 );
111 (UDT, $($into_type:tt)+) => (
112 impl IntoRustByName<$($into_type)+> for UDT {
113 fn get_by_name(&self, name: &str) -> Result<Option<$($into_type)+>> {
114 self.data.get(name)
115 .ok_or(column_is_empty_err(name))
116 .and_then(|v| {
117 let &(ref col_type, ref bytes) = v;
118 let converted = as_rust_type!(col_type, bytes, $($into_type)+);
119 converted.map_err(|err| err.into())
120 })
121 }
122 }
123 );
124}
125
126#[macro_export]
127macro_rules! into_rust_by_index {
128 (Tuple, $($into_type:tt)+) => (
129 impl IntoRustByIndex<$($into_type)+> for Tuple {
130 fn get_by_index(&self, index: usize) -> Result<Option<$($into_type)+>> {
131 self.data
132 .get(index)
133 .ok_or(column_is_empty_err(index))
134 .and_then(|v| {
135 let &(ref col_type, ref bytes) = v;
136 let converted = as_rust_type!(col_type, bytes, $($into_type)+);
137 converted.map_err(|err| err.into())
138 })
139 }
140 }
141 );
142 (Row, $($into_type:tt)+) => (
143 impl IntoRustByIndex<$($into_type)+> for Row {
144 fn get_by_index(&self, index: usize) -> Result<Option<$($into_type)+>> {
145 self.get_col_spec_by_index(index)
146 .ok_or(column_is_empty_err(index))
147 .and_then(|(col_spec, cbytes)| {
148 let ref col_type = col_spec.col_type;
149 as_rust_type!(col_type, cbytes, $($into_type)+)
150 })
151 }
152 }
153 );
154}
155
156#[macro_export]
157macro_rules! as_res_opt {
158 ($data_value:ident, $deserialize:expr) => {
159 match $data_value.as_plain() {
160 Some(ref bytes) => ($deserialize)(bytes).map(|v| Some(v)).map_err(Into::into),
161 None => Ok(None),
162 }
163 };
164}
165
166#[macro_export]
170macro_rules! as_rust_type {
171 ($data_type_option:ident, $data_value:ident, Blob) => {
172 match $data_type_option.id {
173 ColType::Blob => as_res_opt!($data_value, decode_blob),
174 _ => Err(Error::General(format!(
175 "Invalid conversion. \
176 Cannot convert {:?} into Vec<u8> (valid types: Blob).",
177 $data_type_option.id
178 ))),
179 }
180 };
181 ($data_type_option:ident, $data_value:ident, String) => {
182 match $data_type_option.id {
183 ColType::Custom => as_res_opt!($data_value, decode_custom),
184 ColType::Ascii => as_res_opt!($data_value, decode_ascii),
185 ColType::Varchar => as_res_opt!($data_value, decode_varchar),
186 _ => Err(Error::General(format!(
191 "Invalid conversion. \
192 Cannot convert {:?} into String (valid types: Custom, Ascii, Varchar).",
193 $data_type_option.id
194 ))),
195 }
196 };
197 ($data_type_option:ident, $data_value:ident, bool) => {
198 match $data_type_option.id {
199 ColType::Boolean => as_res_opt!($data_value, decode_boolean),
200 _ => Err(Error::General(format!(
201 "Invalid conversion. \
202 Cannot convert {:?} into bool (valid types: Boolean).",
203 $data_type_option.id
204 ))),
205 }
206 };
207 ($data_type_option:ident, $data_value:ident, i64) => {
208 match $data_type_option.id {
209 ColType::Bigint => as_res_opt!($data_value, decode_bigint),
210 ColType::Timestamp => as_res_opt!($data_value, decode_timestamp),
211 ColType::Time => as_res_opt!($data_value, decode_time),
212 ColType::Varint => as_res_opt!($data_value, decode_varint),
213 ColType::Counter => as_res_opt!($data_value, decode_bigint),
214 _ => Err(Error::General(format!(
215 "Invalid conversion. \
216 Cannot convert {:?} into i64 (valid types: Bigint, Timestamp, Time, Variant,\
217 Counter).",
218 $data_type_option.id
219 ))),
220 }
221 };
222 ($data_type_option:ident, $data_value:ident, i32) => {
223 match $data_type_option.id {
224 ColType::Int => as_res_opt!($data_value, decode_int),
225 ColType::Date => as_res_opt!($data_value, decode_date),
226 _ => Err(Error::General(format!(
227 "Invalid conversion. \
228 Cannot convert {:?} into i32 (valid types: Int, Date).",
229 $data_type_option.id
230 ))),
231 }
232 };
233 ($data_type_option:ident, $data_value:ident, i16) => {
234 match $data_type_option.id {
235 ColType::Smallint => as_res_opt!($data_value, decode_smallint),
236 _ => Err(Error::General(format!(
237 "Invalid conversion. \
238 Cannot convert {:?} into i16 (valid types: Smallint).",
239 $data_type_option.id
240 ))),
241 }
242 };
243 ($data_type_option:ident, $data_value:ident, i8) => {
244 match $data_type_option.id {
245 ColType::Tinyint => as_res_opt!($data_value, decode_tinyint),
246 _ => Err(Error::General(format!(
247 "Invalid conversion. \
248 Cannot convert {:?} into i8 (valid types: Tinyint).",
249 $data_type_option.id
250 ))),
251 }
252 };
253 ($data_type_option:ident, $data_value:ident, f64) => {
254 match $data_type_option.id {
255 ColType::Double => as_res_opt!($data_value, decode_double),
256 _ => Err(Error::General(format!(
257 "Invalid conversion. \
258 Cannot convert {:?} into f64 (valid types: Double).",
259 $data_type_option.id
260 ))),
261 }
262 };
263 ($data_type_option:ident, $data_value:ident, f32) => {
264 match $data_type_option.id {
265 ColType::Float => as_res_opt!($data_value, decode_float),
266 _ => Err(Error::General(format!(
267 "Invalid conversion. \
268 Cannot convert {:?} into f32 (valid types: Float).",
269 $data_type_option.id
270 ))),
271 }
272 };
273 ($data_type_option:ident, $data_value:ident, IpAddr) => {
274 match $data_type_option.id {
275 ColType::Inet => as_res_opt!($data_value, decode_inet),
276 _ => Err(Error::General(format!(
277 "Invalid conversion. \
278 Cannot convert {:?} into IpAddr (valid types: Inet).",
279 $data_type_option.id
280 ))),
281 }
282 };
283 ($data_type_option:ident, $data_value:ident, Uuid) => {
284 match $data_type_option.id {
285 ColType::Uuid | ColType::Timeuuid => as_res_opt!($data_value, decode_timeuuid),
286 _ => Err(Error::General(format!(
287 "Invalid conversion. \
288 Cannot convert {:?} into Uuid (valid types: Uuid, Timeuuid).",
289 $data_type_option.id
290 ))),
291 }
292 };
293 ($data_type_option:ident, $data_value:ident, List) => {
294 match $data_type_option.id {
295 ColType::List | ColType::Set => match $data_value.as_slice() {
296 Some(ref bytes) => decode_list(bytes)
297 .map(|data| Some(List::new(data, $data_type_option.clone())))
298 .map_err(Into::into),
299 None => Ok(None),
300 },
301 _ => Err(Error::General(format!(
302 "Invalid conversion. \
303 Cannot convert {:?} into List (valid types: List, Set).",
304 $data_type_option.id
305 ))),
306 }
307 };
308 ($data_type_option:ident, $data_value:ident, Map) => {
309 match $data_type_option.id {
310 ColType::Map => match $data_value.as_slice() {
311 Some(ref bytes) => decode_map(bytes)
312 .map(|data| Some(Map::new(data, $data_type_option.clone())))
313 .map_err(Into::into),
314 None => Ok(None),
315 },
316 _ => Err(Error::General(format!(
317 "Invalid conversion. \
318 Cannot convert {:?} into Map (valid types: Map).",
319 $data_type_option.id
320 ))),
321 }
322 };
323 ($data_type_option:ident, $data_value:ident, UDT) => {
324 match *$data_type_option {
325 ColTypeOption {
326 id: ColType::Udt,
327 value: Some(ColTypeOptionValue::UdtType(ref list_type_option)),
328 } => match $data_value.as_slice() {
329 Some(ref bytes) => decode_udt(bytes, list_type_option.descriptions.len())
330 .map(|data| Some(UDT::new(data, list_type_option)))
331 .map_err(Into::into),
332 None => Ok(None),
333 },
334 _ => Err(Error::General(format!(
335 "Invalid conversion. \
336 Cannot convert {:?} into UDT (valid types: UDT).",
337 $data_type_option.id
338 ))),
339 }
340 };
341 ($data_type_option:ident, $data_value:ident, Tuple) => {
342 match *$data_type_option {
343 ColTypeOption {
344 id: ColType::Tuple,
345 value: Some(ColTypeOptionValue::TupleType(ref list_type_option)),
346 } => match $data_value.as_slice() {
347 Some(ref bytes) => decode_tuple(bytes, list_type_option.types.len())
348 .map(|data| Some(Tuple::new(data, list_type_option)))
349 .map_err(Into::into),
350 None => Ok(None),
351 },
352 _ => Err(Error::General(format!(
353 "Invalid conversion. \
354 Cannot convert {:?} into Tuple (valid types: tuple).",
355 $data_type_option.id
356 ))),
357 }
358 };
359 ($data_type_option:ident, $data_value:ident, Timespec) => {
360 match $data_type_option.id {
361 ColType::Timestamp => match $data_value.as_slice() {
362 Some(ref bytes) => decode_timestamp(bytes)
363 .map(|ts| Some(Timespec::new(ts / 1_000, (ts % 1_000 * 1_000_000) as i32)))
364 .map_err(Into::into),
365 None => Ok(None),
366 },
367 _ => Err(Error::General(format!(
368 "Invalid conversion. \
369 Cannot convert {:?} into Timespec (valid types: Timestamp).",
370 $data_type_option.id
371 ))),
372 }
373 };
374 ($data_type_option:ident, $data_value:ident, Decimal) => {
375 match $data_type_option.id {
376 ColType::Decimal => match $data_value.as_slice() {
377 Some(ref bytes) => decode_decimal(bytes).map(|d| Some(d)).map_err(Into::into),
378 None => Ok(None),
379 },
380 _ => Err(Error::General(format!(
381 "Invalid conversion. \
382 Cannot convert {:?} into Decimal (valid types: Decimal).",
383 $data_type_option.id
384 ))),
385 }
386 };
387}