Function wiggle_generate::names::builtin_type
source · pub fn builtin_type(b: BuiltinType) -> TokenStream
Examples found in repository?
More examples
src/names.rs (line 49)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
pub fn type_ref(tref: &TypeRef, lifetime: TokenStream) -> TokenStream {
match tref {
TypeRef::Name(nt) => {
let ident = type_(&nt.name);
if nt.tref.needs_lifetime() {
quote!(#ident<#lifetime>)
} else {
quote!(#ident)
}
}
TypeRef::Value(ty) => match &**ty {
Type::Builtin(builtin) => builtin_type(*builtin),
Type::Pointer(pointee) | Type::ConstPointer(pointee) => {
let pointee_type = type_ref(&pointee, lifetime.clone());
quote!(wiggle::GuestPtr<#lifetime, #pointee_type>)
}
Type::List(pointee) => match &**pointee.type_() {
Type::Builtin(BuiltinType::Char) => {
quote!(wiggle::GuestPtr<#lifetime, str>)
}
_ => {
let pointee_type = type_ref(&pointee, lifetime.clone());
quote!(wiggle::GuestPtr<#lifetime, [#pointee_type]>)
}
},
Type::Variant(v) => match v.as_expected() {
Some((ok, err)) => {
let ok = match ok {
Some(ty) => type_ref(ty, lifetime.clone()),
None => quote!(()),
};
let err = match err {
Some(ty) => type_ref(ty, lifetime.clone()),
None => quote!(()),
};
quote!(Result<#ok, #err>)
}
None => unimplemented!("anonymous variant ref {:?}", tref),
},
Type::Record(r) if r.is_tuple() => {
let types = r
.members
.iter()
.map(|m| type_ref(&m.tref, lifetime.clone()))
.collect::<Vec<_>>();
quote!((#(#types,)*))
}
_ => unimplemented!("anonymous type ref {:?}", tref),
},
}
}
src/types/record.rs (line 26)
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
pub(super) fn define_struct(name: &witx::Id, s: &witx::RecordDatatype) -> TokenStream {
let ident = names::type_(name);
let size = s.mem_size_align().size as u32;
let align = s.mem_size_align().align as usize;
let member_names = s.members.iter().map(|m| names::struct_member(&m.name));
let member_decls = s.members.iter().map(|m| {
let name = names::struct_member(&m.name);
let type_ = match &m.tref {
witx::TypeRef::Name(nt) => {
let tt = names::type_(&nt.name);
if m.tref.needs_lifetime() {
quote!(#tt<'a>)
} else {
quote!(#tt)
}
}
witx::TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(builtin) => names::builtin_type(*builtin),
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
let pointee_type = names::type_ref(&pointee, quote!('a));
quote!(wiggle::GuestPtr<'a, #pointee_type>)
}
_ => unimplemented!("other anonymous struct members: {:?}", m.tref),
},
};
quote!(pub #name: #type_)
});
let member_reads = s.member_layout().into_iter().map(|ml| {
let name = names::struct_member(&ml.member.name);
let offset = ml.offset as u32;
let location = quote!(location.cast::<u8>().add(#offset)?.cast());
match &ml.member.tref {
witx::TypeRef::Name(nt) => {
let type_ = names::type_(&nt.name);
quote! {
let #name = <#type_ as wiggle::GuestType>::read(&#location)?;
}
}
witx::TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(builtin) => {
let type_ = names::builtin_type(*builtin);
quote! {
let #name = <#type_ as wiggle::GuestType>::read(&#location)?;
}
}
witx::Type::Pointer(pointee) | witx::Type::ConstPointer(pointee) => {
let pointee_type = names::type_ref(&pointee, anon_lifetime());
quote! {
let #name = <wiggle::GuestPtr::<#pointee_type> as wiggle::GuestType>::read(&#location)?;
}
}
_ => unimplemented!("other anonymous struct members: {:?}", ty),
},
}
});
let member_writes = s.member_layout().into_iter().map(|ml| {
let name = names::struct_member(&ml.member.name);
let offset = ml.offset as u32;
quote! {
wiggle::GuestType::write(
&location.cast::<u8>().add(#offset)?.cast(),
val.#name,
)?;
}
});
let (struct_lifetime, extra_derive) = if s.needs_lifetime() {
(quote!(<'a>), quote!())
} else {
(quote!(), quote!(, PartialEq))
};
quote! {
#[derive(Clone, Debug #extra_derive)]
pub struct #ident #struct_lifetime {
#(#member_decls),*
}
impl<'a> wiggle::GuestType<'a> for #ident #struct_lifetime {
fn guest_size() -> u32 {
#size
}
fn guest_align() -> usize {
#align
}
fn read(location: &wiggle::GuestPtr<'a, Self>) -> Result<Self, wiggle::GuestError> {
#(#member_reads)*
Ok(#ident { #(#member_names),* })
}
fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self) -> Result<(), wiggle::GuestError> {
#(#member_writes)*
Ok(())
}
}
}
}