custom_print/macros/writer.rs
1/// Defines a writer from writer expression arguments or from the provided one.
2///
3/// If more than one argument is used, the first argument specifies the writer type,
4/// and the others are used to define the expression:
5/// - `concat, args...`: [`ConcatWriter`]`::from_closure(`[`define_writer_expr`]`!(args...))`
6/// - `fmt, args...`: [`FmtWriter`]`::from_closure(`[`define_writer_expr`]`!(args...))`
7/// - `io, args...`: [`IoWriter`]`::from_closure(`[`define_writer_expr`]`!(args...))`
8///
9/// If only one argument is used, the macro just returns it as a result.
10///
11/// Use [`define_try_writer`] if you need to define a fallible writer.
12/// This macro is used by [`define_printlike`], [`define_dbglike`] and [`define_flush`] macros.
13///
14/// # Examples
15///
16#[cfg_attr(feature = "alloc", doc = "```rust")]
17#[cfg_attr(not(feature = "alloc"), doc = "```rust,compile_fail")]
18/// use core::fmt::Write;
19///
20/// let mut expr_string = String::new();
21/// let mut expr_writer = custom_print::define_writer!(&mut expr_string);
22/// let mut concat_string = String::new();
23/// let mut concat_writer = custom_print::define_writer!(concat, |value: &str| {
24/// concat_string += value;
25/// });
26///
27/// assert_eq!(writeln!(expr_writer, "first"), Ok(()));
28/// assert_eq!(expr_string, "first\n");
29/// assert_eq!(writeln!(concat_writer, "second"), Ok(()));
30/// assert_eq!(concat_string, "second\n");
31/// ```
32///
33/// [`ConcatWriter`]: struct.ConcatTryWriter.html
34/// [`FmtWriter`]: struct.FmtTryWriter.html
35/// [`IoWriter`]: struct.IoTryWriter.html
36/// [`define_writer_expr`]: macro.define_writer_expr.html
37/// [`define_try_writer`]: macro.define_try_writer.html
38/// [`define_printlike`]: macro.define_printlike.html
39/// [`define_dbglike`]: macro.define_dbglike.html
40/// [`define_flush`]: macro.define_flush.html
41#[macro_export]
42macro_rules! define_writer {
43 ( concat, $($args:tt)* ) => {
44 $crate::ConcatWriter::from_closure($crate::define_writer_expr!($($args)*))
45 };
46 ( fmt, $($args:tt)* ) => {
47 $crate::FmtWriter::from_closure($crate::define_writer_expr!($($args)*))
48 };
49 ( io, $($args:tt)* ) => {
50 $crate::IoWriter::from_closure($crate::define_writer_expr!($($args)*))
51 };
52 ( $expr:expr ) => {
53 $expr
54 };
55}
56
57/// Defines a fallible writer from writer expression arguments or from the provided one.
58///
59/// If more than one argument is used, the first argument specifies the writer type,
60/// and the others are used to define the expression:
61/// - `concat, args...`: [`ConcatTryWriter`]`::from_closure(`[`define_writer_expr`]`!(args...))`
62/// - `fmt, args...`: [`FmtTryWriter`]`::from_closure(`[`define_writer_expr`]`!(args...))`
63/// - `io, args...`: [`IoTryWriter`]`::from_closure(`[`define_writer_expr`]`!(args...))`
64///
65/// If only one argument is used, the macro just returns it as a result.
66///
67/// Use [`define_writer`] if you need to define a non-fallible writer.
68/// This macro is used by [`define_printlike`], [`define_dbglike`] and [`define_try_flush`] macros.
69///
70/// # Examples
71///
72#[cfg_attr(feature = "alloc", doc = "```rust")]
73#[cfg_attr(not(feature = "alloc"), doc = "```rust,compile_fail")]
74/// use core::fmt::{self, Write};
75///
76/// let mut expr_string = String::new();
77/// let mut expr_writer = custom_print::define_try_writer!(&mut expr_string);
78/// let mut concat_string = String::new();
79/// let mut concat_writer = custom_print::define_writer!(concat, |value: &str| {
80/// concat_string += value;
81/// });
82/// let mut fallible_writer = custom_print::define_try_writer!(fmt, |_: &str| Err(fmt::Error));
83///
84/// assert_eq!(writeln!(expr_writer, "first"), Ok(()));
85/// assert_eq!(expr_string, "first\n");
86/// assert_eq!(writeln!(concat_writer, "second"), Ok(()));
87/// assert_eq!(concat_string, "second\n");
88/// assert_eq!(writeln!(fallible_writer, "third"), Err(fmt::Error));
89/// ```
90///
91/// [`ConcatTryWriter`]: struct.ConcatTryWriter.html
92/// [`FmtTryWriter`]: struct.FmtTryWriter.html
93/// [`IoTryWriter`]: struct.IoTryWriter.html
94/// [`define_writer_expr`]: macro.define_writer_expr.html
95/// [`define_writer`]: macro.define_writer.html
96/// [`define_printlike`]: macro.define_printlike.html
97/// [`define_dbglike`]: macro.define_dbglike.html
98/// [`define_try_flush`]: macro.define_try_flush.html
99#[macro_export]
100macro_rules! define_try_writer {
101 ( concat, $($args:tt)* ) => {
102 $crate::ConcatTryWriter::from_closure($crate::define_writer_expr!($($args)*))
103 };
104 ( fmt, $($args:tt)* ) => {
105 $crate::FmtTryWriter::from_closure($crate::define_writer_expr!($($args)*))
106 };
107 ( io, $($args:tt)* ) => {
108 $crate::IoTryWriter::from_closure($crate::define_writer_expr!($($args)*))
109 };
110 ( $expr:expr ) => {
111 $expr
112 };
113}