use syn::ext::IdentExt; use syn::parse::{ParseStream, Result}; use syn::{Ident, LitStr, Token}; pub struct QualifiedName { pub segments: Vec, } impl QualifiedName { pub fn parse_unquoted(input: ParseStream) -> Result { let mut segments = Vec::new(); let mut trailing_punct = true; let leading_colons: Option = input.parse()?; while trailing_punct && input.peek(Ident::peek_any) { let ident = Ident::parse_any(input)?; segments.push(ident); let colons: Option = input.parse()?; trailing_punct = colons.is_some(); } if segments.is_empty() && leading_colons.is_none() { return Err(input.error("expected path")); } else if trailing_punct { return Err(input.error("expected path segment")); } Ok(QualifiedName { segments }) } pub fn parse_quoted_or_unquoted(input: ParseStream) -> Result { if input.peek(LitStr) { let lit: LitStr = input.parse()?; if lit.value().is_empty() { let segments = Vec::new(); Ok(QualifiedName { segments }) } else { lit.parse_with(Self::parse_unquoted) } } else { Self::parse_unquoted(input) } } }