[−][src]Macro syn::custom_punctuation
Define a type that supports parsing and printing a multi-character symbol as if it were a punctuation token.
Usage
syn::custom_punctuation!(LeftRightArrow, <=>);
The generated syntax tree node supports the following operations just like any built-in punctuation token.
-
Peeking —
input.peek(LeftRightArrow)
-
Parsing —
input.parse::<LeftRightArrow>()?
-
Printing —
quote!( ... #lrarrow ... )
-
Construction from a
Span
—let lrarrow = LeftRightArrow(sp)
-
Construction from multiple
Span
—let lrarrow = LeftRightArrow([sp, sp, sp])
-
Field access to its spans —
let spans = lrarrow.spans
Example
use proc_macro2::{TokenStream, TokenTree}; use syn::parse::{Parse, ParseStream, Peek, Result}; use syn::punctuated::Punctuated; use syn::Expr; syn::custom_punctuation!(PathSeparator, </>); // expr </> expr </> expr ... struct PathSegments { segments: Punctuated<Expr, PathSeparator>, } impl Parse for PathSegments { fn parse(input: ParseStream) -> Result<Self> { let mut segments = Punctuated::new(); let first = parse_until(input, PathSeparator)?; segments.push_value(syn::parse2(first)?); while input.peek(PathSeparator) { segments.push_punct(input.parse()?); let next = parse_until(input, PathSeparator)?; segments.push_value(syn::parse2(next)?); } Ok(PathSegments { segments }) } } fn parse_until<E: Peek>(input: ParseStream, end: E) -> Result<TokenStream> { let mut tokens = TokenStream::new(); while !input.is_empty() && !input.peek(end) { let next: TokenTree = input.parse()?; tokens.extend(Some(next)); } Ok(tokens) } fn main() { let input = r#" a::b </> c::d::e "#; let _: PathSegments = syn::parse_str(input).unwrap(); }