1use {
5 crate::{expr::Expression, path::SimplePath, token, util::Parenthesized},
6 rustidy_ast_util::{Longest, PunctuatedTrailing, delimited, punct},
7 rustidy_format::{Format, Formattable, WhitespaceConfig, WhitespaceFormat},
8 rustidy_parse::{ParsableFrom, Parse},
9 rustidy_print::Print,
10 rustidy_util::Whitespace,
11};
12
13#[derive(PartialEq, Eq, Clone, Debug)]
15#[derive(strum::EnumTryAs)]
16#[derive(serde::Serialize, serde::Deserialize)]
17#[derive(Parse, Formattable, Format, Print)]
18pub enum MetaItem {
19 EqExpr(MetaItemEqExpr),
20 Seq(MetaItemSeq),
21 Path(MetaItemPath),
22}
23
24impl MetaItem {
25 #[must_use]
27 pub const fn path(&self) -> &SimplePath {
28 match self {
29 Self::EqExpr(meta) => &meta.path,
30 Self::Seq(meta) => &meta.path,
31 Self::Path(meta) => &meta.0,
32 }
33 }
34}
35
36#[derive(PartialEq, Eq, Clone, Debug)]
37#[derive(serde::Serialize, serde::Deserialize)]
38#[derive(Parse, Formattable, Format, Print)]
39pub struct MetaItemPath(SimplePath);
40
41#[derive(PartialEq, Eq, Clone, Debug)]
42#[derive(serde::Serialize, serde::Deserialize)]
43#[derive(Parse, Formattable, Format, Print)]
44pub struct MetaItemEqExpr {
45 pub path: SimplePath,
46 #[format(prefix_ws = Whitespace::SINGLE)]
47 pub eq: token::Eq,
48 #[format(prefix_ws = Whitespace::SINGLE)]
49 pub expr: Expression,
50}
51
52#[derive(PartialEq, Eq, Clone, Debug)]
53#[derive(serde::Serialize, serde::Deserialize)]
54#[derive(Parse, Formattable, Format, Print)]
55pub struct MetaItemSeq {
56 pub path: SimplePath,
57 #[format(prefix_ws = Whitespace::REMOVE)]
58 #[format(args = delimited::fmt_remove_or_indent_if_non_blank(
59 100,
60 MetaSeqFmt { inner: Whitespace::SINGLE },
61 MetaSeqFmt { inner: Whitespace::INDENT },
62 ))]
63 pub seq: Parenthesized<Option<MetaSeq>>
64}
65
66#[derive(PartialEq, Eq, Clone, Debug)]
68#[derive(serde::Serialize, serde::Deserialize)]
69#[derive(Parse, Formattable, Format, Print)]
70#[format(args(ty = "MetaSeqFmt"))]
71pub struct MetaSeq(
72 #[format(args = punct::fmt(args.inner, Whitespace::REMOVE))]
73 pub PunctuatedTrailing<MetaItemInner, token::Comma>,
74);
75
76#[derive(Clone, Copy, Debug)]
77struct MetaSeqFmt {
78 inner: WhitespaceConfig,
79}
80
81#[derive(PartialEq, Eq, Clone, Debug)]
83#[derive(strum::EnumTryAs)]
84#[derive(serde::Serialize, serde::Deserialize)]
85#[derive(Parse, Formattable, Format, Print)]
86#[parse(from = Longest::<Expression, MetaItem>)]
87pub enum MetaItemInner {
88 Meta(Box<MetaItem>),
89 Expr(Expression),
90}
91
92impl ParsableFrom<Longest<Expression, MetaItem>> for MetaItemInner {
93 fn from_parsable(value: Longest<Expression, MetaItem>) -> Self {
94 match value {
95 Longest::Left(expr) => Self::Expr(expr),
96 Longest::Right(meta) => Self::Meta(Box::new(meta)),
97 }
98 }
99}