const_format/macros.rs
1#[macro_use]
2mod assertions;
3
4#[macro_use]
5#[cfg(feature = "fmt")]
6mod call_debug_fmt;
7
8#[macro_use]
9mod constructors;
10
11#[macro_use]
12mod helper_macros;
13
14#[macro_use]
15mod fmt_macros;
16
17#[macro_use]
18#[cfg(feature = "fmt")]
19mod impl_fmt;
20
21#[macro_use]
22mod map_ascii_case;
23
24#[macro_use]
25mod str_methods;
26
27/// For returning early on an error, otherwise evaluating to `()`.
28///
29/// # Example
30///
31/// ```rust
32///
33/// use const_format::{Error, StrWriter};
34/// use const_format::{try_, writec};
35///
36/// const fn write_stuff(buffer: &mut StrWriter) -> Result<&[u8], Error> {
37/// try_!(writec!(buffer, "Foo{},Bar{},Baz{},", 8u32, 13u32, 21u32));
38/// Ok(buffer.as_bytes_alt())
39/// }
40///
41/// let mut buffer = StrWriter::new([0; 32]);
42/// assert_eq!(write_stuff(&mut buffer)?, "Foo8,Bar13,Baz21,".as_bytes());
43///
44/// # Ok::<(), Error>(())
45/// ```
46#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
47#[cfg(feature = "fmt")]
48#[macro_export]
49macro_rules! try_ {
50 ($e:expr) => {
51 if let $crate::pmr::Err(e) = $e {
52 return $crate::pmr::Err(e);
53 }
54 };
55}
56
57/// Equivalent to `Result::unwrap`, for use with [`const_format::Error`] errors.
58///
59/// You can use this when you know for certain that no error will happen.
60///
61/// [`const_format::Error`]: ./fmt/enum.Error.html
62///
63/// # Example
64///
65/// ```rust
66///
67/// use const_format::{StrWriter, unwrap, writec};
68///
69/// const CAP: usize = 11;
70/// const TEXT: &str = {
71/// const S: &StrWriter = &{
72/// let mut writer = StrWriter::new([0; CAP]);
73/// unwrap!(writec!(writer, "foo bar baz"));
74/// writer
75/// };
76/// S.as_str_alt()
77/// };
78/// assert_eq!(TEXT, "foo bar baz")
79///
80/// ```
81#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
82#[cfg(feature = "fmt")]
83#[macro_export]
84macro_rules! unwrap {
85 ($e:expr $(,)*) => {
86 match $e {
87 $crate::pmr::Ok(x) => x,
88 $crate::pmr::Err(error) => $crate::Error::unwrap(&error),
89 }
90 };
91}
92
93/// Equivalent to `Result::unwrap_or_else` but allows returning from the enclosing function.
94///
95/// # Examples
96///
97/// ### Early return
98///
99/// ```rust
100///
101/// use const_format::unwrap_or_else;
102///
103/// const fn unwrap_square(number: Result<u32, u32>) -> u64 {
104/// let n = unwrap_or_else!(number, |n| return n as u64 ) as u64;
105/// n * n
106/// }
107///
108/// assert_eq!(unwrap_square(Ok(10)), 100);
109/// assert_eq!(unwrap_square(Ok(30)), 900);
110/// assert_eq!(unwrap_square(Err(100)), 100);
111///
112/// ```
113///
114/// ### As unwrap_or
115///
116/// ```rust
117///
118/// use const_format::{AsciiStr, unwrap_or_else};
119///
120/// const FOO: AsciiStr = unwrap_or_else!(AsciiStr::new(b"AB\x80"), |_| AsciiStr::empty() );
121///
122/// const BAR: AsciiStr = unwrap_or_else!(AsciiStr::new(b"bar"), |_| loop{} );
123///
124/// assert_eq!(FOO.as_str(), "");
125/// assert_eq!(BAR.as_str(), "bar");
126///
127/// ```
128#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
129#[cfg(feature = "fmt")]
130#[macro_export]
131macro_rules! unwrap_or_else {
132 ($e:expr, |$($error:ident)? $(_)*| $orelse:expr ) => {
133 match $e {
134 $crate::pmr::Ok(x) => x,
135 $crate::pmr::Err($($error,)?..) => $orelse,
136 }
137 };
138}
139
140/// Coerces a reference to a type that has a `const_*_fmt` method.
141///
142/// # Behavior
143///
144/// For arrays it coerces them into a slice, and wraps them in a [`PWrapper`].
145///
146/// For std types, it wraps them in a [`PWrapper`], which implements the
147/// `const_*_fmt` methods.
148///
149/// For non-std types, it just returns back the same reference.
150///
151/// # Example
152///
153/// ```rust
154///
155/// use const_format::{
156/// for_examples::Unit,
157/// Formatter, FormattingFlags, PWrapper, StrWriter,
158/// coerce_to_fmt,
159/// };
160///
161/// const CAP: usize = 128;
162/// const fn make_strwriter() -> StrWriter<[u8; CAP]> {
163/// let mut writer = StrWriter::new([0; CAP]);
164/// let mut fmt = Formatter::from_sw(&mut writer, FormattingFlags::NEW);
165///
166/// // This is equivalent to the `PWrapper::slice(&[0u8, 1])` below
167/// let _ = coerce_to_fmt!([0u8, 1]).const_debug_fmt(&mut fmt);
168/// let _ = fmt.write_str(",");
169///
170/// let _ = PWrapper::slice(&[0u8, 1]).const_debug_fmt(&mut fmt);
171/// let _ = fmt.write_str(",");
172///
173///
174/// // This is equivalent to the `PWrapper(100u32)` line
175/// let _ = coerce_to_fmt!(100u32).const_debug_fmt(&mut fmt);
176/// let _ = fmt.write_str(",");
177///
178/// let _ = PWrapper(100u32).const_debug_fmt(&mut fmt);
179/// let _ = fmt.write_str(",");
180///
181///
182/// // This is equivalent to the `Unit.const_debug_fmt(&mut fmt)` line
183/// let _ = coerce_to_fmt!(Unit).const_debug_fmt(&mut fmt);
184///
185///
186/// let _ = fmt.write_str(",");
187/// let _ = Unit.const_debug_fmt(&mut fmt);
188///
189/// writer
190/// }
191///
192/// const TEXT: &str = {
193/// const TEXT_: &StrWriter = &make_strwriter();
194/// TEXT_.as_str_alt()
195/// };
196///
197/// assert_eq!(TEXT, "[0, 1],[0, 1],100,100,Unit,Unit");
198///
199/// ```
200///
201/// [`PWrapper`]: ./struct.PWrapper.html
202#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
203#[cfg(feature = "fmt")]
204#[macro_export]
205macro_rules! coerce_to_fmt {
206 ($reference:expr) => {{
207 match $reference {
208 ref reference => {
209 let marker = $crate::pmr::IsAFormatMarker::NEW;
210 if false {
211 marker.infer_type(reference);
212 }
213 marker.coerce(marker.unreference(reference))
214 }
215 }
216 }};
217}
218
219/// Converts a `&'static StrWriter` to a `&'static str`, in a `const`/`static` initializer.
220///
221/// This is usable in `const` or `static` initializers,
222/// but not inside of `const fn`s.
223///
224/// **Deprecated:** This macro is deprecated because
225/// the [`StrWriter::as_str_alt`](crate::StrWriter::as_str_alt) method
226/// allows converting a`&'static StrWriter` to a `&'static str`.
227///
228/// # Runtime
229///
230/// If the "rust_1_64" feature is disabled,
231/// this takes time proportional to `$expr.capacity() - $expr.len()`.
232///
233/// If the "rust_1_64" feature is enabled, it takes constant time to run.
234///
235/// # Example
236///
237/// ```rust
238///
239/// use const_format::StrWriter;
240/// use const_format::{strwriter_as_str, unwrap, writec};
241///
242///
243/// const CAP: usize = 128;
244///
245/// const __STR: &StrWriter = &{
246/// let mut writer = StrWriter::new([0; CAP]);
247///
248/// // Writing the array with debug formatting, and the integers with hexadecimal formatting.
249/// unwrap!(writec!(writer, "{:x}", [3u32, 5, 8, 13, 21, 34]));
250///
251/// writer
252/// };
253///
254/// const STR: &str = strwriter_as_str!(__STR);
255///
256/// fn main() {
257/// assert_eq!(STR, "[3, 5, 8, d, 15, 22]");
258/// }
259/// ```
260///
261#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
262#[cfg(feature = "fmt")]
263#[deprecated(since = "0.2.19", note = "Use `StrWriter::as_str_alt` instead")]
264#[macro_export]
265macro_rules! strwriter_as_str {
266 ($expr:expr) => {
267 unsafe {
268 let writer: &'static $crate::StrWriter = $expr;
269 #[allow(clippy::transmute_bytes_to_str)]
270 $crate::__priv_transmute_bytes_to_str!(writer.as_bytes_alt())
271 }
272 };
273}
274
275#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
276#[cfg(feature = "fmt")]
277macro_rules! conditionally_const {
278 (
279 feature = $feature:literal;
280 $(
281 $( #[$meta:meta] )*
282 $vis:vis fn $fn_name:ident ($($params:tt)*) -> $ret:ty $block:block
283 )*
284 ) => (
285 $(
286 $(#[$meta])*
287 #[cfg(feature = $feature)]
288 $vis const fn $fn_name ($($params)*) -> $ret $block
289
290 $(#[$meta])*
291 #[cfg(not(feature = $feature))]
292 $vis fn $fn_name ($($params)*) -> $ret $block
293 )*
294 )
295}
296
297#[cfg_attr(feature = "__docsrs", doc(cfg(feature = "fmt")))]
298#[cfg(feature = "fmt")]
299macro_rules! std_kind_impl {
300 (
301 impl[$($impl:tt)*] $self:ty
302 $(where[ $($where_:tt)* ])?
303 )=>{
304 impl<$($impl)*> $crate::pmr::FormatMarker for $self
305 where
306 $($($where_)*)?
307 {
308 type Kind = $crate::pmr::IsStdKind;
309 type This = Self;
310 }
311
312 impl<$($impl)* __T> $crate::pmr::IsAFormatMarker<$crate::pmr::IsStdKind, $self, __T>
313 where
314 $($($where_)*)?
315 {
316 #[inline(always)]
317 pub const fn coerce(self, reference: &$self) -> $crate::pmr::PWrapper<$self> {
318 $crate::pmr::PWrapper(*reference)
319 }
320 }
321 }
322}
323
324#[macro_export]
325#[doc(hidden)]
326macro_rules! __priv_transmute_bytes_to_str {
327 ($bytes:expr) => {{
328 let bytes: &'static [$crate::pmr::u8] = $bytes;
329 let string: &'static $crate::pmr::str = {
330 $crate::__hidden_utils::PtrToRef {
331 ptr: bytes as *const [$crate::pmr::u8] as *const str,
332 }
333 .reff
334 };
335 string
336 }};
337}
338
339#[macro_export]
340#[doc(hidden)]
341macro_rules! __priv_transmute_raw_bytes_to_str {
342 ($bytes:expr) => {{
343 let bytes: *const [$crate::pmr::u8] = $bytes;
344 let string: &'static $crate::pmr::str = {
345 $crate::__hidden_utils::PtrToRef {
346 ptr: bytes as *const str,
347 }
348 .reff
349 };
350 string
351 }};
352}