Skip to main content

rustidy_ast/attr/
meta.rs

1//! `MetaItem` attributes
2
3// Imports
4use {
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/// `MetaItem`
14#[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	/// Returns the path of this meta item
26	#[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/// `MetaSeq`
67#[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/// `MetaItemInner`
82#[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}