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}