@@ -28,116 +28,43 @@ extern crate either;
28
28
extern crate xmltree;
29
29
#[ macro_use]
30
30
extern crate failure;
31
- use failure:: ResultExt ;
31
+
32
+ use std:: collections:: HashMap ;
32
33
33
34
use xmltree:: Element ;
34
35
36
+ // ElementExt extends XML elements with useful methods
37
+ pub mod elementext;
38
+ // SVD contains svd primitives
35
39
pub mod svd;
36
40
use svd:: device:: Device ;
41
+ // Error defines SVD error types
37
42
pub mod error;
38
- use error:: { SVDError , SVDErrorKind } ;
43
+ use error:: { SVDError } ;
39
44
40
45
pub mod parse;
46
+ use parse:: Parse ;
47
+
48
+ pub mod encode;
49
+ #[ cfg( feature = "unproven" ) ]
50
+ use encode:: Encode ;
51
+
41
52
pub mod types;
42
- use parse:: BoolParse ;
43
- use types:: Parse ;
44
53
45
- /// Parses the contents of a SVD file (XML)
54
+ /// Parses the contents of an SVD (XML) string
46
55
pub fn parse ( xml : & str ) -> Result < Device , SVDError > {
47
56
let xml = trim_utf8_bom ( xml) ;
48
57
let tree = Element :: parse ( xml. as_bytes ( ) ) ?;
49
58
Device :: parse ( & tree)
50
59
}
51
60
52
- trait ElementExt {
53
- fn get_child_text_opt < K > ( & self , k : K ) -> Result < Option < String > , SVDError >
54
- where
55
- String : PartialEq < K > ;
56
- fn get_child_text < K > ( & self , k : K ) -> Result < String , SVDError >
57
- where
58
- String : PartialEq < K > ,
59
- K : :: std:: fmt:: Display + Clone ;
60
-
61
- fn get_text ( & self ) -> Result < String , SVDError > ;
62
-
63
- fn get_child_elem < ' a > ( & ' a self , n : & str ) -> Result < & ' a Element , SVDError > ;
64
- fn get_child_u32 ( & self , n : & str ) -> Result < u32 , SVDError > ;
65
- fn get_child_bool ( & self , n : & str ) -> Result < bool , SVDError > ;
66
-
67
- fn merge ( & self , n : & Self ) -> Self ;
68
-
69
- fn debug ( & self ) ;
70
- }
71
-
72
- impl ElementExt for Element {
73
- fn get_child_text_opt < K > ( & self , k : K ) -> Result < Option < String > , SVDError >
74
- where
75
- String : PartialEq < K > ,
76
- {
77
- if let Some ( child) = self . get_child ( k) {
78
- Ok ( Some ( child. get_text ( ) . map ( |s| s. to_owned ( ) ) ?) )
79
- } else {
80
- Ok ( None )
81
- }
82
- }
83
- fn get_child_text < K > ( & self , k : K ) -> Result < String , SVDError >
84
- where
85
- String : PartialEq < K > ,
86
- K : :: std:: fmt:: Display + Clone ,
87
- {
88
- self . get_child_text_opt ( k. clone ( ) ) ?. ok_or ( SVDErrorKind :: MissingTag ( self . clone ( ) , format ! ( "{}" , k) ) . into ( ) , )
89
- }
90
-
91
- /// Get text contained by an XML Element
92
- fn get_text ( & self ) -> Result < String , SVDError > {
93
- match self . text . as_ref ( ) {
94
- Some ( s) => Ok ( s. clone ( ) ) ,
95
- // FIXME: Doesn't look good because SVDErrorKind doesn't format by itself. We already
96
- // capture the element and this information can be used for getting the name
97
- // This would fix ParseError
98
- None => {
99
- Err ( SVDErrorKind :: EmptyTag ( self . clone ( ) , self . name . clone ( ) )
100
- . into ( ) )
101
- }
102
- }
103
- }
104
-
105
- /// Get a named child element from an XML Element
106
- fn get_child_elem < ' a > ( & ' a self , n : & str ) -> Result < & ' a Element , SVDError > {
107
- match self . get_child ( n) {
108
- Some ( s) => Ok ( s) ,
109
- None => Err ( SVDErrorKind :: MissingTag ( self . clone ( ) , n. to_string ( ) ) . into ( ) ) ,
110
- }
111
- }
112
-
113
- /// Get a u32 value from a named child element
114
- fn get_child_u32 ( & self , n : & str ) -> Result < u32 , SVDError > {
115
- let s = self . get_child_elem ( n) ?;
116
- u32:: parse ( & s) . context ( SVDErrorKind :: ParseError ( self . clone ( ) ) ) . map_err ( |e| e. into ( ) )
117
- }
118
-
119
- /// Get a bool value from a named child element
120
- fn get_child_bool ( & self , n : & str ) -> Result < bool , SVDError > {
121
- let s = self . get_child_elem ( n) ?;
122
- BoolParse :: parse ( s)
123
- }
124
-
125
- // Merges the children of two elements, maintaining the name and description of the first
126
- fn merge ( & self , r : & Self ) -> Self {
127
- let mut n = self . clone ( ) ;
128
- for c in & r. children {
129
- n. children . push ( c. clone ( ) ) ;
130
- }
131
- n
132
- }
133
-
134
- fn debug ( & self ) {
135
- println ! ( "<{}>" , self . name) ;
136
- for c in & self . children {
137
- println ! ( "{}: {:?}" , c. name, c. text)
138
- }
139
- println ! ( "</{}>" , self . name) ;
140
- }
61
+ /// Encodes a device object to an SVD (XML) string
62
+ #[ cfg( feature = "unproven" ) ]
63
+ pub fn encode ( d : & Device ) -> Result < String , SVDError > {
64
+ let root = d. encode ( ) ?;
65
+ let mut wr = Vec :: new ( ) ;
66
+ root. write ( & mut wr) ;
67
+ Ok ( String :: from_utf8 ( wr) . unwrap ( ) )
141
68
}
142
69
143
70
/// Return the &str trimmed UTF-8 BOM if the input &str contains the BOM.
@@ -149,6 +76,35 @@ fn trim_utf8_bom(s: &str) -> &str {
149
76
}
150
77
}
151
78
79
+ /// Helper to create new base xml elements
80
+ pub ( crate ) fn new_element ( name : & str , text : Option < String > ) -> Element {
81
+ Element {
82
+ name : String :: from ( name) ,
83
+ attributes : HashMap :: new ( ) ,
84
+ children : Vec :: new ( ) ,
85
+ text : text,
86
+ }
87
+ }
88
+
89
+ #[ cfg( test) ]
90
+ use std:: fmt:: Debug ;
91
+ #[ cfg( test) ]
92
+ use types:: { Encode } ;
93
+
94
+ /// Generic test helper function
95
+ /// Takes an array of (item, xml) pairs where the item implements
96
+ /// Parse and Encode and tests object encoding and decoding
97
+ #[ cfg( test) ]
98
+ pub fn run_test < T : Parse < Error =SVDError , Object =T > + Encode < Error =SVDError > + Debug + PartialEq > ( tests : & [ ( T , & str ) ] ) {
99
+ for t in tests {
100
+ let tree1 = Element :: parse ( t. 1 . as_bytes ( ) ) . unwrap ( ) ;
101
+ let elem = T :: parse ( & tree1) . unwrap ( ) ;
102
+ assert_eq ! ( elem, t. 0 , "Error parsing xml` (mismatch between parsed and expected)" ) ;
103
+ let tree2 = elem. encode ( ) . unwrap ( ) ;
104
+ assert_eq ! ( tree1, tree2, "Error encoding xml (mismatch between encoded and original)" ) ;
105
+ } ;
106
+ }
107
+
152
108
#[ cfg( test) ]
153
109
mod tests {
154
110
use super :: * ;
0 commit comments