Skip to content

Commit 5492f74

Browse files
committed
sorting
1 parent 8ee1f61 commit 5492f74

File tree

8 files changed

+149
-19
lines changed

8 files changed

+149
-19
lines changed

svd-encoder/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10+
- Add `Sorting` options to `Config`
11+
1012
## [v0.14.2] - 2022-12-19
1113

1214
- Fix typo in `headerDefinitionsPrefix`

svd-encoder/src/config.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,26 @@ impl FromStr for FieldBitRangeFormat {
166166
}
167167
}
168168

169+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
170+
pub enum Sorting {
171+
Offset,
172+
OffsetReversed,
173+
Name,
174+
}
175+
176+
impl FromStr for Sorting {
177+
type Err = ();
178+
179+
fn from_str(s: &str) -> Result<Self, Self::Err> {
180+
match s {
181+
"Offset" => Ok(Self::Offset),
182+
"OffsetReversed" => Ok(Self::OffsetReversed),
183+
"Name" => Ok(Self::OffsetReversed),
184+
_ => Err(()),
185+
}
186+
}
187+
}
188+
169189
#[derive(Clone, Copy, Debug)]
170190
#[non_exhaustive]
171191
/// Advanced encoder options
@@ -184,6 +204,9 @@ pub struct Config {
184204
/// format: hex, dec
185205
pub peripheral_base_address: NumberFormat,
186206

207+
/// Sort peripherals in specified order
208+
pub peripheral_sorting: Option<Sorting>,
209+
187210
/// Format of addressBlock's offset element
188211
///
189212
/// format: hex, dec
@@ -209,6 +232,9 @@ pub struct Config {
209232
/// format: hex, dec
210233
pub cluster_address_offset: NumberFormat,
211234

235+
/// Sort registers and clusters in specified order
236+
pub register_cluster_sorting: Option<Sorting>,
237+
212238
/// Format of register's name-kind elements
213239
/// - `derivedFrom`
214240
/// - `name`
@@ -245,6 +271,9 @@ pub struct Config {
245271
/// `None` means keep the original bitRange
246272
pub field_bit_range: Option<FieldBitRangeFormat>,
247273

274+
/// Sort fields in specified order
275+
pub field_sorting: Option<Sorting>,
276+
248277
/// Format of enumeratedValues's name-kind elements
249278
/// - `derivedFrom`
250279
/// - `name`
@@ -278,18 +307,21 @@ impl Default for Config {
278307
Self {
279308
peripheral_name: None,
280309
peripheral_base_address: NumberFormat::UpperHex8,
310+
peripheral_sorting: None,
281311
address_block_offset: NumberFormat::UpperHex,
282312
address_block_size: NumberFormat::UpperHex,
283313
interrupt_name: None,
284314
cluster_name: None,
285315
cluster_address_offset: NumberFormat::UpperHex,
316+
register_cluster_sorting: None,
286317
register_name: None,
287318
register_address_offset: NumberFormat::UpperHex,
288319
register_size: NumberFormat::LowerHex,
289320
register_reset_value: NumberFormat::UpperHex16,
290321
register_reset_mask: NumberFormat::UpperHex16,
291322
field_name: None,
292323
field_bit_range: None,
324+
field_sorting: None,
293325
enumerated_values_name: None,
294326
enumerated_value_name: None,
295327
enumerated_value_value: NumberFormat::Dec,
@@ -308,18 +340,23 @@ impl Config {
308340
match name {
309341
"peripheral_name" => self.peripheral_name = Some(value.parse().unwrap()),
310342
"peripheral_base_address" => self.peripheral_base_address = value.parse().unwrap(),
343+
"peripheral_sorting" => self.peripheral_sorting = Some(value.parse().unwrap()),
311344
"address_block_offset" => self.address_block_offset = value.parse().unwrap(),
312345
"address_block_size" => self.address_block_size = value.parse().unwrap(),
313346
"interrupt_name" => self.interrupt_name = Some(value.parse().unwrap()),
314347
"cluster_name" => self.cluster_name = Some(value.parse().unwrap()),
315348
"cluster_address_offset" => self.cluster_address_offset = value.parse().unwrap(),
349+
"register_cluster_sorting" => {
350+
self.register_cluster_sorting = Some(value.parse().unwrap())
351+
}
316352
"register_name" => self.register_name = Some(value.parse().unwrap()),
317353
"register_address_offset" => self.register_address_offset = value.parse().unwrap(),
318354
"register_size" => self.register_size = value.parse().unwrap(),
319355
"register_reset_value" => self.register_reset_value = value.parse().unwrap(),
320356
"register_reset_mask" => self.register_reset_mask = value.parse().unwrap(),
321357
"field_name" => self.field_name = Some(value.parse().unwrap()),
322358
"field_bit_range" => self.field_bit_range = Some(value.parse().unwrap()),
359+
"field_sorting" => self.field_sorting = Some(value.parse().unwrap()),
323360
"enumerated_values_name" => self.enumerated_values_name = Some(value.parse().unwrap()),
324361
"enumerated_value_name" => self.enumerated_value_name = Some(value.parse().unwrap()),
325362
"enumerated_value_value" => self.enumerated_value_value = value.parse().unwrap(),
@@ -348,6 +385,14 @@ impl Config {
348385
self
349386
}
350387

388+
/// Sort peripherals in specified order
389+
///
390+
/// `None` means keep the original order
391+
pub fn peripheral_sorting(mut self, val: Option<Sorting>) -> Self {
392+
self.peripheral_sorting = val;
393+
self
394+
}
395+
351396
/// Format of addressBlock's offset element
352397
///
353398
/// format: hex, dec
@@ -384,6 +429,14 @@ impl Config {
384429
self
385430
}
386431

432+
/// Sort registers and clusters in specified order
433+
///
434+
/// `None` means keep the original order
435+
pub fn register_cluster_sorting(mut self, val: Option<Sorting>) -> Self {
436+
self.register_cluster_sorting = val;
437+
self
438+
}
439+
387440
/// Format of register's name-kind elements
388441
pub fn register_name(mut self, val: Option<IdentifierFormat>) -> Self {
389442
self.register_name = val;
@@ -436,6 +489,14 @@ impl Config {
436489
self
437490
}
438491

492+
/// Sort fields in specified order
493+
///
494+
/// `None` means keep the original order
495+
pub fn field_sorting(mut self, val: Option<Sorting>) -> Self {
496+
self.field_sorting = val;
497+
self
498+
}
499+
439500
/// Format of enumeratedValues's name-kind elements
440501
pub fn enumerated_values_name(mut self, val: Option<IdentifierFormat>) -> Self {
441502
self.enumerated_values_name = val;

svd-encoder/src/device.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{new_node, Config, Element, Encode, EncodeChildren, EncodeError, XMLNode};
2-
use crate::svd::Device;
2+
use crate::{config::Sorting, svd::Device};
33

44
impl Encode for Device {
55
type Error = EncodeError;
@@ -57,11 +57,24 @@ impl Encode for Device {
5757
.encode_with_config(config)?,
5858
);
5959

60-
let peripherals: Result<Vec<_>, _> = self
61-
.peripherals
62-
.iter()
63-
.map(|peripheral| peripheral.encode_node_with_config(config))
64-
.collect();
60+
let peripherals: Result<Vec<_>, _> = if let Some(sorting) = config.peripheral_sorting {
61+
let mut refs = self.peripherals.iter().collect::<Vec<_>>();
62+
match sorting {
63+
Sorting::Offset => refs.sort_by_key(|p| p.base_address),
64+
Sorting::OffsetReversed => {
65+
refs.sort_by_key(|p| -(p.base_address as i32));
66+
}
67+
Sorting::Name => refs.sort_by_key(|p| &p.name),
68+
}
69+
refs.into_iter()
70+
.map(|peripheral| peripheral.encode_node_with_config(config))
71+
.collect()
72+
} else {
73+
self.peripherals
74+
.iter()
75+
.map(|peripheral| peripheral.encode_node_with_config(config))
76+
.collect()
77+
};
6578
elem.children.push({
6679
let mut e = Element::new("peripherals");
6780
e.children = peripherals?;

svd-encoder/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use svd_rs as svd;
66
use crate::svd::Device;
77
use xmltree::{Element, EmitterConfig, XMLNode};
88

9-
pub use crate::config::{Config, IdentifierFormat, NumberFormat};
9+
pub use crate::config::{Config, IdentifierFormat, NumberFormat, Sorting};
1010

1111
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
1212
pub enum EncodeError {}

svd-encoder/src/peripheral.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{
33
};
44

55
use crate::{
6-
config::{change_case, format_number},
6+
config::{change_case, format_number, Sorting},
77
svd::{Peripheral, PeripheralInfo},
88
};
99

@@ -102,10 +102,24 @@ impl Encode for PeripheralInfo {
102102
elem.children.append(&mut interrupts?);
103103

104104
if let Some(v) = &self.registers {
105-
let children: Result<Vec<_>, _> = v
106-
.iter()
107-
.map(|e| e.encode_node_with_config(config))
108-
.collect();
105+
let children: Result<Vec<_>, _> = if let Some(sorting) = config.register_cluster_sorting
106+
{
107+
let mut refs = v.iter().collect::<Vec<_>>();
108+
match sorting {
109+
Sorting::Offset => refs.sort_by_key(|r| r.address_offset()),
110+
Sorting::OffsetReversed => {
111+
refs.sort_by_key(|r| -(r.address_offset() as i32));
112+
}
113+
Sorting::Name => refs.sort_by_key(|r| r.name()),
114+
}
115+
refs.into_iter()
116+
.map(|e| e.encode_node_with_config(config))
117+
.collect()
118+
} else {
119+
v.iter()
120+
.map(|e| e.encode_node_with_config(config))
121+
.collect()
122+
};
109123

110124
elem.children.push({
111125
let mut e = Element::new("registers");

svd-encoder/src/register.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{
33
};
44

55
use crate::{
6-
config::{change_case, format_number},
6+
config::{change_case, format_number, Sorting},
77
svd::{Register, RegisterInfo},
88
};
99

@@ -74,10 +74,24 @@ impl Encode for RegisterInfo {
7474
}
7575

7676
if let Some(v) = &self.fields {
77-
let children = v
78-
.iter()
79-
.map(|field| field.encode_node_with_config(config))
80-
.collect::<Result<Vec<_>, EncodeError>>()?;
77+
let children: Result<Vec<_>, _> = if let Some(sorting) = config.field_sorting {
78+
let mut refs = v.iter().collect::<Vec<_>>();
79+
match sorting {
80+
Sorting::Offset => refs.sort_by_key(|f| f.bit_offset()),
81+
Sorting::OffsetReversed => {
82+
refs.sort_by_key(|f| -(f.bit_offset() as i32));
83+
}
84+
Sorting::Name => refs.sort_by_key(|f| &f.name),
85+
}
86+
refs.into_iter()
87+
.map(|field| field.encode_node_with_config(config))
88+
.collect()
89+
} else {
90+
v.iter()
91+
.map(|field| field.encode_node_with_config(config))
92+
.collect()
93+
};
94+
let children = children?;
8195
if !children.is_empty() {
8296
let mut fields = Element::new("fields");
8397
fields.children = children;

svd-rs/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10+
- Add `name`, `description`, `address_offset` for `RegisterCluster`
11+
1012
## [v0.14.1] - 2022-10-23
1113

1214
- (De)serialize `dimIndex` (from)to string

svd-rs/src/registercluster.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,37 @@ pub enum RegisterCluster {
1717

1818
impl From<Register> for RegisterCluster {
1919
fn from(reg: Register) -> Self {
20-
RegisterCluster::Register(reg)
20+
Self::Register(reg)
2121
}
2222
}
2323

2424
impl From<Cluster> for RegisterCluster {
2525
fn from(cluser: Cluster) -> Self {
26-
RegisterCluster::Cluster(cluser)
26+
Self::Cluster(cluser)
27+
}
28+
}
29+
30+
impl RegisterCluster {
31+
/// Name of register or cluster
32+
pub fn name(&self) -> &String {
33+
match self {
34+
Self::Register(r) => &r.name,
35+
Self::Cluster(c) => &c.name,
36+
}
37+
}
38+
/// Description of register or cluster
39+
pub fn description(&self) -> &Option<String> {
40+
match self {
41+
Self::Register(r) => &r.description,
42+
Self::Cluster(c) => &c.description,
43+
}
44+
}
45+
/// Address offset of register or cluster
46+
pub fn address_offset(&self) -> u32 {
47+
match self {
48+
Self::Register(r) => r.address_offset,
49+
Self::Cluster(c) => c.address_offset,
50+
}
2751
}
2852
}
2953

0 commit comments

Comments
 (0)