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 .last()
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 .last()
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 pub fn try_into_ident(self) -> Result<Ident, PathExpr> {
57 if self.root_opt.is_none()
58 && self.suffix.is_empty()
59 && self.prefix.generics_opt.is_none()
60 && !self.incomplete_suffix
61 {
62 return Ok(self.prefix.name);
63 }
64 Err(self)
65 }
66}
67
68impl Spanned for PathExprSegment {
69 fn span(&self) -> Span {
70 let start = self.name.span();
71 match &self.generics_opt {
72 Some((_, generic_args)) => Span::join(start, &generic_args.span()),
73 None => start,
74 }
75 }
76}
77
78#[derive(Clone, Debug, Serialize)]
79pub struct PathType {
80 pub root_opt: Option<(Option<AngleBrackets<QualifiedPathRoot>>, DoubleColonToken)>,
81 pub prefix: PathTypeSegment,
82 pub suffix: Vec<(DoubleColonToken, PathTypeSegment)>,
83}
84
85impl PathType {
86 pub fn last_segment(&self) -> &PathTypeSegment {
87 self.suffix
88 .iter()
89 .map(|s| &s.1)
90 .last()
91 .unwrap_or(&self.prefix)
92 }
93
94 pub fn last_segment_mut(&mut self) -> &mut PathTypeSegment {
95 self.suffix
96 .iter_mut()
97 .map(|s| &mut s.1)
98 .last()
99 .unwrap_or(&mut self.prefix)
100 }
101}
102
103impl Spanned for PathType {
104 fn span(&self) -> Span {
105 let start = match &self.root_opt {
106 Some((qualified_path_root_opt, double_colon_token)) => match qualified_path_root_opt {
107 Some(qualified_path_root) => qualified_path_root.span(),
108 None => double_colon_token.span(),
109 },
110 None => self.prefix.span(),
111 };
112 let end = match self.suffix.last() {
113 Some((_, path_type_segment)) => path_type_segment.span(),
114 None => self.prefix.span(),
115 };
116 Span::join(start, &end)
117 }
118}
119
120#[derive(Clone, Debug, Serialize)]
121pub struct PathTypeSegment {
122 pub name: Ident,
123 pub generics_opt: Option<(Option<DoubleColonToken>, GenericArgs)>,
124}
125
126impl Spanned for PathTypeSegment {
127 fn span(&self) -> Span {
128 let start = self.name.span();
129 match &self.generics_opt {
130 Some((_, generic_args)) => Span::join(start, &generic_args.span()),
131 None => start,
132 }
133 }
134}
135
136#[derive(Clone, Debug, Serialize)]
137pub struct QualifiedPathRoot {
138 pub ty: Box<Ty>,
139 pub as_trait: (AsToken, Box<PathType>),
140}