Skip to content

Commit d384b3c

Browse files
committed
- add: complex type encode and decode methods
1 parent 31432ec commit d384b3c

File tree

1 file changed

+95
-4
lines changed

1 file changed

+95
-4
lines changed

generator/src/codegen/rust/codegen_source.rs

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,25 @@ impl<'a, W: Write> CodeSourceGenerator<'a, W> {
125125
debug!(r#"Type "{}" not found, outputting anyway"#, elem.type_());
126126
&trimmed_type
127127
});
128-
cg!(self, "let {} = {}::decode(decoder)?;", name, rust_type);
128+
let (type_, bits) = if let Some(ref o) = elem.occurs() {
129+
use ::flat_ast::Occurs::*;
130+
let type_ = match o {
131+
Unbounded => format!("Vec"),
132+
Num(n) => {
133+
// TODO: Check to see if this is actually needed?
134+
if n.parse::<usize>().is_ok() {
135+
format!("[{}; {}]", rust_type, n)
136+
} else {
137+
format!("[{}; ({} as usize)]", rust_type, n)
138+
}
139+
}
140+
};
141+
(type_, "".to_string())
142+
} else {
143+
let bits = elem.bits().map_or_else(|| "".to_string(), |b| format!(" : {}", b));
144+
(rust_type.to_owned().to_string(), bits)
145+
};
146+
cg!(self, "let {} = {}::decode(decoder)?;", name, type_);
129147
},
130148
_ => {}
131149
};
@@ -172,7 +190,6 @@ impl<'a, W: Write> CodeSourceGenerator<'a, W> {
172190
fn complex_type(&mut self, complex: &ComplexType, iserialize: &HashMap<String, String>) -> Result<()> {
173191
use ::flat_ast::ComplexTypeContent::*;
174192
if complex.inline() == false {
175-
176193
// All unions need to be outside the struct
177194
match complex.content() {
178195
Choice(ref c) => {
@@ -207,8 +224,8 @@ impl<'a, W: Write> CodeSourceGenerator<'a, W> {
207224
}
208225

209226
cg!(self);
210-
cg!(self, r#"#[derive(Debug, Encode, Decode)]"#);
211-
cg!(self, "struct {} {{", complex.name());
227+
cg!(self, r#"#[derive(Debug)]"#);
228+
cg!(self, "pub struct {} {{", complex.name());
212229
self.indent();
213230
match complex.content() {
214231
Seq(ref s) => {
@@ -224,10 +241,84 @@ impl<'a, W: Write> CodeSourceGenerator<'a, W> {
224241
self.dedent();
225242
cg!(self, "}}");
226243
cg!(self);
244+
self.complex_encode(complex, iserialize);
245+
cg!(self);
246+
self.complex_decode(complex, iserialize);
247+
}
248+
Ok(())
249+
}
250+
251+
fn complex_encode(&mut self, complex: &ComplexType, iserialize: &HashMap<String, String>) -> Result<()> {
252+
use ::flat_ast::ComplexTypeContent::*;
253+
cg!(self, "impl Encode for {} {{", complex.name());
254+
self.indent();
255+
cg!(self, "fn encode<E: Encoder>(&self, encoder: &mut E) -> std::result::Result<(), bincode::error::EncodeError> {{");
256+
self.indent();
257+
258+
match complex.content() {
259+
Seq(ref s) => {
260+
for elem in s.elements() {
261+
let data = elem.name().to_string().to_snake_case();
262+
cg!(self, "self.{}.encode(encoder)?;", data);
263+
}
264+
},
265+
Choice(ref c) => {
266+
// TODO: Figure out how to make this work
267+
},
268+
Empty => {}
269+
}
270+
cg!(self, "Ok(())");
271+
272+
self.dedent();
273+
cg!(self, "}}");
274+
self.dedent();
275+
cg!(self, "}}");
276+
Ok(())
277+
}
278+
279+
fn complex_decode(&mut self, complex: &ComplexType, iserialize: &HashMap<String, String>) -> Result<()> {
280+
use ::flat_ast::ComplexTypeContent::*;
281+
cg!(self, "impl Decode for {} {{", complex.name().to_upper_camel_case());
282+
self.indent();
283+
cg!(self, "fn decode<D: Decoder>(decoder: &mut D) -> std::result::Result<Self, bincode::error::DecodeError> {{");
284+
self.indent();
285+
286+
let mut output_list = Vec::new();
287+
match complex.content() {
288+
Seq(ref s) => {
289+
for elem in s.elements() {
290+
let name = elem.name().to_string().to_snake_case();
291+
let trimmed_type = elem.type_().trim().to_string();
292+
let rust_type = iserialize.get(elem.type_().trim()).map(|s| s.to_string()).unwrap_or_else(|| {
293+
debug!(r#"Type "{}" not found, outputting anyway"#, elem.type_());
294+
trimmed_type.clone()
295+
});
296+
297+
cg!(self, "let {} = {}::decode(decoder)?;", name, rust_type);
298+
output_list.push(name);
299+
}
300+
},
301+
Choice(ref c) => {
302+
// TODO: Figure out how to make this work
303+
},
304+
Empty => {}
305+
}
306+
cg!(self, "Ok(Self {{");
307+
self.indent();
308+
for name in &output_list {
309+
cg!(self, "{},", name);
227310
}
311+
self.dedent();
312+
cg!(self, "}})");
313+
314+
self.dedent();
315+
cg!(self, "}}");
316+
self.dedent();
317+
cg!(self, "}}");
228318
Ok(())
229319
}
230320

321+
231322
fn simple_type(&mut self, simple: &SimpleType, iserialize: &HashMap<String, String>) -> Result<()> {
232323
cg!(self);
233324
self.doc(simple.doc())?;

0 commit comments

Comments
 (0)