Skip to main content

rustidy_ast/expr/without_block/
field.rs

1//! Field expression
2
3use {
4	crate::{expr::{Expression, ExpressionInner}, token},
5	super::ExpressionWithoutBlockInner,
6	rustidy_ast_util::Identifier,
7	rustidy_format::{
8		Format,
9		FormatOutput,
10		FormatTag,
11		Formattable,
12		WhitespaceConfig,
13		WhitespaceFormat,
14	},
15	rustidy_parse::ParseRecursive,
16	rustidy_print::Print,
17	rustidy_util::Whitespace,
18};
19
20/// `FieldExpression`
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 = "left")]
27#[format(args = FieldExpressionFmt)]
28pub struct FieldExpression {
29	pub expr:  Expression,
30	#[format(indent(if_has_tag = FormatTag::InsideChain))]
31	#[format(prefix_ws = match ctx.has_tag(FormatTag::InsideChain) {
32		true => Whitespace::INDENT,
33		false => Whitespace::REMOVE,
34	})]
35	pub dot:   token::Dot,
36	#[format(prefix_ws = Whitespace::REMOVE)]
37	pub ident: Identifier,
38}
39
40struct FieldExpressionFmt;
41
42impl Format<WhitespaceConfig, ()> for FieldExpression {
43	fn format(
44		&mut self,
45		ctx: &mut rustidy_format::Context,
46		prefix_ws: WhitespaceConfig,
47		_args: ()
48	) -> FormatOutput {
49		let output = self.format(ctx, prefix_ws, FieldExpressionFmt);
50
51		match ctx.has_tag(FormatTag::InsideChain) {
52			true => output,
53			false => match output.len_non_multiline_ws() >= ctx.config().max_chain_len {
54				// TODO: Ideally we wouldn't re-format everything here.
55				true => ctx
56					.with_tag(FormatTag::InsideChain, |ctx| {
57						self
58							.format(ctx, prefix_ws, FieldExpressionFmt)
59					}),
60				false => output,
61			},
62		}
63	}
64}