aboutsummaryrefslogtreecommitdiff
path: root/syn-mid/src/path.rs
blob: 8093b53bd5c84c3a54f75cc87b6a6a020d7d9b40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
        },
    })
}