Skip to content

Commit 47bccc7

Browse files
committed
registers_or_clusters_first
1 parent 5492f74 commit 47bccc7

File tree

3 files changed

+84
-18
lines changed

3 files changed

+84
-18
lines changed

svd-encoder/src/config.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use convert_case::{Boundary, Case, Casing};
44

55
use crate::svd::BitRangeType;
66

7-
#[derive(Clone, Copy, Debug)]
7+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
88
pub enum IdentifierFormat {
99
/// `Camel` case
1010
///
@@ -63,7 +63,7 @@ pub fn change_case(s: &str, case: Option<IdentifierFormat>) -> String {
6363
}
6464
}
6565

66-
#[derive(Clone, Copy, Debug)]
66+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6767
pub enum NumberFormat {
6868
/// `UpperHex` format
6969
///
@@ -186,6 +186,24 @@ impl FromStr for Sorting {
186186
}
187187
}
188188

189+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
190+
pub enum RegistersOrClustersFirst {
191+
Registers,
192+
Clusters,
193+
}
194+
195+
impl FromStr for RegistersOrClustersFirst {
196+
type Err = ();
197+
198+
fn from_str(s: &str) -> Result<Self, Self::Err> {
199+
match s {
200+
"Registers" => Ok(Self::Registers),
201+
"Clusters" => Ok(Self::Clusters),
202+
_ => Err(()),
203+
}
204+
}
205+
}
206+
189207
#[derive(Clone, Copy, Debug)]
190208
#[non_exhaustive]
191209
/// Advanced encoder options
@@ -235,6 +253,9 @@ pub struct Config {
235253
/// Sort registers and clusters in specified order
236254
pub register_cluster_sorting: Option<Sorting>,
237255

256+
/// First write registers or clusters
257+
pub registers_or_clusters_first: Option<RegistersOrClustersFirst>,
258+
238259
/// Format of register's name-kind elements
239260
/// - `derivedFrom`
240261
/// - `name`
@@ -314,6 +335,7 @@ impl Default for Config {
314335
cluster_name: None,
315336
cluster_address_offset: NumberFormat::UpperHex,
316337
register_cluster_sorting: None,
338+
registers_or_clusters_first: None,
317339
register_name: None,
318340
register_address_offset: NumberFormat::UpperHex,
319341
register_size: NumberFormat::LowerHex,
@@ -349,6 +371,9 @@ impl Config {
349371
"register_cluster_sorting" => {
350372
self.register_cluster_sorting = Some(value.parse().unwrap())
351373
}
374+
"registers_or_clusters_first" => {
375+
self.registers_or_clusters_first = Some(value.parse().unwrap())
376+
}
352377
"register_name" => self.register_name = Some(value.parse().unwrap()),
353378
"register_address_offset" => self.register_address_offset = value.parse().unwrap(),
354379
"register_size" => self.register_size = value.parse().unwrap(),
@@ -437,6 +462,14 @@ impl Config {
437462
self
438463
}
439464

465+
/// First write registers or clusters
466+
///
467+
/// `None` means only `register_cluster_sorting` does matter
468+
pub fn registers_or_clusters_first(mut self, val: Option<RegistersOrClustersFirst>) -> Self {
469+
self.registers_or_clusters_first = val;
470+
self
471+
}
472+
440473
/// Format of register's name-kind elements
441474
pub fn register_name(mut self, val: Option<IdentifierFormat>) -> Self {
442475
self.register_name = val;

svd-encoder/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ 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, Sorting};
9+
pub use crate::config::{
10+
Config, IdentifierFormat, NumberFormat, RegistersOrClustersFirst, Sorting,
11+
};
1012

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

svd-encoder/src/peripheral.rs

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use svd_rs::RegisterCluster;
2+
13
use super::{
24
new_node, Config, Element, ElementMerge, Encode, EncodeChildren, EncodeError, XMLNode,
35
};
@@ -102,24 +104,41 @@ impl Encode for PeripheralInfo {
102104
elem.children.append(&mut interrupts?);
103105

104106
if let Some(v) = &self.registers {
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));
107+
let children: Result<Vec<_>, _> =
108+
if let Some(first) = config.registers_or_clusters_first {
109+
let mut reg_refs = v
110+
.iter()
111+
.filter(|rc| matches!(rc, RegisterCluster::Register(_)))
112+
.collect::<Vec<_>>();
113+
sort_register_cluster(&mut reg_refs, config.register_cluster_sorting);
114+
let mut c_refs = v
115+
.iter()
116+
.filter(|rc| matches!(rc, RegisterCluster::Cluster(_)))
117+
.collect::<Vec<_>>();
118+
sort_register_cluster(&mut c_refs, config.register_cluster_sorting);
119+
match first {
120+
crate::RegistersOrClustersFirst::Registers => {
121+
reg_refs.into_iter().chain(c_refs.into_iter())
122+
}
123+
crate::RegistersOrClustersFirst::Clusters => {
124+
c_refs.into_iter().chain(reg_refs.into_iter())
125+
}
112126
}
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()
120127
.map(|e| e.encode_node_with_config(config))
121128
.collect()
122-
};
129+
} else {
130+
if let Some(sorting) = config.register_cluster_sorting {
131+
let mut refs = v.iter().collect::<Vec<_>>();
132+
sort_register_cluster(&mut refs, Some(sorting));
133+
refs.into_iter()
134+
.map(|e| e.encode_node_with_config(config))
135+
.collect()
136+
} else {
137+
v.iter()
138+
.map(|e| e.encode_node_with_config(config))
139+
.collect()
140+
}
141+
};
123142

124143
elem.children.push({
125144
let mut e = Element::new("registers");
@@ -138,3 +157,15 @@ impl Encode for PeripheralInfo {
138157
Ok(elem)
139158
}
140159
}
160+
161+
fn sort_register_cluster(refs: &mut [&RegisterCluster], sorting: Option<Sorting>) {
162+
if let Some(sorting) = sorting {
163+
match sorting {
164+
Sorting::Offset => refs.sort_by_key(|r| r.address_offset()),
165+
Sorting::OffsetReversed => {
166+
refs.sort_by_key(|r| -(r.address_offset() as i32));
167+
}
168+
Sorting::Name => refs.sort_by_key(|r| r.name()),
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)