pub fn builtin_type(b: BuiltinType) -> TokenStream
Examples found in repository?
src/types/mod.rs (line 56)
54
55
56
57
58
fn define_builtin(name: &witx::Id, builtin: witx::BuiltinType) -> TokenStream {
    let ident = names::type_(name);
    let built = names::builtin_type(builtin);
    quote!(pub type #ident = #built;)
}
More examples
Hide additional 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(())
            }
        }
    }
}