data_buffer/
macros.rs

1//! Utility macros for code generation.
2
3#![macro_use]
4
5/// Applies `$fn` to an `DataBuffer` mapping valid numeric data types by corresponding generic
6/// parameters.  For example, passing an `DataBuffer` containing data of type `u8` will cause this
7/// macro to call `$fn` with type parameter `u8` like `$fn::<u8>(buffer)`.
8/// # Examples
9/// ```rust
10/// # #[macro_use] extern crate data_buffer as buf;
11/// # use std::fmt;
12/// # use std::any::Any;
13/// # use buf::DataBuffer;
14/// # fn main() {
15/// // Implement pretty printing of a `DataBuffer` derivative for numeric buffers.
16/// struct MyBuffer(DataBuffer);
17/// impl fmt::Display for MyBuffer {
18///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19///         unsafe fn display_buf<T: Any + fmt::Display>(buf: &DataBuffer, f: &mut fmt::Formatter) {
20///             for item in buf.iter::<T>().unwrap() {
21///                 write!(f, "{} ", item)
22///                     .expect("Error occurred while writing MyBuffer.");
23///             }
24///         }
25///         call_numeric_buffer_fn!( display_buf::<_>(&self.0, f) or {});
26///         write!(f, "")
27///     }
28/// }
29/// # }
30/// ```
31#[macro_export]
32macro_rules! call_numeric_buffer_fn {
33    ($fn:ident ::<_,$($params:ident),*>( $data:expr, $($args:expr),* ) or $err:block ) => {
34        {
35            let buf = $data;
36            unsafe {
37                match buf.element_type_id() {
38                    x if x == ::std::any::TypeId::of::<u8>() =>  $fn::<u8,$($params),*> (buf, $($args),*),
39                    x if x == ::std::any::TypeId::of::<i8>() =>  $fn::<i8,$($params),*> (buf, $($args),*),
40                    x if x == ::std::any::TypeId::of::<u16>() => $fn::<u16,$($params),*>(buf, $($args),*),
41                    x if x == ::std::any::TypeId::of::<i16>() => $fn::<i16,$($params),*>(buf, $($args),*),
42                    x if x == ::std::any::TypeId::of::<u32>() => $fn::<u32,$($params),*>(buf, $($args),*),
43                    x if x == ::std::any::TypeId::of::<i32>() => $fn::<i32,$($params),*>(buf, $($args),*),
44                    x if x == ::std::any::TypeId::of::<u64>() => $fn::<u64,$($params),*>(buf, $($args),*),
45                    x if x == ::std::any::TypeId::of::<i64>() => $fn::<i64,$($params),*>(buf, $($args),*),
46                    x if x == ::std::any::TypeId::of::<f32>() => $fn::<f32,$($params),*>(buf, $($args),*),
47                    x if x == ::std::any::TypeId::of::<f64>() => $fn::<f64,$($params),*>(buf, $($args),*),
48                    _ => $err,
49                }
50            }
51        }
52    };
53    // Same thing as above but with one parameter argument.
54    ($fn:ident ::<_>( $($args:expr),* ) or $err:block ) => {
55        call_numeric_buffer_fn!($fn ::<_,>( $($args),* ) or $err )
56    };
57    // Same thing as above but with one function argument.
58    ($fn:ident ::<_,$($params:ident),*>( $data:expr ) or $err:block ) => {
59        call_numeric_buffer_fn!($fn ::<_,$($params),*>( $data, ) or $err )
60    };
61    // Using method synax for member functions if any.
62    ($data:ident . $fn:ident ::<_,$($params:ident),*>( $($args:expr),* ) or $err:block ) => {
63        {
64            let buf = $data;
65            unsafe {
66                match buf.element_type_id() {
67                    x if x == ::std::any::TypeId::of::<u8>() =>  buf.$fn::<u8,$($params),*> ($($args),*),
68                    x if x == ::std::any::TypeId::of::<i8>() =>  buf.$fn::<i8,$($params),*> ($($args),*),
69                    x if x == ::std::any::TypeId::of::<u16>() => buf.$fn::<u16,$($params),*>($($args),*),
70                    x if x == ::std::any::TypeId::of::<i16>() => buf.$fn::<i16,$($params),*>($($args),*),
71                    x if x == ::std::any::TypeId::of::<u32>() => buf.$fn::<u32,$($params),*>($($args),*),
72                    x if x == ::std::any::TypeId::of::<i32>() => buf.$fn::<i32,$($params),*>($($args),*),
73                    x if x == ::std::any::TypeId::of::<u64>() => buf.$fn::<u64,$($params),*>($($args),*),
74                    x if x == ::std::any::TypeId::of::<i64>() => buf.$fn::<i64,$($params),*>($($args),*),
75                    x if x == ::std::any::TypeId::of::<f32>() => buf.$fn::<f32,$($params),*>($($args),*),
76                    x if x == ::std::any::TypeId::of::<f64>() => buf.$fn::<f64,$($params),*>($($args),*),
77                    _ => $err,
78                }
79            }
80        }
81    };
82    // Same as above but with one parameter argument.
83    ($data:ident . $fn:ident ::<_>( $($args:expr),* ) or $err:block ) => {
84        call_numeric_buffer_fn!($data . $fn ::<_,>( $($args),* ) or $err )
85    };
86}