Skip to main content

rustidy_ast/expr/without_block/
call.rs

1//! Method call expression
2
3use {
4	crate::{
5		expr::{Expression, ExpressionInner},
6		token,
7		util::{FmtSingleOrIndent, Parenthesized},
8	},
9	super::{ExpressionWithoutBlockInner, path::PathExprSegment},
10	rustidy_ast_util::{PunctuatedTrailing, delimited, punct},
11	rustidy_format::{
12		Format,
13		FormatOutput,
14		FormatTag,
15		Formattable,
16		WhitespaceConfig,
17		WhitespaceFormat,
18	},
19	rustidy_parse::{Parse, ParseRecursive},
20	rustidy_print::Print,
21	rustidy_util::Whitespace,
22};
23
24/// `CallExpression`
25#[derive(PartialEq, Eq, Clone, Debug)]
26#[derive(serde::Serialize, serde::Deserialize)]
27#[derive(ParseRecursive, Formattable, Format, Print)]
28#[parse_recursive(root = ExpressionInner)]
29#[parse_recursive(into_root = ExpressionWithoutBlockInner)]
30#[parse_recursive(kind = "left")]
31pub struct CallExpression {
32	pub expr:   Expression,
33	#[format(without_tag = FormatTag::InsideChain)]
34	#[format(prefix_ws = Whitespace::REMOVE)]
35	#[format(args = delimited::fmt_remove_or_indent_if_non_blank(
36		50,
37		FmtSingleOrIndent::Single,
38		FmtSingleOrIndent::Indent
39	))]
40	pub params: Parenthesized<Option<CallParams>>,
41}
42
43/// `MethodCallExpression`
44#[derive(PartialEq, Eq, Clone, Debug)]
45#[derive(serde::Serialize, serde::Deserialize)]
46#[derive(ParseRecursive, Formattable, Format, Print)]
47#[parse_recursive(root = ExpressionInner)]
48#[parse_recursive(into_root = ExpressionWithoutBlockInner)]
49#[parse_recursive(kind = "left")]
50#[format(args = MethodCallExpressionFmt)]
51pub struct MethodCallExpression {
52	pub expr:    Expression,
53	#[format(indent(if_has_tag = FormatTag::InsideChain))]
54	#[format(prefix_ws = match ctx.has_tag(FormatTag::InsideChain) {
55		true => Whitespace::INDENT,
56		false => Whitespace::REMOVE,
57	})]
58	pub dot:     token::Dot,
59	#[format(prefix_ws = Whitespace::REMOVE)]
60	pub segment: PathExprSegment,
61	#[format(prefix_ws = Whitespace::REMOVE)]
62	#[format(without_tag = FormatTag::InsideChain)]
63	#[format(indent(if_has_tag = FormatTag::InsideChain))]
64	#[format(args = delimited::fmt_remove_or_indent_if_non_blank(
65		50,
66		FmtSingleOrIndent::Single,
67		FmtSingleOrIndent::Indent
68	))]
69	pub params:  Parenthesized<Option<CallParams>>,
70}
71
72struct MethodCallExpressionFmt;
73
74impl Format<WhitespaceConfig, ()> for MethodCallExpression {
75	fn format(
76		&mut self,
77		ctx: &mut rustidy_format::Context,
78		prefix_ws: WhitespaceConfig,
79		_args: ()
80	) -> FormatOutput {
81		let output = self
82			.format(ctx, prefix_ws, MethodCallExpressionFmt);
83
84		match ctx.has_tag(FormatTag::InsideChain) {
85			true => output,
86			false => match output.len_non_multiline_ws() >= ctx.config().max_chain_len {
87				// TODO: Ideally we wouldn't re-format everything here.
88				true => ctx
89					.with_tag(FormatTag::InsideChain, |ctx| {
90						self
91							.format(ctx, prefix_ws, MethodCallExpressionFmt)
92					}),
93				false => output,
94			},
95		}
96	}
97}
98
99/// `CallParams`
100#[derive(PartialEq, Eq, Clone, Debug)]
101#[derive(serde::Serialize, serde::Deserialize)]
102#[derive(Parse, Formattable, Format, Print)]
103#[format(args(ty = "FmtSingleOrIndent"))]
104pub struct CallParams(
105	#[format(args = punct::fmt(args.prefix_ws(), Whitespace::REMOVE))]
106	pub PunctuatedTrailing<Expression, token::Comma>,
107);