@@ -14,6 +14,10 @@ use std::error::Error;
14
14
use std:: result:: Result ;
15
15
use varlink:: parser:: * ;
16
16
use std:: fmt;
17
+ use std:: collections:: HashMap ;
18
+ use std:: iter:: FromIterator ;
19
+
20
+ type EnumHash < ' a > = HashMap < String , Vec < String > > ;
17
21
18
22
trait MainReturn {
19
23
fn into_error_code ( self ) -> i32 ;
@@ -31,27 +35,24 @@ impl<E: Error> MainReturn for Result<(), E> {
31
35
}
32
36
33
37
trait ToRust {
34
- fn to_rust ( & self ) -> Result < String , ToRustError > ;
38
+ fn to_rust ( & self , parent : & str , enumhash : & mut EnumHash ) -> Result < String , ToRustError > ;
35
39
}
36
40
37
41
#[ derive( Debug ) ]
38
42
enum ToRustError {
39
- BadStruct ,
40
43
IoError ( IOError ) ,
41
44
}
42
45
43
46
impl Error for ToRustError {
44
47
fn description ( & self ) -> & str {
45
48
match * self {
46
- ToRustError :: BadStruct => "Anonymous struct" ,
47
49
ToRustError :: IoError ( _) => "an I/O error occurred" ,
48
50
}
49
51
}
50
52
51
53
fn cause ( & self ) -> Option < & Error > {
52
54
match self {
53
55
& ToRustError :: IoError ( ref err) => Some ( & * err as & Error ) ,
54
- _ => None ,
55
56
}
56
57
}
57
58
}
@@ -71,22 +72,27 @@ impl fmt::Display for ToRustError {
71
72
}
72
73
73
74
impl < ' a > ToRust for VType < ' a > {
74
- fn to_rust ( & self ) -> Result < String , ToRustError > {
75
+ fn to_rust ( & self , parent : & str , enumhash : & mut EnumHash ) -> Result < String , ToRustError > {
75
76
match * self {
76
77
VType :: Bool ( _) => Ok ( "bool" . into ( ) ) ,
77
78
VType :: Int ( _) => Ok ( "i64" . into ( ) ) ,
78
79
VType :: Float ( _) => Ok ( "f64" . into ( ) ) ,
79
80
VType :: VString ( _) => Ok ( "String" . into ( ) ) ,
80
81
VType :: VData ( _) => Ok ( "String" . into ( ) ) ,
81
82
VType :: VTypename ( v) => Ok ( v. into ( ) ) ,
82
- VType :: VStruct ( _) => Err ( ToRustError :: BadStruct ) ,
83
+ VType :: VEnum ( ref v) => {
84
+ enumhash. insert ( parent. into ( ) ,
85
+ Vec :: from_iter ( v. elts . iter ( ) . map ( |s| String :: from ( * s) ) ) ) ;
86
+ Ok ( format ! ( "{}" , parent) . into ( ) )
87
+ }
88
+ VType :: VStruct ( _) => Ok ( format ! ( "{}" , parent) . into ( ) ) ,
83
89
}
84
90
}
85
91
}
86
92
87
93
impl < ' a > ToRust for VTypeExt < ' a > {
88
- fn to_rust ( & self ) -> Result < String , ToRustError > {
89
- let v = self . vtype . to_rust ( ) ?;
94
+ fn to_rust ( & self , parent : & str , enumhash : & mut EnumHash ) -> Result < String , ToRustError > {
95
+ let v = self . vtype . to_rust ( parent , enumhash ) ?;
90
96
91
97
if self . isarray {
92
98
Ok ( format ! ( "Vec<{}>" , v) . into ( ) )
@@ -97,45 +103,110 @@ impl<'a> ToRust for VTypeExt<'a> {
97
103
}
98
104
99
105
impl < ' a > ToRust for Interface < ' a > {
100
- fn to_rust ( & self ) -> Result < String , ToRustError > {
106
+ fn to_rust ( & self , _ : & str , _ : & mut EnumHash ) -> Result < String , ToRustError > {
101
107
let mut out: String = "" . to_owned ( ) ;
108
+ let mut enumhash = EnumHash :: new ( ) ;
102
109
103
110
for t in self . typedefs . values ( ) {
104
111
out += "#[derive(Serialize, Deserialize, Debug)]\n " ;
105
- out += format ! ( "pub struct {} {{\n " , t. name) . as_ref ( ) ;
106
- for e in & t. vstruct . elts {
107
- let v = & e. vtypes [ 0 ] ;
108
- out += format ! ( " pub {} : {},\n " , e. name, v. to_rust( ) ?) . as_ref ( ) ;
112
+ match t. elt {
113
+ VStructOrEnum :: VStruct ( ref v) => {
114
+ out += format ! ( "pub struct {} {{\n " , t. name) . as_ref ( ) ;
115
+ for e in & v. elts {
116
+ out += format ! ( " pub {}: Option<{}>,\n " ,
117
+ e. name,
118
+ e. vtype
119
+ . to_rust( format!( "{}_{}" , t. name, e. name) . as_ref( ) ,
120
+ & mut enumhash) ?)
121
+ . as_ref ( ) ;
122
+ }
123
+ }
124
+ VStructOrEnum :: VEnum ( ref v) => {
125
+ out += format ! ( "pub enum {} {{\n " , t. name) . as_ref ( ) ;
126
+ let mut iter = v. elts . iter ( ) ;
127
+ if let Some ( fst) = iter. next ( ) {
128
+ out += format ! ( " {}" , fst) . as_ref ( ) ;
129
+ for elt in iter {
130
+ out += format ! ( ",\n {}" , elt) . as_ref ( ) ;
131
+ }
132
+ }
133
+ out += "\n " ;
134
+ }
109
135
}
110
136
out += "}\n \n " ;
111
137
}
112
138
113
139
for t in self . methods . values ( ) {
114
- out += "#[derive(Serialize, Deserialize, Debug)]\n " ;
115
- out += format ! ( "pub struct {}Reply {{\n " , t. name) . as_ref ( ) ;
116
- for e in & t. output . elts {
117
- let v = & e. vtypes [ 0 ] ;
118
- out += format ! ( " pub {} : {},\n " , e. name, v. to_rust( ) ?) . as_ref ( ) ;
140
+ if t. output . elts . len ( ) > 0 {
141
+ out += "#[derive(Serialize, Deserialize, Debug)]\n " ;
142
+ out += format ! ( "pub struct {}Reply {{\n " , t. name) . as_ref ( ) ;
143
+ for e in & t. output . elts {
144
+ out += format ! ( " pub {}: Option<{}>,\n " ,
145
+ e. name,
146
+ e. vtype. to_rust( self . name, & mut enumhash) ?)
147
+ . as_ref ( ) ;
148
+ }
149
+ out += "}\n \n " ;
119
150
}
120
- out += "}\n \n " ;
121
151
122
152
if t. input . elts . len ( ) > 0 {
123
153
out += "#[derive(Serialize, Deserialize, Debug)]\n " ;
124
154
out += format ! ( "pub struct {}Args {{\n " , t. name) . as_ref ( ) ;
125
155
for e in & t. input . elts {
126
- let v = & e. vtypes [ 0 ] ;
127
- out += format ! ( " pub {} : {},\n " , e. name, v. to_rust( ) ?) . as_ref ( ) ;
156
+ out += format ! ( " pub {}: Option<{}>,\n " ,
157
+ e. name,
158
+ e. vtype. to_rust( self . name, & mut enumhash) ?)
159
+ . as_ref ( ) ;
128
160
}
129
161
out += "}\n \n " ;
130
162
}
163
+
131
164
}
165
+
166
+ for ( name, v) in & enumhash {
167
+ out += format ! ( "pub enum {} {{\n " , name) . as_ref ( ) ;
168
+ let mut iter = v. iter ( ) ;
169
+ if let Some ( fst) = iter. next ( ) {
170
+ out += format ! ( " {}" , fst) . as_ref ( ) ;
171
+ for elt in iter {
172
+ out += format ! ( ",\n {}" , elt) . as_ref ( ) ;
173
+ }
174
+ }
175
+ out += "\n }\n \n " ;
176
+ }
177
+
178
+ out += "pub trait Interface: VarlinkInterface {\n " ;
179
+ for t in self . methods . values ( ) {
180
+ let mut inparms: String = "" . to_owned ( ) ;
181
+ if t. input . elts . len ( ) > 0 {
182
+ for e in & t. input . elts {
183
+ inparms += format ! ( ", {} : {}" ,
184
+ e. name,
185
+ e. vtype. to_rust( self . name, & mut enumhash) ?)
186
+ . as_ref ( ) ;
187
+ }
188
+ }
189
+ let mut c = t. name . chars ( ) ;
190
+ let fname = match c. next ( ) {
191
+ None => String :: from ( t. name ) ,
192
+ Some ( f) => f. to_lowercase ( ) . chain ( c) . collect ( ) ,
193
+ } ;
194
+
195
+ out += format ! ( " fn {}(&self{}) -> Result<{}Reply, Error>;\n " ,
196
+ fname,
197
+ inparms,
198
+ t. name)
199
+ . as_ref ( ) ;
200
+ }
201
+ out += "}\n \n " ;
202
+
132
203
Ok ( out)
133
204
}
134
205
}
135
206
136
207
fn do_main ( ) -> Result < ( ) , ToRustError > {
137
208
let mut buffer = String :: new ( ) ;
138
-
209
+ let mut enumhash = EnumHash :: new ( ) ;
139
210
let args: Vec < _ > = env:: args ( ) . collect ( ) ;
140
211
match args. len ( ) {
141
212
0 | 1 => io:: stdin ( ) . read_to_string ( & mut buffer) ?,
@@ -152,7 +223,17 @@ fn do_main() -> Result<(), ToRustError> {
152
223
exit ( 1 ) ;
153
224
}
154
225
155
- println ! ( "{}" , vr. unwrap( ) . interface. to_rust( ) ?) ;
226
+ println ! (
227
+ r#"
228
+ use serde_json;
229
+ use std::result::Result;
230
+ use std::convert::From;
231
+ use std::borrow::Cow;
232
+ use varlink;
233
+
234
+ {}"# ,
235
+ vr. unwrap( ) . interface. to_rust( "" , & mut enumhash) ?
236
+ ) ;
156
237
157
238
Ok ( ( ) )
158
239
}
0 commit comments