diff options
Diffstat (limited to 'syn-mid/src/path.rs')
-rw-r--r-- | syn-mid/src/path.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/syn-mid/src/path.rs b/syn-mid/src/path.rs new file mode 100644 index 0000000..8093b53 --- /dev/null +++ b/syn-mid/src/path.rs @@ -0,0 +1,50 @@ +use syn::{ + ext::IdentExt, + parse::{ParseStream, Result}, + punctuated::Punctuated, + Ident, Path, PathArguments, PathSegment, Token, +}; + +fn parse_path_segment(input: ParseStream<'_>) -> Result<PathSegment> { + if input.peek(Token![super]) + || input.peek(Token![self]) + || input.peek(Token![crate]) + || input.peek(Token![extern]) + { + let ident = input.call(Ident::parse_any)?; + return Ok(PathSegment::from(ident)); + } + + let ident = if input.peek(Token![Self]) { + input.call(Ident::parse_any)? + } else { + input.parse()? + }; + + if input.peek(Token![::]) && input.peek3(Token![<]) { + Ok(PathSegment { + ident, + arguments: PathArguments::AngleBracketed(input.parse()?), + }) + } else { + Ok(PathSegment::from(ident)) + } +} + +pub(crate) fn parse_path(input: ParseStream<'_>) -> Result<Path> { + Ok(Path { + leading_colon: input.parse()?, + segments: { + let mut segments = Punctuated::new(); + let value = parse_path_segment(input)?; + segments.push_value(value); + while input.peek(Token![::]) { + let punct: Token![::] = input.parse()?; + segments.push_punct(punct); + let value = parse_path_segment(input)?; + segments.push_value(value); + } + segments + }, + }) +} |