Macro macro_tools::prelude::custom_punctuation  
source · macro_rules! custom_punctuation { ($ident:ident, $($tt:tt)+) => { ... }; }
Expand description
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();
}