custom_print/macros/
writer_expr.rs

1/// Defines a writer expression from another expression, unsafe function or extern function.
2///
3/// If unsafe function specified as argument
4/// it just creates an `FnMut` wrapper that calls unsafe fn in unsafe block.
5/// The function can be specified by identifier or by braced full path.
6/// See [Safety](#safety) section for important details about safety.
7///
8/// If extern function specified as argument
9/// it creates extern block with this function and
10/// creates an `FnMut` wrapper that calls unsafe fn in unsafe block.
11/// See [Safety](#safety) section for important details about safety.
12///
13/// If an expression given as argument, the macro just returns it as a result.
14///
15/// This macro is used by [`define_writer`], [`define_try_writer`] macros.
16///
17/// # Safety
18///
19/// Note that writing using writer expression
20/// defined with `unsafe fn` or `extern `fn` do not require unsafe,
21/// so defining writer expression itself should be treated as an unsafe operation.
22///
23/// [`define_writer`]: macro.define_writer.htm
24/// [`define_try_writer`]: macro.define_try_writer.htm
25#[macro_export]
26macro_rules! define_writer_expr {
27    ( unsafe fn $func:ident($ty1:ty) $( -> $ret:ty)? ) => {
28        |arg1: $ty1| unsafe {
29            #[allow(unused_qualifications)]
30            $func(arg1)
31        }
32    };
33    ( unsafe fn ($func:path)($ty1:ty) $( -> $ret:ty)? ) => {
34        |arg1: $ty1| unsafe {
35            #[allow(unused_qualifications)]
36            $func(arg1)
37        }
38    };
39    ( unsafe fn $func:ident($ty1:ty, $ty2:ty) $( -> $ret:ty)? ) => {
40        |arg1: $ty1, arg2: $ty2| unsafe {
41            #[allow(unused_qualifications)]
42            $func(arg1, arg2)
43        }
44    };
45    ( unsafe fn ($func:path)($ty1:ty, $ty2:ty) $( -> $ret:ty)? ) => {
46        |arg1: $ty1, arg2: $ty2| unsafe {
47            #[allow(unused_qualifications)]
48            $func(arg1, arg2)
49        }
50    };
51    ( $(#[$extern_meta:meta])* extern $($abi:literal)?
52        $(#[$meta:meta])* fn $func:ident($arg1:tt: $ty1:ty) $( -> $ret:ty)?
53    ) => {{
54        $(#[$extern_meta])* extern $($abi)? {
55            $(#[$meta])* fn $func($arg1: $ty1) $( -> $ret)?;
56        }
57        |arg1: $ty1| unsafe { $func(arg1) }
58    }};
59    ( $(#[$extern_meta:meta])* extern $($abi:literal)?
60        $(#[$meta:meta])* fn $func:ident($arg1:tt: $ty1:ty, $arg2:tt: $ty2:ty) $( -> $ret:ty)?
61    ) => {{
62        $(#[$extern_meta])* extern $($abi)? {
63            $(#[$meta])* fn $func($arg1: $ty1, $arg2: $ty2) $( -> $ret)?;
64        }
65        |arg1: $ty1, arg2: $ty2| unsafe { $func(arg1, arg2) }
66    }};
67    ( $expr:expr ) => {
68        $expr
69    };
70}