fn impl_struct(
name: &syn::Ident,
fields: &syn::punctuated::Punctuated<syn::Field, syn::Token![,]>,
generics: &syn::Generics,
) -> proc_macro2::TokenStream { let items: Vec<_> = fields
.iter()
.enumerate()
.map(|(i, f)| { let ident = &f.ident.as_ref().map(|i| quote! {#i}).unwrap_or({ let t = proc_macro2::Literal::usize_unsuffixed(i);
quote! {#t}
}); let ty = &f.ty;
impl_field(ident, ty)
})
.collect();
let gl = &generics.lt_token; let gp = &generics.params; let gg = &generics.gt_token; let gn = gp.iter().map(|param: &syn::GenericParam| match param {
syn::GenericParam::Type(ref t) => { let ident = &t.ident;
quote! { #ident }
}
p => quote! { #p },
}); let gn = quote! { #gl#(#gn ),* #gg }; let gw = if !gp.is_empty() { let gi = gp.iter().map(|param: &syn::GenericParam| match param {
syn::GenericParam::Type(ref t) => { let ident = &t.ident;
quote! { #ident : ::scroll::ctx::TryFromCtx<'a, ::scroll::Endian> + ::std::convert::From<u8> + ::std::marker::Copy,
::scroll::Error : ::std::convert::From<< #identas ::scroll::ctx::TryFromCtx<'a, ::scroll::Endian>>::Error>,
< #identas ::scroll::ctx::TryFromCtx<'a, ::scroll::Endian>>::Error : ::std::convert::From<scroll::Error>
}
},
p => quote! { #p }
});
quote! { #(#gi ),* , }
} else {
quote! {}
};
quote! { impl<'a, #gp > ::scroll::ctx::TryFromCtx<'a, ::scroll::Endian> for#name#gnwhere#gw#name#gn : 'a { type Error = ::scroll::Error; #[inline] fn try_from_ctx(src: &'a [u8], ctx: ::scroll::Endian) -> ::scroll::export::result::Result<(Self, usize), Self::Error> { use ::scroll::Pread; let offset = &mut0; let data = Self { #(#items,)* };
Ok((data, *offset))
}
}
}
}
fn impl_try_from_ctx(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let name = &ast.ident; let generics = &ast.generics; match ast.data {
syn::Data::Struct(ref data) => match data.fields {
syn::Fields::Named(ref fields) => impl_struct(name, &fields.named, generics),
syn::Fields::Unnamed(ref fields) => impl_struct(name, &fields.unnamed, generics),
_ => {
panic!("Pread can not be derived for unit structs")
}
},
_ => panic!("Pread can only be derived for structs"),
}
}
fn impl_pwrite(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let name = &ast.ident; let generics = &ast.generics; match ast.data {
syn::Data::Struct(ref data) => match data.fields {
syn::Fields::Named(ref fields) => impl_try_into_ctx(name, &fields.named, generics),
syn::Fields::Unnamed(ref fields) => impl_try_into_ctx(name, &fields.unnamed, generics),
_ => {
panic!("Pwrite can not be derived for unit structs")
}
},
_ => panic!("Pwrite can only be derived for structs"),
}
}
fn impl_size_with(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let name = &ast.ident; let generics = &ast.generics; match ast.data {
syn::Data::Struct(ref data) => match data.fields {
syn::Fields::Named(ref fields) => size_with(name, &fields.named, generics),
syn::Fields::Unnamed(ref fields) => size_with(name, &fields.unnamed, generics),
_ => {
panic!("SizeWith can not be derived for unit structs")
}
},
_ => panic!("SizeWith can only be derived for structs"),
}
}
fn impl_cread_struct(
name: &syn::Ident,
fields: &syn::punctuated::Punctuated<syn::Field, syn::Token![,]>,
generics: &syn::Generics,
) -> proc_macro2::TokenStream { let items: Vec<_> = fields.iter().enumerate().map(|(i, f)| { let ident = &f.ident.as_ref().map(|i|quote!{#i}).unwrap_or({let t = proc_macro2::Literal::usize_unsuffixed(i); quote!{#t}}); let ty = &f.ty; match *ty {
syn::Type::Array(ref array) => { let arrty = &array.elem; match array.len {
syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(ref int), ..}) => { let size = int.base10_parse::<usize>().unwrap(); let incr = quote! { ::scroll::export::mem::size_of::<#arrty>() };
quote! { #ident: { letmut __tmp: #ty = [0u8.into(); #size]; for i in0..__tmp.len() {
__tmp[i] = src.cread_with(*offset, ctx);
*offset += #incr;
}
__tmp
}
}
},
_ => panic!("IOread derive with bad array constexpr")
}
},
_ => { let size = quote! { ::scroll::export::mem::size_of::<#ty>() };
quote! { #ident: { let res = src.cread_with::<#ty>(*offset, ctx); *offset += #size; res }
}
}
}
}).collect();
let gl = &generics.lt_token; let gp = &generics.params; let gg = &generics.gt_token; let gn = gp.iter().map(|param: &syn::GenericParam| match param {
syn::GenericParam::Type(ref t) => { let ident = &t.ident;
quote! { #ident }
}
p => quote! { #p },
}); let gn = quote! { #gl#(#gn ),* #gg }; let gw = if !gp.is_empty() { let gi = gp.iter().map(|param: &syn::GenericParam| match param {
syn::GenericParam::Type(ref t) => { let ident = &t.ident;
quote! { #ident : ::scroll::ctx::FromCtx<::scroll::Endian> + ::std::convert::From<u8> + ::std::marker::Copy
}
},
p => quote! { #p }
});
quote! { where#(#gi ),* , }
} else {
quote! {}
};
quote! { impl#gl#gp#gg ::scroll::ctx::FromCtx<::scroll::Endian> for#name#gn#gw { #[inline] fn from_ctx(src: &[u8], ctx: ::scroll::Endian) -> Self { use ::scroll::Cread; let offset = &mut0; let data = Self { #(#items,)* };
data
}
}
}
}
fn impl_from_ctx(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let name = &ast.ident; let generics = &ast.generics; match ast.data {
syn::Data::Struct(ref data) => match data.fields {
syn::Fields::Named(ref fields) => impl_cread_struct(name, &fields.named, generics),
syn::Fields::Unnamed(ref fields) => impl_cread_struct(name, &fields.unnamed, generics),
_ => {
panic!("IOread can not be derived for unit structs")
}
},
_ => panic!("IOread can only be derived for structs"),
}
}
fn impl_iowrite(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let name = &ast.ident; let generics = &ast.generics; match ast.data {
syn::Data::Struct(ref data) => match data.fields {
syn::Fields::Named(ref fields) => impl_into_ctx(name, &fields.named, generics),
syn::Fields::Unnamed(ref fields) => impl_into_ctx(name, &fields.unnamed, generics),
_ => {
panic!("IOwrite can not be derived for unit structs")
}
},
_ => panic!("IOwrite can only be derived for structs"),
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.