rustidy_ast/expr/without_block/
array.rs1use {
5 crate::{expr::Expression, token, util::Bracketed},
6 rustidy_ast_util::{Delimited, delimited, punct::{self, PunctuatedTrailing}},
7 rustidy_format::{Format, FormatOutput, Formattable, WhitespaceConfig, WhitespaceFormat},
8 rustidy_parse::Parse,
9 rustidy_print::Print,
10 rustidy_util::Whitespace,
11};
12
13#[derive(PartialEq, Eq, Clone, Debug)]
15#[derive(serde::Serialize, serde::Deserialize)]
16#[derive(Parse, Formattable, Print)]
17#[parse(name = "an array expression")]
18pub struct ArrayExpression(Bracketed<Option<ArrayElements>>);
19
20impl ArrayExpression {
21 fn format_single_line(
23 prefix: &mut token::BracketOpen,
24 values: &mut PunctuatedTrailing<Expression, token::Comma>,
25 suffix: &mut token::BracketClose,
26 ctx: &mut rustidy_format::Context,
27 prefix_ws: WhitespaceConfig,
28 ) -> FormatOutput {
29 let mut delimited = Delimited { prefix, value: values, suffix, };
30 let args = delimited::FmtRemoveWith(
31 punct::fmt(Whitespace::SINGLE, Whitespace::REMOVE)
32 );
33 delimited.format(ctx, prefix_ws, args)
34 }
35
36 fn format_multi_line(
38 prefix: &mut token::BracketOpen,
39 values: &mut PunctuatedTrailing<Expression, token::Comma>,
40 suffix: &mut token::BracketClose,
41 ctx: &mut rustidy_format::Context,
42 prefix_ws: WhitespaceConfig,
43 ) -> FormatOutput {
44 let mut delimited = Delimited { prefix, value: values, suffix, };
45 let args = delimited::fmt_indent_if_non_blank_with_value(
46 punct::FmtIndentColumns { columns: ctx.config().array_expr_cols, }
47 );
48 delimited.format(ctx, prefix_ws, args)
49 }
50}
51
52impl Format<WhitespaceConfig, ()> for ArrayExpression {
53 fn format(
54 &mut self,
55 ctx: &mut rustidy_format::Context,
56 prefix_ws: WhitespaceConfig,
57 _args: ()
58 ) -> FormatOutput {
59 match &mut self.0.value {
60 Some(ArrayElements::Punctuated(values)) => {
61 let trailing_comma = values.trailing.take();
62 let single_line_output = Self::format_single_line(
63 &mut self.0.prefix,
64 values,
65 &mut self.0.suffix,
66 ctx,
67 prefix_ws
68 );
69
70 let cols = ctx.config().array_expr_cols;
75 let is_single_line = single_line_output.multiline.is_none() && match cols {
76 Some(cols) => cols >= values.values_len(),
77 None => single_line_output.len_non_multiline_ws() <= ctx.config().max_array_expr_len,
78 };
79
80 match is_single_line {
82 true => single_line_output,
83 false => {
84 values.trailing = Some(trailing_comma.unwrap_or_default());
85 Self::format_multi_line(
86 &mut self.0.prefix,
87 values,
88 &mut self.0.suffix,
89 ctx,
90 prefix_ws,
91 )
92 },
93 }
94 },
95
96 Some(ArrayElements::Repeat(repeat)) => {
97 let mut output = FormatOutput::default();
98
99 ctx
100 .format(&mut self.0.prefix, prefix_ws)
101 .append_to(&mut output);
102 ctx
103 .format(repeat, Whitespace::REMOVE)
104 .append_to(&mut output);
105 ctx
106 .format(&mut self.0.suffix, Whitespace::REMOVE)
107 .append_to(&mut output);
108
109 output
110 },
111
112 None => FormatOutput::default(),
113 }
114 }
115}
116
117#[derive(PartialEq, Eq, Clone, Debug)]
119#[derive(serde::Serialize, serde::Deserialize)]
120#[derive(Parse, Formattable, Print)]
121pub enum ArrayElements {
122 Repeat(ArrayElementsRepeat),
123 Punctuated(PunctuatedTrailing<Expression, token::Comma>),
124}
125
126#[derive(PartialEq, Eq, Clone, Debug)]
127#[derive(serde::Serialize, serde::Deserialize)]
128#[derive(Parse, Formattable, Format, Print)]
129pub struct ArrayElementsRepeat {
130 pub expr: Expression,
131 #[format(prefix_ws = Whitespace::REMOVE)]
132 pub semi: token::Semi,
133 #[format(prefix_ws = Whitespace::SINGLE)]
134 pub count: Expression,
135}