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
112
113
114
115
116
117
118
119
120
121
122
123
124
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Low-level formatting macro implementation.
//!
//! This module provides the `lformat!` macro which is used internally by logging macros
//! to transform format strings with key-value pairs into sequences of formatter calls.
use ;
use VecDeque;
use cratelformat_impl;
/// Low-level macro for generating formatter calls from format strings.
///
/// This macro is used internally by the logging macros to transform format strings
/// with key-value pairs into sequences of `write_literal()` and `write_val()` calls
/// on a formatter object. It's exposed publicly for advanced use cases but most users
/// should use the higher-level logging macros instead.
///
/// # Syntax
/// ```
/// # struct Formatter;
/// # impl Formatter {
/// # fn write_literal(&self, s: &str) {}
/// # fn write_val(&self, s: u8) {}
/// # }
/// # let format_ident = Formatter;
/// # use logwise_proc::lformat;
/// lformat!(format_ident, "format string with {key1} {key2}", key1=2, key2=3);
/// ```
///
/// # Arguments
/// * `formatter_ident` - The name of the formatter variable to call methods on
/// * `format_string` - A string literal with `{key}` placeholders
/// * `key=value` pairs - Values to substitute for placeholders in the format string
///
/// # Generated Code
/// The macro generates a sequence of method calls on the formatter:
/// - `formatter.write_literal("text")` for literal text portions
/// - `formatter.write_val(expression)` for placeholder values
///
/// # Examples
///
/// Basic usage with a mock formatter:
/// ```
/// # struct Logger;
/// # impl Logger {
/// # fn write_literal(&self, s: &str) {}
/// # fn write_val(&self, s: u8) {}
/// # }
/// # let logger = Logger;
/// use logwise_proc::lformat;
/// lformat!(logger,"Hello, {world}!", world=23);
/// ```
///
/// This expands to approximately:
/// ```ignore
/// # // ignore because: This shows macro expansion output, not actual runnable code
/// logger.write_literal("Hello, ");
/// logger.write_val(23);
/// logger.write_literal("!");
/// ```
///
/// Complex expressions as values:
/// ```
/// # struct Logger;
/// # impl Logger {
/// # fn write_literal(&self, s: &str) {}
/// # fn write_val<A>(&self, s: A) {}
/// # }
/// # let logger = Logger;
/// # use logwise_proc::lformat;
/// // This works with any expression
/// lformat!(logger, "User {a} has {b} items",
/// a = "hi",
/// b = 3);
/// ```
///
/// # Error Cases
///
/// Missing formatter identifier:
/// ```compile_fail
/// use logwise_proc::lformat;
/// lformat!(23);
/// ```
///
/// Missing key in format string:
/// ```compile_fail
/// # struct Logger;
/// # impl Logger {
/// # fn write_literal(&self, s: &str) {}
/// # fn write_val(&self, s: u8) {}
/// # }
/// # let logger = Logger;
/// use logwise_proc::lformat;
/// lformat!(logger, "Hello {missing}!", provided=123);
/// ```