1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::format::{Format, Formatter};
use crate::items::components::TupleLike;
use crate::items::tokens::AtomToken;
use crate::items::Expr;
use crate::parse::Parse;
use crate::span::Span;

/// `{` ([Expr] `,`?)* `}`
#[derive(Debug, Clone, Span, Parse, Format)]
pub struct TupleExpr(TupleLike<Expr>);

impl TupleExpr {
    pub fn children(&self) -> impl Iterator<Item = &Expr> {
        self.items().1.iter()
    }

    pub(crate) fn items(&self) -> (Option<&AtomToken>, &[Expr]) {
        self.0.items()
    }

    pub(crate) fn try_format_app_file(&self, fmt: &mut Formatter) -> bool {
        self.0.try_format_app_file(fmt)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn tuple_works() {
        let texts = [
            "{}",
            "{1}",
            "{foo, bar, baz}",
            indoc::indoc! {"
            {1, 2, 3, 4, 5, 6,
             7, 8, 9}"},
            indoc::indoc! {"
            {1,
             2,
             {3, 4, 5},
             6,
             {7, 8, 9}}"},
            indoc::indoc! {"
            {error,
             {Foo, Bar,
              Baz},
             qux}"},
        ];
        for text in texts {
            crate::assert_format!(text, Expr);
        }
    }

    #[test]
    fn tagged_tuple_works() {
        let texts = [indoc::indoc! {"
            {error, {Foo, Bar,
                     Baz},
                    qux}"}];
        for text in texts {
            crate::assert_format!(text, Expr);
        }
    }
}