1
1
//! Provides [expand] method to convert arrays, clusters and derived items in regular instances
2
2
3
3
use anyhow:: { anyhow, Result } ;
4
- use std:: collections:: HashMap ;
5
- use std:: fmt;
6
- use std:: mem:: take;
4
+ use std:: { collections:: HashMap , fmt, mem:: take, rc:: Rc } ;
7
5
use svd_rs:: {
8
6
array:: names, cluster, field, peripheral, register, Cluster , ClusterInfo , DeriveFrom , Device ,
9
7
EnumeratedValues , Field , Peripheral , Register , RegisterCluster , RegisterProperties ,
@@ -12,23 +10,23 @@ use svd_rs::{
12
10
/// Path to `peripheral` or `cluster` element
13
11
#[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
14
12
pub struct BlockPath {
15
- pub peripheral : String ,
16
- pub path : Vec < String > ,
13
+ pub peripheral : Rc < str > ,
14
+ pub path : Vec < Rc < str > > ,
17
15
}
18
16
19
17
impl BlockPath {
20
- pub fn new ( p : impl Into < String > ) -> Self {
18
+ pub fn new ( p : impl Into < Rc < str > > ) -> Self {
21
19
Self {
22
20
peripheral : p. into ( ) ,
23
21
path : Vec :: new ( ) ,
24
22
}
25
23
}
26
- pub fn new_cluster ( & self , name : impl Into < String > ) -> Self {
24
+ pub fn new_cluster ( & self , name : impl Into < Rc < str > > ) -> Self {
27
25
let mut child = self . clone ( ) ;
28
26
child. path . push ( name. into ( ) ) ;
29
27
child
30
28
}
31
- pub fn new_register ( & self , name : impl Into < String > ) -> RegisterPath {
29
+ pub fn new_register ( & self , name : impl Into < Rc < str > > ) -> RegisterPath {
32
30
RegisterPath :: new ( self . clone ( ) , name)
33
31
}
34
32
pub fn parse_str ( s : & str ) -> ( Option < Self > , & str ) {
@@ -46,7 +44,7 @@ impl BlockPath {
46
44
} ;
47
45
( block, name)
48
46
}
49
- pub fn name ( & self ) -> & String {
47
+ pub fn name ( & self ) -> & str {
50
48
self . path . last ( ) . unwrap ( )
51
49
}
52
50
pub fn parent ( & self ) -> Option < Self > {
@@ -63,11 +61,11 @@ impl PartialEq<str> for BlockPath {
63
61
}
64
62
let mut parts = other. split ( '.' ) ;
65
63
if let Some ( part1) = parts. next ( ) {
66
- if self . peripheral != part1 {
64
+ if self . peripheral . as_ref ( ) != part1 {
67
65
return false ;
68
66
}
69
67
for p in parts. zip ( self . path . iter ( ) ) {
70
- if p. 0 != p. 1 {
68
+ if p. 0 != p. 1 . as_ref ( ) {
71
69
return false ;
72
70
}
73
71
}
@@ -93,17 +91,17 @@ impl fmt::Display for BlockPath {
93
91
#[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
94
92
pub struct RegisterPath {
95
93
pub block : BlockPath ,
96
- pub name : String ,
94
+ pub name : Rc < str > ,
97
95
}
98
96
99
97
impl RegisterPath {
100
- pub fn new ( block : BlockPath , name : impl Into < String > ) -> Self {
98
+ pub fn new ( block : BlockPath , name : impl Into < Rc < str > > ) -> Self {
101
99
Self {
102
100
block,
103
101
name : name. into ( ) ,
104
102
}
105
103
}
106
- pub fn new_field ( & self , name : impl Into < String > ) -> FieldPath {
104
+ pub fn new_field ( & self , name : impl Into < Rc < str > > ) -> FieldPath {
107
105
FieldPath :: new ( self . clone ( ) , name)
108
106
}
109
107
pub fn parse_str ( s : & str ) -> ( Option < BlockPath > , & str ) {
@@ -112,15 +110,15 @@ impl RegisterPath {
112
110
pub fn parse_vec ( v : Vec < & str > ) -> ( Option < BlockPath > , & str ) {
113
111
BlockPath :: parse_vec ( v)
114
112
}
115
- pub fn peripheral ( & self ) -> & String {
113
+ pub fn peripheral ( & self ) -> & str {
116
114
& self . block . peripheral
117
115
}
118
116
}
119
117
120
118
impl PartialEq < str > for RegisterPath {
121
119
fn eq ( & self , other : & str ) -> bool {
122
120
if let Some ( ( block, reg) ) = other. rsplit_once ( '.' ) {
123
- self . name == reg && & self . block == block
121
+ self . name . as_ref ( ) == reg && & self . block == block
124
122
} else {
125
123
false
126
124
}
@@ -140,17 +138,17 @@ impl fmt::Display for RegisterPath {
140
138
#[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
141
139
pub struct FieldPath {
142
140
pub register : RegisterPath ,
143
- pub name : String ,
141
+ pub name : Rc < str > ,
144
142
}
145
143
146
144
impl FieldPath {
147
- pub fn new ( register : RegisterPath , name : impl Into < String > ) -> Self {
145
+ pub fn new ( register : RegisterPath , name : impl Into < Rc < str > > ) -> Self {
148
146
Self {
149
147
register,
150
148
name : name. into ( ) ,
151
149
}
152
150
}
153
- pub fn new_enum ( & self , name : impl Into < String > ) -> EnumPath {
151
+ pub fn new_enum ( & self , name : impl Into < Rc < str > > ) -> EnumPath {
154
152
EnumPath :: new ( self . clone ( ) , name)
155
153
}
156
154
pub fn parse_str ( s : & str ) -> ( Option < RegisterPath > , & str ) {
@@ -172,15 +170,15 @@ impl FieldPath {
172
170
pub fn register ( & self ) -> & RegisterPath {
173
171
& self . register
174
172
}
175
- pub fn peripheral ( & self ) -> & String {
173
+ pub fn peripheral ( & self ) -> & str {
176
174
self . register . peripheral ( )
177
175
}
178
176
}
179
177
180
178
impl PartialEq < str > for FieldPath {
181
179
fn eq ( & self , other : & str ) -> bool {
182
180
if let Some ( ( reg, field) ) = other. rsplit_once ( '.' ) {
183
- self . name == field && & self . register == reg
181
+ self . name . as_ref ( ) == field && & self . register == reg
184
182
} else {
185
183
false
186
184
}
@@ -200,11 +198,11 @@ impl fmt::Display for FieldPath {
200
198
#[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
201
199
pub struct EnumPath {
202
200
pub field : FieldPath ,
203
- pub name : String ,
201
+ pub name : Rc < str > ,
204
202
}
205
203
206
204
impl EnumPath {
207
- pub fn new ( field : FieldPath , name : impl Into < String > ) -> Self {
205
+ pub fn new ( field : FieldPath , name : impl Into < Rc < str > > ) -> Self {
208
206
Self {
209
207
field,
210
208
name : name. into ( ) ,
@@ -216,15 +214,15 @@ impl EnumPath {
216
214
pub fn register ( & self ) -> & RegisterPath {
217
215
& self . field . register
218
216
}
219
- pub fn peripheral ( & self ) -> & String {
217
+ pub fn peripheral ( & self ) -> & str {
220
218
self . field . peripheral ( )
221
219
}
222
220
}
223
221
224
222
impl PartialEq < str > for EnumPath {
225
223
fn eq ( & self , other : & str ) -> bool {
226
224
if let Some ( ( field, evs) ) = other. rsplit_once ( '.' ) {
227
- self . name == evs && & self . field == field
225
+ self . name . as_ref ( ) == evs && & self . field == field
228
226
} else {
229
227
false
230
228
}
@@ -263,7 +261,7 @@ impl<'a> Index<'a> {
263
261
self . peripherals . insert ( path, p) ;
264
262
}
265
263
}
266
- let path = BlockPath :: new ( & p. name ) ;
264
+ let path = BlockPath :: new ( p. name . as_ref ( ) ) ;
267
265
for r in p. registers ( ) {
268
266
self . add_register ( & path, r) ;
269
267
}
@@ -286,7 +284,7 @@ impl<'a> Index<'a> {
286
284
self . clusters . insert ( cpath, c) ;
287
285
}
288
286
}
289
- let cpath = path. new_cluster ( & c. name ) ;
287
+ let cpath = path. new_cluster ( c. name . as_ref ( ) ) ;
290
288
for r in c. registers ( ) {
291
289
self . add_register ( & cpath, r) ;
292
290
}
@@ -305,7 +303,7 @@ impl<'a> Index<'a> {
305
303
self . registers . insert ( rpath, r) ;
306
304
}
307
305
}
308
- let rpath = path. new_register ( & r. name ) ;
306
+ let rpath = path. new_register ( r. name . as_ref ( ) ) ;
309
307
for f in r. fields ( ) {
310
308
self . add_field ( & rpath, f) ;
311
309
}
@@ -317,16 +315,16 @@ impl<'a> Index<'a> {
317
315
let fpath = path. new_field ( name) ;
318
316
for evs in & f. enumerated_values {
319
317
if let Some ( name) = evs. name . as_ref ( ) {
320
- self . evs . insert ( fpath. new_enum ( name) , evs) ;
318
+ self . evs . insert ( fpath. new_enum ( name. as_ref ( ) ) , evs) ;
321
319
}
322
320
}
323
321
self . fields . insert ( fpath, f) ;
324
322
}
325
323
}
326
- let fpath = path. new_field ( & f. name ) ;
324
+ let fpath = path. new_field ( f. name . as_ref ( ) ) ;
327
325
for evs in & f. enumerated_values {
328
326
if let Some ( name) = evs. name . as_ref ( ) {
329
- self . evs . insert ( fpath. new_enum ( name) , evs) ;
327
+ self . evs . insert ( fpath. new_enum ( name. as_ref ( ) ) , evs) ;
330
328
}
331
329
}
332
330
self . fields . insert ( fpath, f) ;
@@ -365,7 +363,7 @@ fn expand_cluster_array(
365
363
if let Some ( dpath) = dpath {
366
364
cpath = derive_cluster ( & mut c, & dpath, path, index) ?;
367
365
}
368
- let cpath = cpath. unwrap_or_else ( || path. new_cluster ( & c. name ) ) ;
366
+ let cpath = cpath. unwrap_or_else ( || path. new_cluster ( c. name . as_ref ( ) ) ) ;
369
367
370
368
for rc in take ( & mut c. children ) {
371
369
expand_register_cluster ( & mut c. children , rc, & cpath, index) ?;
@@ -499,7 +497,7 @@ fn expand_register_array(
499
497
if let Some ( dpath) = dpath {
500
498
rpath = derive_register ( & mut r, & dpath, path, index) ?;
501
499
}
502
- let rpath = rpath. unwrap_or_else ( || path. new_register ( & r. name ) ) ;
500
+ let rpath = rpath. unwrap_or_else ( || path. new_register ( r. name . as_ref ( ) ) ) ;
503
501
504
502
if let Some ( field) = r. fields . as_mut ( ) {
505
503
for f in take ( field) {
@@ -529,7 +527,7 @@ fn expand_field(
529
527
if let Some ( dpath) = dpath {
530
528
fpath = derive_field ( & mut f, & dpath, rpath, index) ?;
531
529
}
532
- let fpath = fpath. unwrap_or_else ( || rpath. new_field ( & f. name ) ) ;
530
+ let fpath = fpath. unwrap_or_else ( || rpath. new_field ( f. name . as_ref ( ) ) ) ;
533
531
534
532
for ev in & mut f. enumerated_values {
535
533
let dpath = ev. derived_from . take ( ) ;
@@ -564,7 +562,7 @@ pub fn derive_enumerated_values(
564
562
if let Some ( r) = index. registers . get ( rdpath) {
565
563
let mut found = None ;
566
564
for f in r. fields ( ) {
567
- let epath = EnumPath :: new ( rdpath. new_field ( & f. name ) , dname) ;
565
+ let epath = EnumPath :: new ( rdpath. new_field ( f. name . as_ref ( ) ) , dname) ;
568
566
if let Some ( d) = index. evs . get ( & epath) {
569
567
found = Some ( ( d, epath) ) ;
570
568
break ;
@@ -645,7 +643,7 @@ pub fn expand(indevice: &Device) -> Result<Device> {
645
643
if let Some ( dpath) = dpath {
646
644
path = derive_peripheral ( & mut p, & dpath, & index) ?;
647
645
}
648
- let path = path. unwrap_or_else ( || BlockPath :: new ( & p. name ) ) ;
646
+ let path = path. unwrap_or_else ( || BlockPath :: new ( p. name . as_ref ( ) ) ) ;
649
647
if let Some ( regs) = p. registers . as_mut ( ) {
650
648
for rc in take ( regs) {
651
649
expand_register_cluster ( regs, rc, & path, & index) ?;
0 commit comments