FILE
custom_punctuation.rs
File preview with syntax highlighting.
linux-6.19.14/rust/syn/custom_punctuation.rs
1// SPDX-License-Identifier: Apache-2.0 OR MIT 2 3/// Define a type that supports parsing and printing a multi-character symbol 4/// as if it were a punctuation token. 5/// 6/// # Usage 7/// 8/// ``` 9/// syn::custom_punctuation!(LeftRightArrow, <=>); 10/// ``` 11/// 12/// The generated syntax tree node supports the following operations just like 13/// any built-in punctuation token. 14/// 15/// - [Peeking] — `input.peek(LeftRightArrow)` 16/// 17/// - [Parsing] — `input.parse::<LeftRightArrow>()?` 18/// 19/// - [Printing] — `quote!( ... #lrarrow ... )` 20/// 21/// - Construction from a [`Span`] — `let lrarrow = LeftRightArrow(sp)` 22/// 23/// - Construction from multiple [`Span`] — `let lrarrow = LeftRightArrow([sp, sp, sp])` 24/// 25/// - Field access to its spans — `let spans = lrarrow.spans` 26/// 27/// [Peeking]: crate::parse::ParseBuffer::peek 28/// [Parsing]: crate::parse::ParseBuffer::parse 29/// [Printing]: quote::ToTokens 30/// [`Span`]: proc_macro2::Span 31/// 32/// # Example 33/// 34/// ``` 35/// use proc_macro2::{TokenStream, TokenTree}; 36/// use syn::parse::{Parse, ParseStream, Peek, Result}; 37/// use syn::punctuated::Punctuated; 38/// use syn::Expr; 39/// 40/// syn::custom_punctuation!(PathSeparator, </>); 41/// 42/// // expr </> expr </> expr ... 43/// struct PathSegments { 44/// segments: Punctuated<Expr, PathSeparator>, 45/// } 46/// 47/// impl Parse for PathSegments { 48/// fn parse(input: ParseStream) -> Result<Self> { 49/// let mut segments = Punctuated::new(); 50/// 51/// let first = parse_until(input, PathSeparator)?; 52/// segments.push_value(syn::parse2(first)?); 53/// 54/// while input.peek(PathSeparator) { 55/// segments.push_punct(input.parse()?); 56/// 57/// let next = parse_until(input, PathSeparator)?; 58/// segments.push_value(syn::parse2(next)?); 59/// } 60/// 61/// Ok(PathSegments { segments }) 62/// } 63/// } 64/// 65/// fn parse_until<E: Peek>(input: ParseStream, end: E) -> Result<TokenStream> { 66/// let mut tokens = TokenStream::new(); 67/// while !input.is_empty() && !input.peek(end) { 68/// let next: TokenTree = input.parse()?; 69/// tokens.extend(Some(next)); 70/// } 71/// Ok(tokens) 72/// } 73/// 74/// fn main() { 75/// let input = r#" a::b </> c::d::e "#; 76/// let _: PathSegments = syn::parse_str(input).unwrap(); 77/// } 78/// ``` 79#[macro_export] 80macro_rules! custom_punctuation { 81 ($ident:ident, $($tt:tt)+) => { 82 pub struct $ident { 83 #[allow(dead_code)] 84 pub spans: $crate::custom_punctuation_repr!($($tt)+), 85 } 86 87 #[doc(hidden)] 88 #[allow(dead_code, non_snake_case)] 89 pub fn $ident<__S: $crate::__private::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>( 90 spans: __S, 91 ) -> $ident { 92 let _validate_len = 0 $(+ $crate::custom_punctuation_len!(strict, $tt))*; 93 $ident { 94 spans: $crate::__private::IntoSpans::into_spans(spans) 95 } 96 } 97 98 const _: () = { 99 impl $crate::__private::Default for $ident { 100 fn default() -> Self { 101 $ident($crate::__private::Span::call_site()) 102 } 103 } 104 105 $crate::impl_parse_for_custom_punctuation!($ident, $($tt)+); 106 $crate::impl_to_tokens_for_custom_punctuation!($ident, $($tt)+); 107 $crate::impl_clone_for_custom_punctuation!($ident, $($tt)+); 108 $crate::impl_extra_traits_for_custom_punctuation!($ident, $($tt)+); 109 }; 110 }; 111} 112 113// Not public API. 114#[cfg(feature = "parsing")] 115#[doc(hidden)] 116#[macro_export] 117macro_rules! impl_parse_for_custom_punctuation { 118 ($ident:ident, $($tt:tt)+) => { 119 impl $crate::__private::CustomToken for $ident { 120 fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { 121 $crate::__private::peek_punct(cursor, $crate::stringify_punct!($($tt)+)) 122 } 123 124 fn display() -> &'static $crate::__private::str { 125 $crate::__private::concat!("`", $crate::stringify_punct!($($tt)+), "`") 126 } 127 } 128 129 impl $crate::parse::Parse for $ident { 130 fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { 131 let spans: $crate::custom_punctuation_repr!($($tt)+) = 132 $crate::__private::parse_punct(input, $crate::stringify_punct!($($tt)+))?; 133 Ok($ident(spans)) 134 } 135 } 136 }; 137} 138 139// Not public API. 140#[cfg(not(feature = "parsing"))] 141#[doc(hidden)] 142#[macro_export] 143macro_rules! impl_parse_for_custom_punctuation { 144 ($ident:ident, $($tt:tt)+) => {}; 145} 146 147// Not public API. 148#[cfg(feature = "printing")] 149#[doc(hidden)] 150#[macro_export] 151macro_rules! impl_to_tokens_for_custom_punctuation { 152 ($ident:ident, $($tt:tt)+) => { 153 impl $crate::__private::ToTokens for $ident { 154 fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { 155 $crate::__private::print_punct($crate::stringify_punct!($($tt)+), &self.spans, tokens) 156 } 157 } 158 }; 159} 160 161// Not public API. 162#[cfg(not(feature = "printing"))] 163#[doc(hidden)] 164#[macro_export] 165macro_rules! impl_to_tokens_for_custom_punctuation { 166 ($ident:ident, $($tt:tt)+) => {}; 167} 168 169// Not public API. 170#[cfg(feature = "clone-impls")] 171#[doc(hidden)] 172#[macro_export] 173macro_rules! impl_clone_for_custom_punctuation { 174 ($ident:ident, $($tt:tt)+) => { 175 impl $crate::__private::Copy for $ident {} 176 177 #[allow(clippy::expl_impl_clone_on_copy)] 178 impl $crate::__private::Clone for $ident { 179 fn clone(&self) -> Self { 180 *self 181 } 182 } 183 }; 184} 185 186// Not public API. 187#[cfg(not(feature = "clone-impls"))] 188#[doc(hidden)] 189#[macro_export] 190macro_rules! impl_clone_for_custom_punctuation { 191 ($ident:ident, $($tt:tt)+) => {}; 192} 193 194// Not public API. 195#[cfg(feature = "extra-traits")] 196#[doc(hidden)] 197#[macro_export] 198macro_rules! impl_extra_traits_for_custom_punctuation { 199 ($ident:ident, $($tt:tt)+) => { 200 impl $crate::__private::Debug for $ident { 201 fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult { 202 $crate::__private::Formatter::write_str(f, $crate::__private::stringify!($ident)) 203 } 204 } 205 206 impl $crate::__private::Eq for $ident {} 207 208 impl $crate::__private::PartialEq for $ident { 209 fn eq(&self, _other: &Self) -> $crate::__private::bool { 210 true 211 } 212 } 213 214 impl $crate::__private::Hash for $ident { 215 fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} 216 } 217 }; 218} 219 220// Not public API. 221#[cfg(not(feature = "extra-traits"))] 222#[doc(hidden)] 223#[macro_export] 224macro_rules! impl_extra_traits_for_custom_punctuation { 225 ($ident:ident, $($tt:tt)+) => {}; 226} 227 228// Not public API. 229#[doc(hidden)] 230#[macro_export] 231macro_rules! custom_punctuation_repr { 232 ($($tt:tt)+) => { 233 [$crate::__private::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+] 234 }; 235} 236 237// Not public API. 238#[doc(hidden)] 239#[macro_export] 240#[rustfmt::skip] 241macro_rules! custom_punctuation_len { 242 ($mode:ident, &) => { 1 }; 243 ($mode:ident, &&) => { 2 }; 244 ($mode:ident, &=) => { 2 }; 245 ($mode:ident, @) => { 1 }; 246 ($mode:ident, ^) => { 1 }; 247 ($mode:ident, ^=) => { 2 }; 248 ($mode:ident, :) => { 1 }; 249 ($mode:ident, ,) => { 1 }; 250 ($mode:ident, $) => { 1 }; 251 ($mode:ident, .) => { 1 }; 252 ($mode:ident, ..) => { 2 }; 253 ($mode:ident, ...) => { 3 }; 254 ($mode:ident, ..=) => { 3 }; 255 ($mode:ident, =) => { 1 }; 256 ($mode:ident, ==) => { 2 }; 257 ($mode:ident, =>) => { 2 }; 258 ($mode:ident, >=) => { 2 }; 259 ($mode:ident, >) => { 1 }; 260 ($mode:ident, <-) => { 2 }; 261 ($mode:ident, <=) => { 2 }; 262 ($mode:ident, <) => { 1 }; 263 ($mode:ident, -) => { 1 }; 264 ($mode:ident, -=) => { 2 }; 265 ($mode:ident, !=) => { 2 }; 266 ($mode:ident, !) => { 1 }; 267 ($mode:ident, |) => { 1 }; 268 ($mode:ident, |=) => { 2 }; 269 ($mode:ident, ||) => { 2 }; 270 ($mode:ident, ::) => { 2 }; 271 ($mode:ident, %) => { 1 }; 272 ($mode:ident, %=) => { 2 }; 273 ($mode:ident, +) => { 1 }; 274 ($mode:ident, +=) => { 2 }; 275 ($mode:ident, #) => { 1 }; 276 ($mode:ident, ?) => { 1 }; 277 ($mode:ident, ->) => { 2 }; 278 ($mode:ident, ;) => { 1 }; 279 ($mode:ident, <<) => { 2 }; 280 ($mode:ident, <<=) => { 3 }; 281 ($mode:ident, >>) => { 2 }; 282 ($mode:ident, >>=) => { 3 }; 283 ($mode:ident, /) => { 1 }; 284 ($mode:ident, /=) => { 2 }; 285 ($mode:ident, *) => { 1 }; 286 ($mode:ident, *=) => { 2 }; 287 ($mode:ident, ~) => { 1 }; 288 (lenient, $tt:tt) => { 0 }; 289 (strict, $tt:tt) => {{ $crate::custom_punctuation_unexpected!($tt); 0 }}; 290} 291 292// Not public API. 293#[doc(hidden)] 294#[macro_export] 295macro_rules! custom_punctuation_unexpected { 296 () => {}; 297} 298 299// Not public API. 300#[doc(hidden)] 301#[macro_export] 302macro_rules! stringify_punct { 303 ($($tt:tt)+) => { 304 $crate::__private::concat!($($crate::__private::stringify!($tt)),+) 305 }; 306}
~/
Read-only file preview.