/// Generates the code for reading bytes to struct
///
/// # Params
///
/// * `struct_name` - Name of the struct
/// * `data`        - Information about the struct
///
/// # Returns
///
/// [proc_macro2::TokenStream] with the implementation of the read function.
///
Generates the code for reading bytes to struct
Generates the code for reading bytes to struct
fn generate_fn_read(struct_name: &Ident, data: &Data) -> TokenStream {
    match *data {
        Data::Struct(ref data) => {
            match data.fields {
                // Structs with fields
                Fields::Named(ref fields) => {
                    let struct_fields = fields
                        .named
                        .iter()
                        .map(|field| {
                        let field_name = &field.ident;
                        match &field.ty {
                            Type::Path(_) => {
                                let datatype = crate::utils::ident_from_type(&field.ty);
                                quote! {
                                    #field_name: #datatype::read(buf).await?
                                }
                            }
                            _ => {
                                crate::utils::error(
                                    field.ty.span(),
                                    "The given type is not supported.".into()
                                )
                            }
                        }
                    });
                    quote! {
                        Ok(#struct_name {
                            #(#struct_fields),*
                        })
                    }
                },
                // Struct with only one entry
                Fields::Unnamed(ref fields) => {
                    let datatype = fields
                        .unnamed
                        .iter()
                        .map(|f| {
                        match &f.ty {
                            Type::Path(x) => {
                                let datatype = x.path.segments.first().unwrap().ident.clone();
                                quote! {
                                    Ok(Self(#datatype::read(buf).await?))
                                }
                            },
                            _ => {
                                crate::utils::error(
                                    f.ty.span(),
                                    "The given type is not supported.".into()
                                )
                            }
                        }
                    });
                    quote! {
                        #(#datatype)*
                    }
                },
                // Structs without any fields
                Fields::Unit => quote! {
                    let _ = u8::read(buf).await?;
                    Ok(Self {})
                }
            }
        },
        Data::Enum(ref data) => {
            let fields = data.variants.iter().enumerate().map(|(i, v)| {
                let i = i as u8;
                let field_name = &v.ident;
                match v.fields {
                    Fields::Unnamed(ref fields) => {
                        let datatype = fields
                            .unnamed
                            .iter()
                            .map(|f| {
                            match &f.ty {
                                Type::Path(x) => {
                                    let datatype = crate::utils::get_datatype_enum(x);
                                    quote! {
                                        Self::#field_name(#datatype::read(buf).await?)
                                    }
                                },
                                _ => {
                                    crate::utils::error(
                                        f.ty.span(),
                                        "The given type is not supported.".into()
                                    )
                                }
                            }
                        });
                        quote! {
                            #i => #(#datatype)*
                        }
                    },
                    Fields::Unit => {
                        quote! {
                            #i => {
                                cachem::EmptyMsg::read(buf).await?;
                                Self::#field_name
                            }
                        }
                    }
                    _ => {
                        crate::utils::error(
                            v.fields.span(),
                            "Only unnamed and unit fields are supported.".into()
                        )
                    }
                }
            });
            quote! {
                let index = u8::read(buf).await?;
                let ret = match index {
                    #(#fields),*,
                    _ => panic!("Invalid enum field")
                };
                Ok(ret)
            }
        },
        _ => {
            crate::utils::error(
                struct_name.span(),
                "Only structs are supported.".into()
            )
        }
    }
}
fn generate_fn_read ( struct_name : & Ident , data : & Data ) -> TokenStream { match * data { Data :: Struct ( ref data ) => { match data . fields { // Structs with fields Fields :: Named ( ref fields ) => { let struct_fields = fields . named . iter ( ) . map ( | field | { let field_name = & field . ident ; match & field . ty { Type :: Path ( _ ) => { let datatype = crate :: utils :: ident_from_type ( & field . ty ) ; quote ! { field_name datatype read ( buf ) await } } _ => { crate :: utils :: error ( field . ty . span ( ) , " " . into ( ) ) } } } ) ; quote ! { Ok ( struct_name { ( struct_fields ) } ) } } , // Struct with only one entry Fields :: Unnamed ( ref fields ) => { let datatype = fields . unnamed . iter ( ) . map ( | f | { match & f . ty { Type :: Path ( x ) => { let datatype = x . path . segments . first ( ) . unwrap ( ) . ident . clone ( ) ; quote ! { Ok ( Self ( datatype read ( buf ) await ) ) } } , _ => { crate :: utils :: error ( f . ty . span ( ) , " " . into ( ) ) } } } ) ; quote ! { ( datatype ) } } , // Structs without any fields Fields :: Unit => quote ! { let u8 read ( buf ) await Ok ( Self { } ) } } } , Data :: Enum ( ref data ) => { let fields = data . variants . iter ( ) . enumerate ( ) . map ( | ( i , v ) | { let i = i as u8 ; let field_name = & v . ident ; match v . fields { Fields :: Unnamed ( ref fields ) => { let datatype = fields . unnamed . iter ( ) . map ( | f | { match & f . ty { Type :: Path ( x ) => { let datatype = crate :: utils :: get_datatype_enum ( x ) ; quote ! { Self field_name ( datatype read ( buf ) await ) } } , _ => { crate :: utils :: error ( f . ty . span ( ) , " " . into ( ) ) } } } ) ; quote ! { i ( datatype ) } } , Fields :: Unit => { quote ! { i { cachem EmptyMsg read ( buf ) await Self field_name } } } _ => { crate :: utils :: error ( v . fields . span ( ) , " " . into ( ) ) } } } ) ; quote ! { let index u8 read ( buf ) await let ret match index { ( fields ) panic ( " " ) } Ok ( ret ) } } , _ => { crate :: utils :: error ( struct_name . span ( ) , " " . into ( ) ) } } }
Generates the code for reading bytes to struct
Generates the code for reading bytes to struct
[proc_macro2::TokenStream] with the implementation of the read function.
[ proc_macro2 :: TokenStream ] with the implementation of the read function .
struct_name
&Ident
data
&Data
params
`struct_name` - Name of the struct
`data`        - Information about the struct
` struct_name ` - Name of the struct ` data ` - Information about the struct