1use std::fmt;
2use std::str::FromStr;
3
4const IMPORTS: u8 = 1 << 0;
5const LAYOUT: u8 = 1 << 1;
6const SPACING: u8 = 1 << 2;
7const SYNTAX_NORMALIZATION: u8 = 1 << 3;
8const ALL: u8 = IMPORTS | LAYOUT | SPACING | SYNTAX_NORMALIZATION;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[non_exhaustive]
13pub enum FormatRule {
14 Imports,
16 Layout,
18 Spacing,
20 SyntaxNormalization,
22}
23
24impl FormatRule {
25 #[must_use]
27 pub const fn id(self) -> &'static str {
28 match self {
29 Self::Imports => "imports",
30 Self::Layout => "layout",
31 Self::Spacing => "spacing",
32 Self::SyntaxNormalization => "syntax-normalization",
33 }
34 }
35
36 const fn bit(self) -> u8 {
37 match self {
38 Self::Imports => IMPORTS,
39 Self::Layout => LAYOUT,
40 Self::Spacing => SPACING,
41 Self::SyntaxNormalization => SYNTAX_NORMALIZATION,
42 }
43 }
44}
45
46impl fmt::Display for FormatRule {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.write_str(self.id())
49 }
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
54pub struct FormatRuleParseError {
55 value: String,
56}
57
58impl FormatRuleParseError {
59 #[must_use]
61 pub fn value(&self) -> &str {
62 &self.value
63 }
64}
65
66impl fmt::Display for FormatRuleParseError {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(
69 f,
70 "unknown formatter rule '{}' (expected one of imports|layout|spacing|syntax-normalization)",
71 self.value
72 )
73 }
74}
75
76impl std::error::Error for FormatRuleParseError {}
77
78impl FromStr for FormatRule {
79 type Err = FormatRuleParseError;
80
81 fn from_str(value: &str) -> Result<Self, Self::Err> {
82 match value {
83 "imports" => Ok(Self::Imports),
84 "layout" => Ok(Self::Layout),
85 "spacing" => Ok(Self::Spacing),
86 "syntax-normalization" => Ok(Self::SyntaxNormalization),
87 _ => Err(FormatRuleParseError {
88 value: value.to_string(),
89 }),
90 }
91 }
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
96pub struct FormatRuleSet {
97 bits: u8,
98}
99
100impl Default for FormatRuleSet {
101 fn default() -> Self {
102 Self::all()
103 }
104}
105
106impl FormatRuleSet {
107 #[must_use]
109 pub const fn all() -> Self {
110 Self { bits: ALL }
111 }
112
113 #[must_use]
115 pub const fn none() -> Self {
116 Self { bits: 0 }
117 }
118
119 #[must_use]
121 pub fn from_rules(rules: impl IntoIterator<Item = FormatRule>) -> Self {
122 let mut set = Self::none();
123 for rule in rules {
124 set.insert(rule);
125 }
126 set
127 }
128
129 pub const fn insert(&mut self, rule: FormatRule) {
131 self.bits |= rule.bit();
132 }
133
134 pub const fn remove(&mut self, rule: FormatRule) {
136 self.bits &= !rule.bit();
137 }
138
139 #[must_use]
141 pub const fn contains(self, rule: FormatRule) -> bool {
142 self.bits & rule.bit() != 0
143 }
144}