1pub mod block;
5pub mod match_;
6
7pub use self::{block::BlockExpression, match_::{MatchExpression, Scrutinee}};
9
10use {
12 crate::{
13 attr::{self, WithOuterAttributes},
14 lifetime::LifetimeOrLabel,
15 pat::Pattern,
16 token,
17 },
18 super::Expression,
19 rustidy_ast_util::{Longest, Punctuated, punct},
20 rustidy_format::{Format, Formattable, WhitespaceFormat},
21 rustidy_parse::{ParsableFrom, Parse, ParserTag},
22 rustidy_print::Print,
23 rustidy_util::Whitespace,
24};
25
26#[derive(PartialEq, Eq, Clone, Debug)]
28#[derive(serde::Serialize, serde::Deserialize)]
29#[derive(Parse, Formattable, Format, Print)]
30pub struct ExpressionWithBlock(
31 #[format(args = attr::with::fmt(Whitespace::INDENT))]
33 pub WithOuterAttributes<ExpressionWithBlockInner>,
34);
35
36#[derive(PartialEq, Eq, Clone, Debug)]
37#[derive(serde::Serialize, serde::Deserialize)]
38#[derive(Parse, Formattable, Format, Print)]
39pub enum ExpressionWithBlockInner {
40 Block(BlockExpression),
41 ConstBlock(ConstBlockExpression),
42 UnsafeBlock(UnsafeBlockExpression),
43 TryBlock(TryBlockExpression),
44 Loop(LoopExpression),
45 If(IfExpression),
46 Match(MatchExpression),
47}
48
49#[derive(PartialEq, Eq, Clone, Debug)]
51#[derive(serde::Serialize, serde::Deserialize)]
52#[derive(Parse, Formattable, Format, Print)]
53pub struct ConstBlockExpression {
54 pub const_: token::Const,
55 #[format(prefix_ws = Whitespace::SINGLE)]
56 pub expr: BlockExpression,
57}
58
59#[derive(PartialEq, Eq, Clone, Debug)]
61#[derive(serde::Serialize, serde::Deserialize)]
62#[derive(Parse, Formattable, Format, Print)]
63pub struct UnsafeBlockExpression {
64 pub unsafe_: token::Unsafe,
65 #[format(prefix_ws = Whitespace::SINGLE)]
66 pub expr: BlockExpression,
67}
68
69#[derive(PartialEq, Eq, Clone, Debug)]
71#[derive(serde::Serialize, serde::Deserialize)]
72#[derive(Parse, Formattable, Format, Print)]
73pub struct TryBlockExpression {
74 pub try_: token::Try,
75 #[parse(fatal)]
76 #[format(prefix_ws = Whitespace::SINGLE)]
77 pub expr: BlockExpression,
78}
79
80#[derive(PartialEq, Eq, Clone, Debug)]
82#[derive(serde::Serialize, serde::Deserialize)]
83#[derive(Parse, Formattable, Format, Print)]
84#[parse(name = "an if expression")]
85pub struct IfExpression {
86 pub if_: token::If,
87 #[parse(fatal)]
88 #[format(prefix_ws = Whitespace::SINGLE)]
89 pub conditions: Conditions,
90 #[format(prefix_ws = Whitespace::SINGLE)]
91 pub expr: BlockExpression,
92 #[format(prefix_ws = Whitespace::SINGLE)]
93 pub else_: Option<IfExpressionElse>,
94}
95
96#[derive(PartialEq, Eq, Clone, Debug)]
97#[derive(serde::Serialize, serde::Deserialize)]
98#[derive(Parse, Formattable, Format, Print)]
99pub struct IfExpressionElse {
100 pub else_: token::Else,
101 #[parse(fatal)]
102 #[format(prefix_ws = Whitespace::SINGLE)]
103 pub inner: IfExpressionElseInner,
104}
105
106#[derive(PartialEq, Eq, Clone, Debug)]
107#[derive(serde::Serialize, serde::Deserialize)]
108#[derive(Parse, Formattable, Format, Print)]
109pub enum IfExpressionElseInner {
110 Block(BlockExpression),
111 If(Box<IfExpression>),
112}
113
114#[derive(PartialEq, Eq, Clone, Debug)]
116#[derive(serde::Serialize, serde::Deserialize)]
117#[derive(Parse, Formattable, Format, Print)]
118#[parse(from = Longest::<LetChain, ConditionsExpr>)]
119pub enum Conditions {
120 Let(LetChain),
121 Expr(ConditionsExpr)
122}
123
124impl ParsableFrom<Longest<LetChain, ConditionsExpr>> for Conditions {
125 fn from_parsable(value: Longest<LetChain, ConditionsExpr>) -> Self {
126 match value {
127 Longest::Left(let_chain) => Self::Let(let_chain),
128 Longest::Right(expr) => Self::Expr(expr),
129 }
130 }
131}
132
133#[derive(PartialEq, Eq, Clone, Debug)]
134#[derive(serde::Serialize, serde::Deserialize)]
135#[derive(Parse, Formattable, Format, Print)]
136pub struct ConditionsExpr(
137 #[parse(with_tag = ParserTag::SkipStructExpression)]
138 #[parse(with_tag = ParserTag::SkipOptionalTrailingBlockExpression)]
139 Expression,
140);
141
142#[derive(PartialEq, Eq, Clone, Debug)]
144#[derive(serde::Serialize, serde::Deserialize)]
145#[derive(Parse, Formattable, Format, Print)]
146pub struct LetChain(
147 #[format(args = punct::fmt(Whitespace::SINGLE, Whitespace::SINGLE))]
148 pub Punctuated<LetChainCondition, token::AndAnd>,
149);
150
151#[derive(PartialEq, Eq, Clone, Debug)]
153#[derive(serde::Serialize, serde::Deserialize)]
154#[derive(Parse, Formattable, Format, Print)]
155pub enum LetChainCondition {
156 #[format(args = attr::with::fmt(Whitespace::SINGLE))]
157 Let(WithOuterAttributes<LetChainConditionLet>),
158 #[parse(with_tag = ParserTag::SkipStructExpression)]
159 #[parse(with_tag = ParserTag::SkipLazyBooleanExpression)]
160 #[parse(with_tag = ParserTag::SkipRangeExpr)]
161 #[parse(with_tag = ParserTag::SkipRangeFromExpr)]
162 #[parse(with_tag = ParserTag::SkipRangeInclusiveExpr)]
163 #[parse(with_tag = ParserTag::SkipAssignmentExpression)]
164 #[parse(with_tag = ParserTag::SkipCompoundAssignmentExpression)]
165 #[parse(with_tag = ParserTag::SkipOptionalTrailingBlockExpression)]
166 Expr(Expression),
167}
168
169#[derive(PartialEq, Eq, Clone, Debug)]
170#[derive(serde::Serialize, serde::Deserialize)]
171#[derive(Parse, Formattable, Format, Print)]
172pub struct LetChainConditionLet {
173 pub let_: token::Let,
174 #[parse(fatal)]
175 #[format(prefix_ws = Whitespace::SINGLE)]
176 pub pat: Pattern,
177 #[format(prefix_ws = Whitespace::SINGLE)]
178 pub eq: token::Eq,
179 #[parse(with_tag = ParserTag::SkipStructExpression)]
180 #[parse(with_tag = ParserTag::SkipLazyBooleanExpression)]
181 #[parse(with_tag = ParserTag::SkipRangeExpr)]
182 #[parse(with_tag = ParserTag::SkipRangeFromExpr)]
183 #[parse(with_tag = ParserTag::SkipRangeInclusiveExpr)]
184 #[parse(with_tag = ParserTag::SkipAssignmentExpression)]
185 #[parse(with_tag = ParserTag::SkipCompoundAssignmentExpression)]
186 #[parse(with_tag = ParserTag::SkipOptionalTrailingBlockExpression)]
187 #[format(prefix_ws = Whitespace::SINGLE)]
188 pub scrutinee: Box<Scrutinee>,
189}
190
191#[derive(PartialEq, Eq, Clone, Debug)]
193#[derive(serde::Serialize, serde::Deserialize)]
194#[derive(Parse, Formattable, Format, Print)]
195pub struct LoopExpression {
196 pub label: Option<LoopLabel>,
197 #[format(prefix_ws(expr = Whitespace::SINGLE, if_ = self.label.is_some()))]
198 pub inner: LoopExpressionInner,
199}
200
201#[derive(PartialEq, Eq, Clone, Debug)]
203#[derive(serde::Serialize, serde::Deserialize)]
204#[derive(Parse, Formattable, Format, Print)]
205pub struct LoopLabel {
206 pub lifetime: LifetimeOrLabel,
207 #[format(prefix_ws = Whitespace::REMOVE)]
208 pub colon: token::Colon,
209}
210
211#[derive(PartialEq, Eq, Clone, Debug)]
212#[derive(serde::Serialize, serde::Deserialize)]
213#[derive(Parse, Formattable, Format, Print)]
214pub enum LoopExpressionInner {
215 Infinite(InfiniteLoopExpression),
216 Predicate(PredicateLoopExpression),
217 Iterator(IteratorLoopExpression),
218 LabelBlock(LabelBlockExpression),
219}
220
221#[derive(PartialEq, Eq, Clone, Debug)]
223#[derive(serde::Serialize, serde::Deserialize)]
224#[derive(Parse, Formattable, Format, Print)]
225pub struct IteratorLoopExpression {
226 pub for_: token::For,
227 #[format(prefix_ws = Whitespace::SINGLE)]
228 pub pat: Pattern,
229 #[format(prefix_ws = Whitespace::SINGLE)]
230 pub in_: token::In,
231 #[parse(with_tag = ParserTag::SkipStructExpression)]
232 #[parse(with_tag = ParserTag::SkipOptionalTrailingBlockExpression)]
233 #[format(prefix_ws = Whitespace::SINGLE)]
234 pub expr: Expression,
235 #[format(prefix_ws = Whitespace::SINGLE)]
236 pub body: BlockExpression,
237}
238
239#[derive(PartialEq, Eq, Clone, Debug)]
241#[derive(serde::Serialize, serde::Deserialize)]
242#[derive(Parse, Formattable, Format, Print)]
243pub struct PredicateLoopExpression {
244 pub for_: token::While,
245 #[format(prefix_ws = Whitespace::SINGLE)]
246 pub cond: Conditions,
247 #[format(prefix_ws = Whitespace::SINGLE)]
248 pub body: BlockExpression,
249}
250
251#[derive(PartialEq, Eq, Clone, Debug)]
253#[derive(serde::Serialize, serde::Deserialize)]
254#[derive(Parse, Formattable, Format, Print)]
255pub struct InfiniteLoopExpression {
256 pub loop_: token::Loop,
257 #[format(prefix_ws = Whitespace::SINGLE)]
258 pub body: BlockExpression,
259}
260
261#[derive(PartialEq, Eq, Clone, Debug)]
263#[derive(serde::Serialize, serde::Deserialize)]
264#[derive(Parse, Formattable, Format, Print)]
265pub struct LabelBlockExpression(BlockExpression);