Skip to content

Commit e96c363

Browse files
authored
Merge pull request #819 from rust-embedded/field-derive
DimSuffix trait
2 parents 11937f2 + d3c92ac commit e96c363

File tree

4 files changed

+63
-50
lines changed

4 files changed

+63
-50
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
1313
- Use `PascalCase` for type idents, fix case changing bugs, add `--ident-format` (`-f`) option flag
1414
- Add `enum_read_name` for `read-only` enums, `RWEnum` helper
1515
- Reexport enums inside register again
16+
- Add `DimSuffix` helper trait
1617

1718
## [v0.31.5] - 2024-01-04
1819

src/generate/peripheral.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use quote::{quote, ToTokens};
1616
use syn::{punctuated::Punctuated, Token};
1717

1818
use crate::util::{
19-
self, ident, name_to_ty, path_segment, type_path, unsuffixed, zst_type, FullName, BITS_PER_BYTE,
19+
self, ident, name_to_ty, path_segment, type_path, unsuffixed, zst_type, DimSuffix, FullName,
20+
BITS_PER_BYTE,
2021
};
2122
use anyhow::{anyhow, bail, Context, Result};
2223

@@ -212,9 +213,8 @@ pub fn render(p_original: &Peripheral, index: &Index, config: &Config) -> Result
212213
}
213214
}
214215

215-
let description = util::escape_special_chars(
216-
util::respace(p.description.as_ref().unwrap_or(&name.as_ref().to_owned())).as_ref(),
217-
);
216+
let description =
217+
util::escape_special_chars(util::respace(p.description.as_ref().unwrap_or(&name)).as_ref());
218218

