Skip to main content

rustidy_ast/expr/without_block/
closure.rs

1//! Closure
2
3// Imports
4use {
5	crate::{
6		attr::{self, WithOuterAttributes},
7		expr::{Expression, ExpressionInner},
8		item::function::ForLifetimes,
9		pat::PatternNoTopAlt,
10		token,
11		ty::{Type, TypeNoBounds},
12	},
13	super::ExpressionWithoutBlockInner,
14	rustidy_ast_util::{Delimited, PunctuatedTrailing, delimited, punct},
15	rustidy_format::{Format, Formattable, WhitespaceFormat},
16	rustidy_parse::{Parse, ParseRecursive},
17	rustidy_print::Print,
18	rustidy_util::Whitespace,
19};
20
21#[derive(PartialEq, Eq, Clone, Debug)]
22#[derive(serde::Serialize, serde::Deserialize)]
23#[derive(ParseRecursive, Formattable, Format, Print)]
24#[parse_recursive(root = ExpressionInner)]
25#[parse_recursive(into_root = ExpressionWithoutBlockInner)]
26#[parse_recursive(kind = "right")]
27pub struct ClosureExpression {
28	pub for_:   Option<ForLifetimes>,
29	#[format(prefix_ws(expr = Whitespace::SINGLE, if_ = self.for_.is_some()))]
30	pub async_: Option<token::Async>,
31	#[format(prefix_ws(expr = Whitespace::SINGLE, if_ = self.for_.is_some() || self.async_.is_some()))]
32	pub move_:  Option<token::Move>,
33	#[format(prefix_ws(
34		expr = Whitespace::SINGLE,
35		if_ = self.for_.is_some() || self.async_.is_some() || self.move_.is_some()
36	))]
37	pub params: ClosureParams,
38	#[format(prefix_ws = Whitespace::SINGLE)]
39	pub ret:    Option<ClosureRet>,
40	// TODO: If we parsed a return type, we should error
41	//       if this isn't a block expression.
42	#[format(prefix_ws = Whitespace::SINGLE)]
43	pub expr:   Expression,
44}
45
46#[derive(PartialEq, Eq, Clone, Debug)]
47#[derive(serde::Serialize, serde::Deserialize)]
48#[derive(Parse, Formattable, Format, Print)]
49pub enum ClosureParams {
50	NoParams(token::OrOr),
51	#[format(args = delimited::FmtRemove)]
52	WithParams(Delimited<Option<ClosureParameters>, token::Or, token::Or>),
53}
54
55#[derive(PartialEq, Eq, Clone, Debug)]
56#[derive(serde::Serialize, serde::Deserialize)]
57#[derive(Parse, Formattable, Format, Print)]
58pub struct ClosureRet {
59	pub arrow: token::RArrow,
60	#[parse(fatal)]
61	#[format(prefix_ws = Whitespace::SINGLE)]
62	pub ty:    TypeNoBounds,
63}
64
65/// `ClosureParameters`
66#[derive(PartialEq, Eq, Clone, Debug)]
67#[derive(serde::Serialize, serde::Deserialize)]
68#[derive(Parse, Formattable, Format, Print)]
69pub struct ClosureParameters(
70	#[format(args = punct::fmt(Whitespace::SINGLE, Whitespace::REMOVE))]
71	pub PunctuatedTrailing<ClosureParameter, token::Comma>,
72);
73
74/// `ClosureParameter`
75#[derive(PartialEq, Eq, Clone, Debug)]
76#[derive(serde::Serialize, serde::Deserialize)]
77#[derive(Parse, Formattable, Format, Print)]
78pub struct ClosureParameter(
79	#[format(args = attr::with::fmt(Whitespace::SINGLE))]
80	pub WithOuterAttributes<ClosureParameterInner>,
81);
82
83#[derive(PartialEq, Eq, Clone, Debug)]
84#[derive(serde::Serialize, serde::Deserialize)]
85#[derive(Parse, Formattable, Format, Print)]
86pub struct ClosureParameterInner {
87	pub pat: PatternNoTopAlt,
88	#[format(prefix_ws = Whitespace::REMOVE)]
89	pub ty:  Option<ClosureParameterInnerTy>,
90}
91
92#[derive(PartialEq, Eq, Clone, Debug)]
93#[derive(serde::Serialize, serde::Deserialize)]
94#[derive(Parse, Formattable, Format, Print)]
95pub struct ClosureParameterInnerTy {
96	pub colon: token::Colon,
97	#[format(prefix_ws = Whitespace::SINGLE)]
98	pub ty:    Type,
99}