1use crate::priv_prelude::*;
2
3#[derive(Clone, Debug, Serialize)]
4pub struct PathExpr {
5    pub root_opt: Option<(Option<AngleBrackets<QualifiedPathRoot>>, DoubleColonToken)>,
6    pub prefix: PathExprSegment,
7    pub suffix: Vec<(DoubleColonToken, PathExprSegment)>,
8    #[serde(skip_serializing)]
11    pub incomplete_suffix: bool,
12}
13
14#[derive(Clone, Debug, Serialize)]
15pub struct PathExprSegment {
16    pub name: Ident,
17    pub generics_opt: Option<(DoubleColonToken, GenericArgs)>,
18}
19
20impl PathExpr {
21    pub fn last_segment(&self) -> &PathExprSegment {
22        self.suffix
23            .iter()
24            .map(|s| &s.1)
25            .next_back()
26            .unwrap_or(&self.prefix)
27    }
28
29    pub fn last_segment_mut(&mut self) -> &mut PathExprSegment {
30        self.suffix
31            .iter_mut()
32            .map(|s| &mut s.1)
33            .next_back()
34            .unwrap_or(&mut self.prefix)
35    }
36}
37
38impl Spanned for PathExpr {
39    fn span(&self) -> Span {
40        let start = match &self.root_opt {
41            Some((qualified_path_root_opt, double_colon_token)) => match qualified_path_root_opt {
42                Some(qualified_path_root) => qualified_path_root.span(),
43                None => double_colon_token.span(),
44            },
45            None => self.prefix.span(),
46        };
47        let end = match self.suffix.last() {
48            Some((_, path_expr_segment)) => path_expr_segment.span(),
49            None => self.prefix.span(),
50        };
51        Span::join(start, &end)
52    }
53}
54
55impl PathExpr {
56    #[allow(clippy::result_large_err)]
57    pub fn try_into_ident(self) -> Result<Ident, PathExpr> {
58        if self.root_opt.is_none()
59            && self.suffix.is_empty()
60            && self.prefix.generics_opt.is_none()
61            && !self.incomplete_suffix
62        {
63            return Ok(self.prefix.name);
64        }
65        Err(self)
66    }
67}
68
69impl Spanned for PathExprSegment {
70    fn span(&self) -> Span {
71        let start = self.name.span();
72        match &self.generics_opt {
73            Some((_, generic_args)) => Span::join(start, &generic_args.span()),
74            None => start,
75        }
76    }
77}
78
79#[derive(Clone, Debug, Serialize)]
80pub struct PathType {
81    pub root_opt: Option<(Option<AngleBrackets<QualifiedPathRoot>>, DoubleColonToken)>,
82    pub prefix: PathTypeSegment,
83    pub suffix: Vec<(DoubleColonToken, PathTypeSegment)>,
84}
85
86impl PathType {
87    pub fn last_segment(&self) -> &PathTypeSegment {
88        self.suffix
89            .iter()
90            .map(|s| &s.1)
91            .next_back()
92            .unwrap_or(&self.prefix)
93    }
94
95    pub fn last_segment_mut(&mut self) -> &mut PathTypeSegment {
96        self.suffix
97            .iter_mut()
98            .map(|s| &mut s.1)
99            .next_back()
100            .unwrap_or(&mut self.prefix)
101    }
102}
103
104impl Spanned for PathType {
105    fn span(&self) -> Span {
106        let start = match &self.root_opt {
107            Some((qualified_path_root_opt, double_colon_token)) => match qualified_path_root_opt {
108                Some(qualified_path_root) => qualified_path_root.span(),
109                None => double_colon_token.span(),
110            },
111            None => self.prefix.span(),
112        };
113        let end = match self.suffix.last() {
114            Some((_, path_type_segment)) => path_type_segment.span(),
115            None => self.prefix.span(),
116        };
117        Span::join(start, &end)
118    }
119}
120
121#[derive(Clone, Debug, Serialize)]
122pub struct PathTypeSegment {
123    pub name: Ident,
124    pub generics_opt: Option<(Option<DoubleColonToken>, GenericArgs)>,
125}
126
127impl Spanned for PathTypeSegment {
128    fn span(&self) -> Span {
129        let start = self.name.span();
130        match &self.generics_opt {
131            Some((_, generic_args)) => Span::join(start, &generic_args.span()),
132            None => start,
133        }
134    }
135}
136
137#[derive(Clone, Debug, Serialize)]
138pub struct QualifiedPathRoot {
139    pub ty: Box<Ty>,
140    pub as_trait: (AsToken, Box<PathType>),
141}