diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-05-20 21:55:24 +0200 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-05-20 21:55:24 +0200 |
commit | 44636e5ab31426a0c08360bd5e0dccd6373b05d4 (patch) | |
tree | acfc33d0ea20971ec467a807ffc5d708b5428fd6 | |
parent | d4aa895dad143e8180769fa74def5651d8470274 (diff) |
basic infrastructure for enum-based (de)serialization
-rw-r--r-- | src/lib.rs | 65 |
1 files changed, 62 insertions, 3 deletions
@@ -42,13 +42,72 @@ pub fn derive_deserialize(item: TokenStream) -> TokenStream { let name = ast.ident; let deserializers = ast.fields.iter().map(|field| { + let mut out = TokenStream::new(); + let field_name = field.ident.as_ref().expect("should be a names struct"); let args = Args::from_attributes(&field.attrs).unwrap(); - quote!( - self.#field_name.deserialize(r)?; - ) + out.extend( + vec![quote!( + let mut len_for = HashMap::new(); + let mut discriminant_for = HashMap::new(); + ) + .into()] + .into_iter(), + ); + + if let Some(attr) = args.len_for { + out.extend( + vec![quote!( + let mut len = 0u16; + len.deserialize(r)?; + + len_for.insert(attr, len); + ) + .into()] + .into_iter(), + ); + } + + if let Some(attr) = args.discriminant_for { + out.extend( + vec![quote!( + let mut discriminant = 0u8; + discriminant.deserialize(r)?; + + discriminant_for.insert(attr, discriminant); + ) + .into()] + .into_iter(), + ); + } + + out.extend( + vec![quote!( + let r = if let Some(attr) = len_for.get(field_name) { + r.take(attr) + } else { + r + }; + ) + .into()] + .into_iter(), + ); + + out.extend( + vec![quote!( + if let Some(attr) = discriminant_for.get(field_name) { + self.#field_name.deserialize_with_discriminant(r, attr)?; + } else { + self.#field_name.deserialize(r)?; + } + ) + .into()] + .into_iter(), + ); + + out }); quote!( |