Skip to main content

rustidy_ast/expr/without_block/
path.rs

1//! Path expression
2
3use {
4	crate::{
5		expr::with_block::BlockExpression,
6		item::function::TypeParamBounds,
7		lifetime::Lifetime,
8		path::SimplePathSegment,
9		token,
10		ty::{Type, TypeNoBounds, TypePath, path::TypePathSegment},
11		util::Parenthesized,
12	},
13	super::LiteralExpression,
14	rustidy_ast_util::{
15		AtLeast1,
16		Delimited,
17		Identifier,
18		Longest,
19		Punctuated,
20		PunctuatedTrailing,
21		at_least,
22		delimited,
23		punct,
24	},
25	rustidy_format::{Format, Formattable, WhitespaceFormat},
26	rustidy_parse::Parse,
27	rustidy_print::Print,
28	rustidy_util::Whitespace,
29};
30
31/// `PathExpression`
32#[derive(PartialEq, Eq, Clone, Debug)]
33#[derive(serde::Serialize, serde::Deserialize)]
34#[derive(Parse, Formattable, Format, Print)]
35pub enum PathExpression {
36	Normal(PathInExpression),
37	Qualified(QualifiedPathInExpression),
38}
39
40/// `PathInExpression`
41#[derive(PartialEq, Eq, Clone, Debug)]
42#[derive(serde::Serialize, serde::Deserialize)]
43#[derive(Parse, Formattable, Format, Print)]
44pub struct PathInExpression {
45	pub prefix:   Option<token::PathSep>,
46	#[format(prefix_ws(expr = Whitespace::REMOVE, if_ = self.prefix.is_some()))]
47	#[format(args = punct::fmt(Whitespace::REMOVE, Whitespace::REMOVE))]
48	pub segments: Punctuated<PathExprSegment, token::PathSep>,
49}
50
51/// `PathExprSegment`
52#[derive(PartialEq, Eq, Clone, Debug)]
53#[derive(serde::Serialize, serde::Deserialize)]
54#[derive(Parse, Formattable, Format, Print)]
55pub struct PathExprSegment {
56	pub ident:   PathIdentSegment,
57	#[format(prefix_ws = Whitespace::REMOVE)]
58	pub generic: Option<PathExprSegmentGenericArgs>,
59}
60
61#[derive(PartialEq, Eq, Clone, Debug)]
62#[derive(serde::Serialize, serde::Deserialize)]
63#[derive(Parse, Formattable, Format, Print)]
64pub struct PathExprSegmentGenericArgs {
65	pub sep:     token::PathSep,
66	#[format(prefix_ws = Whitespace::REMOVE)]
67	pub generic: GenericArgs,
68}
69
70/// `PathIdentSegment`
71#[derive(PartialEq, Eq, Clone, Debug)]
72#[derive(serde::Serialize, serde::Deserialize)]
73#[derive(Parse, Formattable, Format, Print)]
74pub enum PathIdentSegment {
75	Super(token::Super),
76	SelfLower(token::SelfLower),
77	SelfUpper(token::SelfUpper),
78	Crate(token::Crate),
79	DollarCrate(token::DollarCrate),
80	Ident(Identifier),
81}
82
83/// `GenericArgs`
84#[derive(PartialEq, Eq, Clone, Debug)]
85#[derive(serde::Serialize, serde::Deserialize)]
86#[derive(Parse, Formattable, Format, Print)]
87#[parse(name = "generic arguments")]
88pub struct GenericArgs(
89	#[format(args = delimited::FmtRemove)]
90	pub Delimited<Option<GenericArgsInner>, token::Lt, token::Gt>,
91);
92
93#[derive(PartialEq, Eq, Clone, Debug)]
94#[derive(serde::Serialize, serde::Deserialize)]
95#[derive(Parse, Formattable, Format, Print)]
96pub struct GenericArgsInner(
97	#[format(args = punct::fmt(Whitespace::SINGLE, Whitespace::REMOVE))]
98	pub PunctuatedTrailing<GenericArg, token::Comma>,
99);
100
101/// `GenericArg`
102#[derive(PartialEq, Eq, Clone, Debug)]
103#[derive(serde::Serialize, serde::Deserialize)]
104#[derive(Parse, Formattable, Format, Print)]
105pub enum GenericArg {
106	Lifetime(Lifetime),
107
108	Binding(GenericArgsBinding),
109	Bounds(GenericArgsBounds),
110
111	// TODO: Unmerge these with some attribute
112	TypeOrConst(Longest<Box<Type>, GenericArgsConst>),
113}
114
115/// `GenericArgsConst`
116#[derive(PartialEq, Eq, Clone, Debug)]
117#[derive(serde::Serialize, serde::Deserialize)]
118#[derive(Parse, Formattable, Format, Print)]
119pub enum GenericArgsConst {
120	Block(Box<BlockExpression>),
121	Literal(LiteralExpression),
122	NegLiteral((token::Minus, LiteralExpression)),
123	Path(SimplePathSegment),
124}
125
126/// `GenericArgsBinding`
127#[derive(PartialEq, Eq, Clone, Debug)]
128#[derive(serde::Serialize, serde::Deserialize)]
129#[derive(Parse, Formattable, Format, Print)]
130pub struct GenericArgsBinding {
131	pub ident:    Identifier,
132	#[format(prefix_ws = Whitespace::REMOVE)]
133	pub generics: Option<Box<GenericArgs>>,
134	#[format(prefix_ws = Whitespace::SINGLE)]
135	pub eq:       token::Eq,
136	#[parse(fatal)]
137	#[format(prefix_ws = Whitespace::SINGLE)]
138	pub ty:       Box<Type>,
139}
140
141/// `GenericArgsBounds`
142#[derive(PartialEq, Eq, Clone, Debug)]
143#[derive(serde::Serialize, serde::Deserialize)]
144#[derive(Parse, Formattable, Format, Print)]
145pub struct GenericArgsBounds {
146	pub ident:    Identifier,
147	#[format(prefix_ws = Whitespace::REMOVE)]
148	pub generics: Option<Box<GenericArgs>>,
149	#[format(prefix_ws = Whitespace::REMOVE)]
150	pub colon:    token::Colon,
151	#[parse(fatal)]
152	#[format(prefix_ws = Whitespace::SINGLE)]
153	pub ty:       Box<TypeParamBounds>,
154}
155
156/// `TypePathFn`
157#[derive(PartialEq, Eq, Clone, Debug)]
158#[derive(serde::Serialize, serde::Deserialize)]
159#[derive(Parse, Formattable, Format, Print)]
160pub struct TypePathFn {
161	#[format(args = delimited::FmtRemove)]
162	pub inputs: Parenthesized<Option<TypePathFnInputs>>,
163	#[format(prefix_ws = Whitespace::SINGLE)]
164	pub ret:    Option<TypePathFnRet>,
165}
166
167/// `TypePathFnInputs`
168#[derive(PartialEq, Eq, Clone, Debug)]
169#[derive(serde::Serialize, serde::Deserialize)]
170#[derive(Parse, Formattable, Format, Print)]
171pub struct TypePathFnInputs(
172	#[format(args = punct::fmt(Whitespace::REMOVE, Whitespace::REMOVE))]
173	PunctuatedTrailing<Box<Type>, token::Comma>,
174);
175
176#[derive(PartialEq, Eq, Clone, Debug)]
177#[derive(serde::Serialize, serde::Deserialize)]
178#[derive(Parse, Formattable, Format, Print)]
179pub struct TypePathFnRet {
180	pub arrow: token::RArrow,
181	#[format(prefix_ws = Whitespace::SINGLE)]
182	pub ty:    Box<TypeNoBounds>,
183}
184
185/// `QualifiedPathInExpression`
186#[derive(PartialEq, Eq, Clone, Debug)]
187#[derive(serde::Serialize, serde::Deserialize)]
188#[derive(Parse, Formattable, Format, Print)]
189pub struct QualifiedPathInExpression {
190	pub qualified: QualifiedPathType,
191	#[format(prefix_ws = Whitespace::REMOVE)]
192	#[format(args = at_least::fmt_prefix_ws(Whitespace::REMOVE))]
193	pub segments:  AtLeast1<QualifiedPathInExpressionSegment>,
194}
195
196#[derive(PartialEq, Eq, Clone, Debug)]
197#[derive(serde::Serialize, serde::Deserialize)]
198#[derive(Parse, Formattable, Format, Print)]
199pub struct QualifiedPathInExpressionSegment {
200	sep:     token::PathSep,
201	#[format(prefix_ws = Whitespace::REMOVE)]
202	segment: PathExprSegment,
203}
204
205/// `QualifiedPathType`
206#[derive(PartialEq, Eq, Clone, Debug)]
207#[derive(serde::Serialize, serde::Deserialize)]
208#[derive(Parse, Formattable, Format, Print)]
209pub struct QualifiedPathType(
210	#[format(args = delimited::FmtRemove)]
211	Delimited<QualifiedPathTypeInner, token::Lt, token::Gt>,
212);
213
214#[derive(PartialEq, Eq, Clone, Debug)]
215#[derive(serde::Serialize, serde::Deserialize)]
216#[derive(Parse, Formattable, Format, Print)]
217pub struct QualifiedPathTypeInner {
218	pub ty:  Box<Type>,
219	#[format(prefix_ws = Whitespace::SINGLE)]
220	pub as_: Option<QualifiedPathTypeAs>,
221}
222
223#[derive(PartialEq, Eq, Clone, Debug)]
224#[derive(serde::Serialize, serde::Deserialize)]
225#[derive(Parse, Formattable, Format, Print)]
226pub struct QualifiedPathTypeAs {
227	pub as_: token::As,
228	#[format(prefix_ws = Whitespace::SINGLE)]
229	pub ty:  TypePath,
230}
231
232#[derive(PartialEq, Eq, Clone, Debug)]
233#[derive(serde::Serialize, serde::Deserialize)]
234#[derive(Parse, Formattable, Format, Print)]
235pub struct QualifiedPathInTypeSegment {
236	pub sep:     token::PathSep,
237	pub segment: TypePathSegment,
238}