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:: borrow:: Cow ;
4
5
use std:: collections:: HashMap ;
5
6
use std:: mem:: take;
6
7
use svd_rs:: {
@@ -10,8 +11,8 @@ use svd_rs::{
10
11
11
12
#[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
12
13
pub struct RegisterPath {
13
- peripheral : String ,
14
- path : Vec < String > ,
14
+ pub peripheral : String ,
15
+ pub path : Vec < String > ,
15
16
}
16
17
17
18
impl RegisterPath {
@@ -21,23 +22,25 @@ impl RegisterPath {
21
22
path : Vec :: new ( ) ,
22
23
}
23
24
}
24
- pub fn new_child ( & self , name : & str ) -> Self {
25
+ pub fn new_child ( & self , name : impl Into < String > ) -> Self {
25
26
let mut child = self . clone ( ) ;
26
27
child. path . push ( name. into ( ) ) ;
27
28
child
28
29
}
29
- pub fn split_str ( s : & str ) -> ( Option < Self > , String ) {
30
+ pub fn split_str < ' a > ( s : & ' a str ) -> ( Option < Self > , Cow < ' a , str > ) {
30
31
Self :: split_vec ( s. split ( '.' ) . collect ( ) )
31
32
}
32
- pub fn split_vec ( mut v : Vec < & str > ) -> ( Option < Self > , String ) {
33
- let name = v. pop ( ) . unwrap ( ) . to_string ( ) ;
34
- if v. is_empty ( ) {
35
- ( None , name)
33
+ pub fn split_vec < ' a > ( mut v : Vec < & ' a str > ) -> ( Option < Self > , Cow < ' a , str > ) {
34
+ let name = v. pop ( ) . unwrap ( ) ;
35
+ let mut iter = v. into_iter ( ) ;
36
+ let path = if let Some ( p) = iter. next ( ) {
37
+ let mut rpath = Self :: new ( p) ;
38
+ rpath. path = iter. map ( Into :: into) . collect ( ) ;
39
+ Some ( rpath)
36
40
} else {
37
- let mut rpath = Self :: new ( v[ 0 ] ) ;
38
- rpath. path = v[ 1 ..] . iter ( ) . map ( |c| c. to_string ( ) ) . collect ( ) ;
39
- ( Some ( rpath) , name)
40
- }
41
+ None
42
+ } ;
43
+ ( path, name. into ( ) )
41
44
}
42
45
pub fn parent ( & self ) -> Self {
43
46
let mut parent = self . clone ( ) ;
@@ -48,8 +51,8 @@ impl RegisterPath {
48
51
49
52
#[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
50
53
pub struct FieldPath {
51
- register : RegisterPath ,
52
- name : String ,
54
+ pub register : RegisterPath ,
55
+ pub name : String ,
53
56
}
54
57
55
58
impl FieldPath {
@@ -61,13 +64,28 @@ impl FieldPath {
61
64
}
62
65
}
63
66
67
+ #[ derive( Clone , Debug , PartialEq , Hash , Eq ) ]
68
+ pub struct EnumPath < ' a > {
69
+ pub field : FieldPath ,
70
+ pub name : & ' a str ,
71
+ }
72
+
73
+ impl < ' a > EnumPath < ' a > {
74
+ pub fn new ( f : & FieldPath , name : & ' a str ) -> Self {
75
+ Self {
76
+ field : f. clone ( ) ,
77
+ name,
78
+ }
79
+ }
80
+ }
81
+
64
82
#[ derive( Clone , Debug , Default ) ]
65
- struct Index < ' a > {
66
- peripherals : HashMap < String , & ' a Peripheral > ,
67
- clusters : HashMap < RegisterPath , & ' a Cluster > ,
68
- registers : HashMap < RegisterPath , & ' a Register > ,
69
- fields : HashMap < FieldPath , & ' a Field > ,
70
- evs : HashMap < ( FieldPath , String ) , & ' a EnumeratedValues > ,
83
+ pub struct Index < ' a > {
84
+ pub peripherals : HashMap < Cow < ' a , str > , & ' a Peripheral > ,
85
+ pub clusters : HashMap < RegisterPath , & ' a Cluster > ,
86
+ pub registers : HashMap < RegisterPath , & ' a Register > ,
87
+ pub fields : HashMap < FieldPath , & ' a Field > ,
88
+ pub evs : HashMap < EnumPath < ' a > , & ' a EnumeratedValues > ,
71
89
}
72
90
73
91
impl < ' a > Index < ' a > {
@@ -81,7 +99,7 @@ impl<'a> Index<'a> {
81
99
for c in p. clusters ( ) {
82
100
self . add_cluster ( & path, c) ;
83
101
}
84
- self . peripherals . insert ( name, p) ;
102
+ self . peripherals . insert ( name. into ( ) , p) ;
85
103
}
86
104
}
87
105
let path = RegisterPath :: new ( & p. name ) ;
@@ -91,13 +109,13 @@ impl<'a> Index<'a> {
91
109
for c in p. clusters ( ) {
92
110
self . add_cluster ( & path, c) ;
93
111
}
94
- self . peripherals . insert ( p. name . clone ( ) , p) ;
112
+ self . peripherals . insert ( p. name . as_str ( ) . into ( ) , p) ;
95
113
}
96
114
97
115
fn add_cluster ( & mut self , path : & RegisterPath , c : & ' a Cluster ) {
98
116
if let Cluster :: Array ( info, dim) = c {
99
117
for name in names ( info, dim) {
100
- let cpath = RegisterPath :: new_child ( path, & name) ;
118
+ let cpath = RegisterPath :: new_child ( path, name) ;
101
119
for r in c. registers ( ) {
102
120
self . add_register ( & cpath, r) ;
103
121
}
@@ -119,7 +137,7 @@ impl<'a> Index<'a> {
119
137
fn add_register ( & mut self , path : & RegisterPath , r : & ' a Register ) {
120
138
if let Register :: Array ( info, dim) = r {
121
139
for name in names ( info, dim) {
122
- let rpath = RegisterPath :: new_child ( path, & name) ;
140
+ let rpath = RegisterPath :: new_child ( path, name) ;
123
141
for f in r. fields ( ) {
124
142
self . add_field ( & rpath, f) ;
125
143
}
@@ -138,7 +156,7 @@ impl<'a> Index<'a> {
138
156
let fpath = FieldPath :: new ( path, & name) ;
139
157
for evs in & f. enumerated_values {
140
158
if let Some ( name) = evs. name . as_ref ( ) {
141
- self . evs . insert ( ( fpath. clone ( ) , name. to_string ( ) ) , evs) ;
159
+ self . evs . insert ( EnumPath :: new ( & fpath, name) , evs) ;
142
160
}
143
161
}
144
162
self . fields . insert ( fpath, f) ;
@@ -147,7 +165,7 @@ impl<'a> Index<'a> {
147
165
let fpath = FieldPath :: new ( path, & f. name ) ;
148
166
for evs in & f. enumerated_values {
149
167
if let Some ( name) = evs. name . as_ref ( ) {
150
- self . evs . insert ( ( fpath. clone ( ) , name. to_string ( ) ) , evs) ;
168
+ self . evs . insert ( EnumPath :: new ( & fpath, name) , evs) ;
151
169
}
152
170
}
153
171
self . fields . insert ( fpath, f) ;
@@ -222,11 +240,11 @@ fn derive_cluster(
222
240
let rdpath;
223
241
let cluster_path;
224
242
let d = ( if let Some ( dparent) = dparent {
225
- cluster_path = RegisterPath :: new_child ( & dparent, & dname) ;
243
+ cluster_path = RegisterPath :: new_child ( & dparent, dname) ;
226
244
rdpath = dparent;
227
245
index. clusters . get ( & cluster_path)
228
246
} else {
229
- cluster_path = RegisterPath :: new_child ( path, & dname) ;
247
+ cluster_path = RegisterPath :: new_child ( path, dname) ;
230
248
rdpath = path. clone ( ) ;
231
249
index. clusters . get ( & cluster_path)
232
250
} )
@@ -253,11 +271,11 @@ fn derive_register(
253
271
let rdpath;
254
272
let reg_path;
255
273
let d = ( if let Some ( dparent) = dparent {
256
- reg_path = RegisterPath :: new_child ( & dparent, & dname) ;
274
+ reg_path = RegisterPath :: new_child ( & dparent, dname) ;
257
275
rdpath = dparent;
258
276
index. registers . get ( & reg_path)
259
277
} else {
260
- reg_path = RegisterPath :: new_child ( path, & dname) ;
278
+ reg_path = RegisterPath :: new_child ( path, dname) ;
261
279
rdpath = path. clone ( ) ;
262
280
index. registers . get ( & reg_path)
263
281
} )
@@ -411,15 +429,15 @@ fn derive_enumerated_values(
411
429
index : & Index ,
412
430
) -> Result < ( ) > {
413
431
let mut v: Vec < & str > = dpath. split ( '.' ) . collect ( ) ;
414
- let dname = v. pop ( ) . unwrap ( ) . to_string ( ) ;
432
+ let dname = v. pop ( ) . unwrap ( ) ;
415
433
let d = if v. is_empty ( ) {
416
434
// Only EVNAME: Must be in one of fields in same register
417
435
let rdpath = & fpath. register ;
418
436
if let Some ( r) = index. registers . get ( rdpath) {
419
437
let mut found = None ;
420
438
for f in r. fields ( ) {
421
439
let fdpath = FieldPath :: new ( rdpath, & f. name ) ;
422
- if let Some ( d) = index. evs . get ( & ( fdpath. clone ( ) , dname. clone ( ) ) ) {
440
+ if let Some ( d) = index. evs . get ( & EnumPath :: new ( & fdpath, dname) ) {
423
441
found = Some ( ( d, fdpath) ) ;
424
442
break ;
425
443
}
@@ -429,7 +447,7 @@ fn derive_enumerated_values(
429
447
None
430
448
}
431
449
} else {
432
- let fdname = v. pop ( ) . unwrap ( ) . to_string ( ) ;
450
+ let fdname = v. pop ( ) . unwrap ( ) ;
433
451
let fdpath = if v. is_empty ( ) {
434
452
// FIELD.EVNAME
435
453
FieldPath :: new ( & fpath. register , & fdname)
@@ -441,12 +459,15 @@ fn derive_enumerated_values(
441
459
} else {
442
460
// REG.FIELD.EVNAME
443
461
let mut rdpath = fpath. register . parent ( ) ;
444
- rdpath. path . push ( rdname) ;
462
+ rdpath. path . push ( rdname. into ( ) ) ;
445
463
rdpath
446
464
} ;
447
465
FieldPath :: new ( & rdpath, & fdname)
448
466
} ;
449
- index. evs . get ( & ( fdpath. clone ( ) , dname) ) . map ( |d| ( d, fdpath) )
467
+ index
468
+ . evs
469
+ . get ( & EnumPath :: new ( & fdpath, dname) )
470
+ . map ( |d| ( d, fdpath) )
450
471
} ;
451
472
452
473
if let Some ( ( d, fdpath) ) = d {
0 commit comments