File Index
Files and directories
Sign in
FILE

format.rs

File preview with syntax highlighting.

linux-6.19.14/rust/quote/format.rs RUST
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3/// Formatting macro for constructing `Ident`s.
  4///
  5/// <br>
  6///
  7/// # Syntax
  8///
  9/// Syntax is copied from the [`format!`] macro, supporting both positional and
 10/// named arguments.
 11///
 12/// Only a limited set of formatting traits are supported. The current mapping
 13/// of format types to traits is:
 14///
 15/// * `{}` ⇒ [`IdentFragment`]
 16/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
 17/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
 18/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
 19/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
 20///
 21/// See [`std::fmt`] for more information.
 22///
 23/// <br>
 24///
 25/// # IdentFragment
 26///
 27/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
 28/// default. This trait is like `Display`, with a few differences:
 29///
 30/// * `IdentFragment` is only implemented for a limited set of types, such as
 31///   unsigned integers and strings.
 32/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
 33///
 34/// [`IdentFragment`]: crate::IdentFragment
 35/// [`Ident`]: proc_macro2::Ident
 36///
 37/// <br>
 38///
 39/// # Hygiene
 40///
 41/// The [`Span`] of the first `Ident` argument is used as the span of the final
 42/// identifier, falling back to [`Span::call_site`] when no identifiers are
 43/// provided.
 44///
 45/// ```
 46/// # use quote::format_ident;
 47/// # let ident = format_ident!("Ident");
 48/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
 49/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
 50/// assert_eq!(my_ident, "MyIdentIsCool");
 51/// ```
 52///
 53/// Alternatively, the span can be overridden by passing the `span` named
 54/// argument.
 55///
 56/// ```
 57/// # use quote::format_ident;
 58/// # const IGNORE_TOKENS: &'static str = stringify! {
 59/// let my_span = /* ... */;
 60/// # };
 61/// # let my_span = proc_macro2::Span::call_site();
 62/// format_ident!("MyIdent", span = my_span);
 63/// ```
 64///
 65/// [`Span`]: proc_macro2::Span
 66/// [`Span::call_site`]: proc_macro2::Span::call_site
 67///
 68/// <p><br></p>
 69///
 70/// # Panics
 71///
 72/// This method will panic if the resulting formatted string is not a valid
 73/// identifier.
 74///
 75/// <br>
 76///
 77/// # Examples
 78///
 79/// Composing raw and non-raw identifiers:
 80/// ```
 81/// # use quote::format_ident;
 82/// let my_ident = format_ident!("My{}", "Ident");
 83/// assert_eq!(my_ident, "MyIdent");
 84///
 85/// let raw = format_ident!("r#Raw");
 86/// assert_eq!(raw, "r#Raw");
 87///
 88/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
 89/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
 90/// ```
 91///
 92/// Integer formatting options:
 93/// ```
 94/// # use quote::format_ident;
 95/// let num: u32 = 10;
 96///
 97/// let decimal = format_ident!("Id_{}", num);
 98/// assert_eq!(decimal, "Id_10");
 99///
100/// let octal = format_ident!("Id_{:o}", num);
101/// assert_eq!(octal, "Id_12");
102///
103/// let binary = format_ident!("Id_{:b}", num);
104/// assert_eq!(binary, "Id_1010");
105///
106/// let lower_hex = format_ident!("Id_{:x}", num);
107/// assert_eq!(lower_hex, "Id_a");
108///
109/// let upper_hex = format_ident!("Id_{:X}", num);
110/// assert_eq!(upper_hex, "Id_A");
111/// ```
112#[macro_export]
113macro_rules! format_ident {
114    ($fmt:expr) => {
115        $crate::format_ident_impl!([
116            $crate::__private::Option::None,
117            $fmt
118        ])
119    };
120
121    ($fmt:expr, $($rest:tt)*) => {
122        $crate::format_ident_impl!([
123            $crate::__private::Option::None,
124            $fmt
125        ] $($rest)*)
126    };
127}
128
129#[macro_export]
130#[doc(hidden)]
131macro_rules! format_ident_impl {
132    // Final state
133    ([$span:expr, $($fmt:tt)*]) => {
134        $crate::__private::mk_ident(
135            &$crate::__private::format!($($fmt)*),
136            $span,
137        )
138    };
139
140    // Span argument
141    ([$old:expr, $($fmt:tt)*] span = $span:expr) => {
142        $crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
143    };
144    ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
145        $crate::format_ident_impl!([
146            $crate::__private::Option::Some::<$crate::__private::Span>($span),
147            $($fmt)*
148        ] $($rest)*)
149    };
150
151    // Named argument
152    ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
153        $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
154    };
155    ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
156        match $crate::__private::IdentFragmentAdapter(&$arg) {
157            arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
158        }
159    };
160
161    // Positional argument
162    ([$span:expr, $($fmt:tt)*] $arg:expr) => {
163        $crate::format_ident_impl!([$span, $($fmt)*] $arg,)
164    };
165    ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
166        match $crate::__private::IdentFragmentAdapter(&$arg) {
167            arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
168        }
169    };
170}
~/ Read-only file preview.