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