1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
use proc_macro::TokenStream; /// Lazy format macro /// /// The first form receives closure as the only one argument. /// /// ``` /// # #![feature(proc_macro_hygiene)] /// # use format_core as format; /// # use format_macro::lazy_format; /// let a = "a"; /// lazy_format!(|f| write!(f, "{}", a)); /// ``` /// /// The second form is syntax sugar of the first form which is a closure with /// the only one [write](std::write) macro. Its syntax is identical to the /// [format](std::fmt::format) syntax. /// /// ``` /// # #![feature(proc_macro_hygiene)] /// # use format_core as format; /// # use format_macro::lazy_format; /// let a = "a"; /// lazy_format!("{}", a); /// ``` /// /// The second form inferences the output format. /// /// Format inference rules: /// /// - has only [Debug](core::fmt::Debug) formats - Debug /// - has formats of only one kind from: [Binary](core::fmt::Binary), /// [LowerExp](core::fmt::LowerExp), [LowerHex](core::fmt::LowerHex), /// [Octal](core::fmt::Octal), [Pointer](core::fmt::Pointer), /// [UpperExp](core::fmt::UpperExp) or [UpperHex](core::fmt::UpperHex) - /// Binary, LowerExp, LowerHex, Octal, Pointer, UpperExp or UpperHex /// respectively /// - otherwise - Display /// /// # Examples /// /// Nested Debug help struct example /// /// ``` /// #![feature(proc_macro_hygiene)] /// /// # mod format { /// # pub use format_core::*; /// # pub use format_macro::lazy_format; /// # } /// # use std::format; /// use core::fmt::{Debug, Formatter, Result}; /// use format::lazy_format; /// /// struct Foo { /// bar: [u32; 10], /// } /// /// impl Debug for Foo { /// fn fmt(&self, f: &mut Formatter) -> Result { /// let bar = lazy_format!(|f| f.debug_list().entries(&self.bar).finish()); /// f.debug_struct("Foo") /// .field("bar", &format_args!("{}", bar)) /// .finish() /// } /// } /// /// assert_eq!( /// "Foo { bar: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }", /// format!("{:?}", Foo { bar: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }) /// ); /// ``` /// /// Control flow example /// /// ``` /// #![feature(proc_macro_hygiene)] /// /// # mod format { /// # pub use format_core::*; /// # pub use format_macro::lazy_format; /// # } /// # use std::format; /// use core::fmt::{Debug, Formatter, Result}; /// use format::lazy_format; /// /// struct Foo(usize); /// /// impl Debug for Foo { /// fn fmt(&self, f: &mut Formatter) -> Result { /// let alternate = f.alternate(); /// let bar = lazy_format!(|f| if alternate { /// write!(f, "{:#x}", self.0) /// } else { /// write!(f, "{:x}", self.0) /// }); /// f.debug_tuple("Foo") /// .field(&format_args!("{}", bar)) /// .finish() /// } /// } /// /// assert_eq!("Foo(75bcd15)", format!("{:?}", Foo(0123456789))); /// assert_eq!("Foo(\n 0x75bcd15,\n)", format!("{:#?}", Foo(0123456789))); /// ``` #[proc_macro] pub fn lazy_format(input: TokenStream) -> TokenStream { lazy_format::proc_macro(input) } mod lazy_format;