219219
// Build up an alternate erc list by expanding any derived registers/clusters
220220
// erc: *E*ither *R*egister or *C*luster
@@ -763,7 +763,7 @@ fn check_erc_derive_infos(
763763

764764
Register::Array(..) => {
765765
// Only match integer indeces when searching for disjoint arrays
766-
let re_string = util::replace_suffix(&info_name, "([0-9]+|%s)");
766+
let re_string = info_name.expand_dim("([0-9]+|%s)");
767767
let re = Regex::new(format!("^{re_string}$").as_str()).map_err(|_| {
768768
anyhow!("Error creating regex for register {}", register.name)
769769
})?;
@@ -991,9 +991,9 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
991991
.to_string();
992992

993993
let ty_name = if cluster.is_single() {
994-
cluster.name.to_string()
994+
Cow::Borrowed(cluster.name.as_str())
995995
} else {
996-
util::replace_suffix(&cluster.name, "")
996+
cluster.name.remove_dim()
997997
};
998998
let span = Span::call_site();
999999
let ty = name_to_ty(ident(&ty_name, config, "cluster", span));
@@ -1166,9 +1166,9 @@ fn expand_register(
11661166

11671167
let info_name = register.fullname(config.ignore_groups);
11681168
let mut ty_name = if register.is_single() {
1169-
info_name.to_string()
1169+
info_name.clone()
11701170
} else {
1171-
util::replace_suffix(&info_name, "")
1171+
info_name.remove_dim()
11721172
};
11731173
let ty_str = ty_name.clone();
11741174

@@ -1220,11 +1220,11 @@ fn expand_register(
12201220
};
12211221
let ac = match derive_info {
12221222
DeriveInfo::Implicit(_) => {
1223-
ty_name = util::replace_suffix(&info_name, &index);
1223+
ty_name = info_name.expand_dim(&index);
12241224
convert_list && sequential_indexes_from0
12251225
}
12261226
DeriveInfo::Explicit(_) => {
1227-
ty_name = util::replace_suffix(&info_name, &index);
1227+
ty_name = info_name.expand_dim(&index);
12281228
convert_list && sequential_indexes_from0
12291229
}
12301230
_ => convert_list,
@@ -1399,7 +1399,7 @@ fn cluster_block(
13991399
) -> Result<TokenStream> {
14001400
let description =
14011401
util::escape_special_chars(&util::respace(c.description.as_ref().unwrap_or(&c.name)));
1402-
let mod_name = util::replace_suffix(&c.name, "");
1402+
let mod_name = c.name.remove_dim().to_string();
14031403

14041404
// name_snake_case needs to take into account array type.
14051405
let span = Span::call_site();
@@ -1413,7 +1413,7 @@ fn cluster_block(
14131413
} else {
14141414
util::block_path_to_ty(&dparent, config, span)
14151415
};
1416-
let dname = util::replace_suffix(&index.clusters.get(&dpath).unwrap().name, "");
1416+
let dname = index.clusters.get(&dpath).unwrap().name.remove_dim();
14171417
let mut mod_derived = derived.clone();
14181418
derived
14191419
.path

src/generate/register.rs

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use svd_parser::expand::{
1515

1616
use crate::config::Config;
1717
use crate::util::{
18-
self, ident, ident_to_path, path_segment, replace_suffix, type_path, unsuffixed, FullName,
19-
U32Ext,
18+
self, ident, ident_to_path, path_segment, type_path, unsuffixed, DimSuffix, FullName, U32Ext,
2019
};
2120
use anyhow::{anyhow, Result};
2221
use syn::punctuated::Punctuated;
@@ -55,7 +54,10 @@ pub fn render(
5554
if let MaybeArray::Array(info, array_info) = register {
5655
if let Some(dim_index) = &array_info.dim_index {
5756
let index: Cow<str> = dim_index.first().unwrap().into();
58-
name = replace_suffix(&info.fullname(config.ignore_groups), &index).into()
57+
name = info
58+
.fullname(config.ignore_groups)
59+
.expand_dim(&index)
60+
.into()
5961
}
6062
}
6163
}
@@ -465,15 +467,14 @@ fn render_register_mod_debug(
465467
if field_access.can_read() && f.read_action.is_none() {
466468
if let Field::Array(_, de) = &f {
467469
for suffix in de.indexes() {
468-
let f_name_n =
469-
field_accessor(&util::replace_suffix(&f.name, &suffix), config, span);
470+
let f_name_n = field_accessor(&f.name.expand_dim(&suffix), config, span);
470471
let f_name_n_s = format!("{f_name_n}");
471472
r_debug_impl.extend(quote! {
472473
.field(#f_name_n_s, &format_args!("{}", self.#f_name_n().#bit_or_bits()))
473474
});
474475
}
475476
} else {
476-
let f_name = util::replace_suffix(&f.name, "");
477+
let f_name = f.name.remove_dim();
477478
let f_name = field_accessor(&f_name, config, span);
478479
let f_name_s = format!("{f_name}");
479480
r_debug_impl.extend(quote! {
@@ -641,7 +642,7 @@ pub fn fields(
641642
return Err(anyhow!("incorrect field {}", f.name));
642643
}
643644

644-
let name = util::replace_suffix(&f.name, "");
645+
let name = f.name.remove_dim();
645646
let name_snake_case = field_accessor(
646647
if let Field::Array(
647648
_,
@@ -694,7 +695,13 @@ pub fn fields(
694695
ev = (*index.evs.get(epath).unwrap()).clone();
695696
}
696697
} else if let Some(path) = fdpath.as_ref() {
697-
epath = Some(path.new_enum(ev.name.clone().unwrap_or_else(|| path.name.clone())));
698+
epath = Some(
699+
path.new_enum(
700+
ev.name
701+
.clone()
702+
.unwrap_or_else(|| path.name.remove_dim().into()),
703+
),
704+
);
698705
}
699706
lookup_results.push((ev, epath));
700707
}
@@ -914,12 +921,7 @@ pub fn fields(
914921
}
915922
EV::Derived(_, base) => {
916923
let base_ident = if config.field_names_for_enums {
917-
ident(
918-
&util::replace_suffix(&base.field().name, ""),
919-
config,
920-
fmt,
921-
span,
922-
)
924+
ident(&base.field().name.remove_dim(), config, fmt, span)
923925
} else {
924926
ident(&base.name, config, fmt, span)
925927
};
@@ -980,7 +982,7 @@ pub fn fields(
980982
// and value if necessary.
981983

982984
// generate pub use field_1 reader as field_2 reader
983-
let base_field = util::replace_suffix(&base.field.name, "");
985+
let base_field = base.field.name.remove_dim();
984986
let base_r = ident(&base_field, config, "field_reader", span);
985987
if !reader_derives.contains(&reader_ty) {
986988
let base_path = base_syn_path(base, &fpath, &base_r, config)?;
@@ -1002,7 +1004,7 @@ pub fn fields(
10021004

10031005
if let Field::Array(f, de) = &f {
10041006
let increment = de.dim_increment;
1005-
let doc = util::replace_suffix(&description, &brief_suffix);
1007+
let doc = description.expand_dim(&brief_suffix);
10061008
let first_name = svd::array::names(f, de).next().unwrap();
10071009
let note = format!("NOTE: `n` is number of field in register. `n == 0` corresponds to `{first_name}` field");
10081010
let offset_calc = calculate_offset(increment, offset, true);
@@ -1182,12 +1184,7 @@ pub fn fields(
11821184
}
11831185
EV::Derived(_, base) => {
11841186
let base_ident = if config.field_names_for_enums {
1185-
ident(
1186-
&util::replace_suffix(&base.field().name, ""),
1187-
config,
1188-
fmt,
1189-
span,
1190-
)
1187+
ident(&base.field().name.remove_dim(), config, fmt, span)
11911188
} else {
11921189
ident(&base.name, config, fmt, span)
11931190
};
@@ -1260,7 +1257,7 @@ pub fn fields(
12601257
}
12611258
Some(EV::Derived(_, base)) => {
12621259
// generate pub use field_1 writer as field_2 writer
1263-
let base_field = util::replace_suffix(&base.field.name, "");
1260+
let base_field = base.field.name.remove_dim();
12641261
let base_w = ident(&base_field, config, "field_writer", span);
12651262
if !writer_derives.contains(&writer_ty) {
12661263
let base_path = base_syn_path(base, &fpath, &base_w, config)?;
@@ -1301,7 +1298,7 @@ pub fn fields(
13011298
if let Field::Array(f, de) = &f {
13021299
let increment = de.dim_increment;
13031300
let offset_calc = calculate_offset(increment, offset, false);
1304-
let doc = &util::replace_suffix(&description, &brief_suffix);
1301+
let doc = &description.expand_dim(&brief_suffix);
13051302
let first_name = svd::array::names(f, de).next().unwrap();
13061303
let note = format!("NOTE: `n` is number of field in register. `n == 0` corresponds to `{first_name}` field");
13071304
let dim = unsuffixed(de.dim);
@@ -1603,7 +1600,7 @@ fn base_syn_path(
16031600
let mut segments = Punctuated::new();
16041601
segments.push(path_segment(Ident::new("super", span)));
16051602
segments.push(path_segment(ident(
1606-
&replace_suffix(&base.register().name, ""),
1603+
&base.register().name.remove_dim(),
16071604
config,
16081605
"register_mod",
16091606
span,

src/util.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,12 @@ pub fn escape_special_chars(s: &str) -> String {
184184
escape_brackets(&html_escaped)
185185
}
186186

187-
pub fn name_of<T: FullName>(maybe_array: &MaybeArray<T>, ignore_group: bool) -> Cow<str> {
188-
match maybe_array {
189-
MaybeArray::Single(info) => info.fullname(ignore_group),
190-
MaybeArray::Array(info, _) => replace_suffix(&info.fullname(ignore_group), "").into(),
191-
}
192-
}
193-
194-
pub fn replace_suffix(name: &str, suffix: &str) -> String {
195-
if name.contains("[%s]") {
196-
name.replace("[%s]", suffix)
187+
pub fn name_of<T: FullName>(maybe_array: &MaybeArray<T>, ignore_group: bool) -> String {
188+
let fullname = maybe_array.fullname(ignore_group);
189+
if maybe_array.is_array() {
190+
fullname.remove_dim().into()
197191
} else {
198-
name.replace("%s", suffix)
192+
fullname.into()
199193
}
200194
}
201195

@@ -433,6 +427,27 @@ pub fn build_rs() -> TokenStream {
433427
}
434428
}
435429

430+
pub trait DimSuffix {
431+
fn expand_dim(&self, suffix: &str) -> Cow<str>;
432+
fn remove_dim(&self) -> Cow<str> {
433+
self.expand_dim("")
434+
}
435+
}
436+
437+
impl DimSuffix for str {
438+
fn expand_dim(&self, suffix: &str) -> Cow<str> {
439+
if self.contains("%s") {
440+
if self.contains("[%s]") {
441+
self.replace("[%s]", suffix).into()
442+
} else {
443+
self.replace("%s", suffix).into()
444+
}
445+
} else {
446+
self.into()
447+
}
448+
}
449+
}
450+
436451
pub trait FullName {
437452
fn fullname(&self, ignore_group: bool) -> Cow<str>;
438453
}
@@ -473,7 +488,7 @@ pub fn peripheral_names(d: &Device, feature_format: &IdentFormat) -> Vec<String>
473488
for p in &d.peripherals {
474489
match p {
475490
Peripheral::Single(info) => {
476-
v.push(replace_suffix(&feature_format.apply(&info.name), ""));
491+
v.push(feature_format.apply(&info.name).remove_dim().into());
477492
}
478493
Peripheral::Array(info, dim) => {
479494
v.extend(svd_rs::array::names(info, dim).map(|n| feature_format.apply(&n).into()));

0 commit comments

Comments
 (0)