Skip to content

Commit 30b35ca

Browse files
committed
cows, cows everywhere
1 parent 54a7f49 commit 30b35ca

File tree

2 files changed

+57
-41
lines changed

2 files changed

+57
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
88
## [Unreleased]
99

1010
- Bump MSRV to 1.65
11+
- Optimize case change/sanitize
1112
- Fix dangling implicit derives
1213
- Fix escaping <> and & characters in doc attributes
1314

src/util.rs

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,41 @@ pub struct Config {
6161
pub log_level: Option<String>,
6262
}
6363

64+
#[derive(Clone, Debug, PartialEq, Eq)]
65+
pub enum Case {
66+
Constant,
67+
Pascal,
68+
Snake,
69+
}
70+
71+
impl Case {
72+
pub fn cow_to_case<'a>(&self, cow: Cow<'a, str>) -> Cow<'a, str> {
73+
match self {
74+
Self::Constant => match cow {
75+
Cow::Borrowed(s) if s.is_constant_case() => cow,
76+
_ => cow.to_constant_case().into(),
77+
},
78+
Self::Pascal => match cow {
79+
Cow::Borrowed(s) if s.is_pascal_case() => cow,
80+
_ => cow.to_pascal_case().into(),
81+
},
82+
Self::Snake => match cow {
83+
Cow::Borrowed(s) if s.is_snake_case() => cow,
84+
_ => cow.to_snake_case().into(),
85+
},
86+
}
87+
}
88+
pub fn sanitize<'a>(&self, s: &'a str) -> Cow<'a, str> {
89+
let s = if s.contains(BLACKLIST_CHARS) {
90+
Cow::Owned(s.replace(BLACKLIST_CHARS, ""))
91+
} else {
92+
s.into()
93+
};
94+
95+
self.cow_to_case(s)
96+
}
97+
}
98+
6499
fn current_dir() -> PathBuf {
65100
PathBuf::from(".")
66101
}
@@ -92,9 +127,10 @@ impl Default for Config {
92127
#[allow(clippy::upper_case_acronyms)]
93128
#[allow(non_camel_case_types)]
94129
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
95-
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
130+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
96131
pub enum Target {
97132
#[cfg_attr(feature = "serde", serde(rename = "cortex-m"))]
133+
#[default]
98134
CortexM,
99135
#[cfg_attr(feature = "serde", serde(rename = "msp430"))]
100136
Msp430,
@@ -122,32 +158,21 @@ impl Target {
122158
}
123159
}
124160

125-
impl Default for Target {
126-
fn default() -> Self {
127-
Self::CortexM
128-
}
129-
}
130-
131161
#[cfg_attr(
132162
feature = "serde",
133163
derive(serde::Deserialize),
134164
serde(rename_all = "lowercase")
135165
)]
136-
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
166+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
137167
pub enum SourceType {
168+
#[default]
138169
Xml,
139170
#[cfg(feature = "yaml")]
140171
Yaml,
141172
#[cfg(feature = "json")]
142173
Json,
143174
}
144175

145-
impl Default for SourceType {
146-
fn default() -> Self {
147-
Self::Xml
148-
}
149-
}
150-
151176
impl SourceType {
152177
/// Make a new [`Source`] from a given extension.
153178
pub fn from_extension(s: &str) -> Option<Self> {
@@ -203,41 +228,31 @@ pub trait ToSanitizedCase {
203228

204229
impl ToSanitizedCase for str {
205230
fn to_sanitized_pascal_case(&self) -> Cow<str> {
206-
let s = self.replace(BLACKLIST_CHARS, "");
207-
208-
match s.chars().next().unwrap_or('\0') {
209-
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => {
210-
Cow::from(format!("_{}", s.to_pascal_case()))
211-
}
212-
_ => Cow::from(s.to_pascal_case()),
231+
let s = Case::Pascal.sanitize(self);
232+
if s.as_bytes().get(0).unwrap_or(&0).is_ascii_digit() {
233+
Cow::from(format!("_{}", s))
234+
} else {
235+
s
213236
}
214237
}
215238
fn to_sanitized_constant_case(&self) -> Cow<str> {
216-
let s = self.replace(BLACKLIST_CHARS, "");
217-
218-
match s.chars().next().unwrap_or('\0') {
219-
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => {
220-
Cow::from(format!("_{}", s.to_constant_case()))
221-
}
222-
_ => Cow::from(s.to_constant_case()),
239+
let s = Case::Constant.sanitize(self);
240+
if s.as_bytes().get(0).unwrap_or(&0).is_ascii_digit() {
241+
Cow::from(format!("_{}", s))
242+
} else {
243+
s
223244
}
224245
}
225246
fn to_sanitized_not_keyword_snake_case(&self) -> Cow<str> {
226247
const INTERNALS: [&str; 4] = ["set_bit", "clear_bit", "bit", "bits"];
227248

228-
let s = self.replace(BLACKLIST_CHARS, "");
229-
match s.chars().next().unwrap_or('\0') {
230-
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => {
231-
format!("_{}", s.to_snake_case()).into()
232-
}
233-
_ => {
234-
let s = Cow::from(s.to_snake_case());
235-
if INTERNALS.contains(&s.as_ref()) {
236-
s + "_"
237-
} else {
238-
s
239-
}
240-
}
249+
let s = Case::Snake.sanitize(self);
250+
if s.as_bytes().get(0).unwrap_or(&0).is_ascii_digit() {
251+
format!("_{}", s).into()
252+
} else if INTERNALS.contains(&s.as_ref()) {
253+
s + "_"
254+
} else {
255+
s
241256
}
242257
}
243258
}

0 commit comments

Comments
 (0)