Function wiggle_generate::names::type_

source ·
pub fn type_(id: &Id) -> Ident
Examples found in repository?
src/types/mod.rs (line 45)
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
fn define_alias(name: &witx::Id, to: &witx::NamedType) -> TokenStream {
    let ident = names::type_(name);
    let rhs = names::type_(&to.name);
    if to.tref.needs_lifetime() {
        quote!(pub type #ident<'a> = #rhs<'a>;)
    } else {
        quote!(pub type #ident = #rhs;)
    }
}

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;)
}

fn define_witx_pointer(
    name: &witx::Id,
    pointer_type: TokenStream,
    pointee: &witx::TypeRef,
) -> TokenStream {
    let ident = names::type_(name);
    let pointee_type = names::type_ref(pointee, quote!('a));

    quote!(pub type #ident<'a> = #pointer_type<'a, #pointee_type>;)
}

fn define_witx_list(name: &witx::Id, arr_raw: &witx::TypeRef) -> TokenStream {
    let ident = names::type_(name);
    let pointee_type = names::type_ref(arr_raw, quote!('a));
    quote!(pub type #ident<'a> = wiggle::GuestPtr<'a, [#pointee_type]>;)
}
More examples
Hide additional examples
src/types/error.rs (line 12)
7
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
pub(super) fn define_error(
    name: &witx::Id,
    _v: &witx::Variant,
    e: &TrappableErrorType,
) -> TokenStream {
    let abi_error = names::type_(name);
    let rich_error = e.typename();

    quote! {
        #[derive(Debug)]
        pub struct #rich_error {
            inner: anyhow::Error,
        }

        impl std::fmt::Display for #rich_error {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                write!(f, "{}", self.inner)
            }
        }
        impl std::error::Error for #rich_error {
            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
                self.inner.source()
            }
        }

        impl #rich_error {
            pub fn trap(inner: anyhow::Error) -> #rich_error {
                Self { inner }
            }
            pub fn downcast(self) -> Result<#abi_error, anyhow::Error> {
                self.inner.downcast()
            }
            pub fn downcast_ref(&self) -> Option<&#abi_error> {
                self.inner.downcast_ref()
            }
            pub fn context(self, s: impl Into<String>) -> Self {
                Self { inner: self.inner.context(s.into()) }
            }
        }

        impl From<#abi_error> for #rich_error {
            fn from(abi: #abi_error) -> #rich_error {
                #rich_error { inner: anyhow::Error::from(abi) }
            }
        }
    }
}
src/types/handle.rs (line 8)
7
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
pub(super) fn define_handle(name: &witx::Id, h: &witx::HandleDatatype) -> TokenStream {
    let ident = names::type_(name);
    let size = h.mem_size_align().size as u32;
    let align = h.mem_size_align().align as usize;
    quote! {
        #[repr(transparent)]
        #[derive(Copy, Clone, Debug, ::std::hash::Hash, Eq, PartialEq)]
        pub struct #ident(u32);

        impl #ident {
            pub unsafe fn inner(&self) -> u32 {
                self.0
            }
        }

        impl From<#ident> for u32 {
            fn from(e: #ident) -> u32 {
                e.0
            }
        }

        impl From<#ident> for i32 {
            fn from(e: #ident) -> i32 {
                e.0 as i32
            }
        }

        impl From<u32> for #ident {
            fn from(e: u32) -> #ident {
                #ident(e)
            }
        }
        impl From<i32> for #ident {
            fn from(e: i32) -> #ident {
                #ident(e as u32)
            }
        }

        impl ::std::fmt::Display for #ident {
            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                write!(f, "{}({})", stringify!(#ident), self.0)
            }
        }

        impl<'a> wiggle::GuestType<'a> for #ident {
            fn guest_size() -> u32 {
                #size
            }

            fn guest_align() -> usize {
                #align
            }

            fn read(location: &wiggle::GuestPtr<'a, #ident>) -> Result<#ident, wiggle::GuestError> {
                Ok(#ident(u32::read(&location.cast())?))
            }

            fn write(location: &wiggle::GuestPtr<'_, Self>, val: Self) -> Result<(), wiggle::GuestError> {
                u32::write(&location.cast(), val.0)
            }
        }
    }
}
src/names.rs (line 41)
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/lib.rs (line 32)
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
pub fn generate(doc: &witx::Document, settings: &CodegenSettings) -> TokenStream {
    let types = doc
        .typenames()
        .map(|t| define_datatype(&t, settings.errors.for_name(&t)));

    let constants = doc.constants().map(|c| {
        let name = quote::format_ident!(
            "{}_{}",
            c.ty.as_str().to_shouty_snake_case(),
            c.name.as_str().to_shouty_snake_case()
        );
        let ty = names::type_(&c.ty);
        let value = Literal::u64_unsuffixed(c.value);
        quote! {
            pub const #name: #ty = #value;
        }
    });

    let user_error_methods = settings.errors.iter().filter_map(|errtype| match errtype {
        ErrorType::User(errtype) => {
            let abi_typename = names::type_ref(&errtype.abi_type(), anon_lifetime());
            let user_typename = errtype.typename();
            let methodname = names::user_error_conversion_method(&errtype);
            Some(quote! {
                fn #methodname(&mut self, e: super::#user_typename)
                    -> wiggle::anyhow::Result<#abi_typename>;
            })
        }
        ErrorType::Generated(_) => None,
    });
    let user_error_conversion = quote! {
        pub trait UserErrorConversion {
            #(#user_error_methods)*
        }
    };
    let modules = doc.modules().map(|module| {
        let modname = names::module(&module.name);
        let fs = module.funcs().map(|f| define_func(&module, &f, &settings));
        let modtrait = define_module_trait(&module, &settings);
        let wasmtime = if settings.wasmtime {
            crate::wasmtime::link_module(&module, None, &settings)
        } else {
            quote! {}
        };
        quote!(
            pub mod #modname {
                use super::types::*;
                pub use super::types::UserErrorConversion;
                #(#fs)*

                #modtrait

                #wasmtime
            }
        )
    });

    quote!(
        pub mod types {
            use std::convert::TryFrom;

            #(#types)*
            #(#constants)*
            #user_error_conversion
        }
        #(#modules)*
    )
}
src/types/flags.rs (line 11)
6
7
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
pub(super) fn define_flags(
    name: &witx::Id,
    repr: witx::IntRepr,
    record: &witx::RecordDatatype,
) -> TokenStream {
    let ident = names::type_(&name);
    let abi_repr = names::wasm_type(repr.into());
    let repr = super::int_repr_tokens(repr);

    let mut names_ = vec![];
    let mut values_ = vec![];
    for (i, member) in record.members.iter().enumerate() {
        let name = names::flag_member(&member.name);
        let value_token = Literal::usize_unsuffixed(1 << i);
        names_.push(name);
        values_.push(value_token);
    }

    quote! {
        wiggle::bitflags::bitflags! {
            pub struct #ident: #repr {
                #(const #names_ = #values_;)*
            }
        }

        impl ::std::fmt::Display for #ident {
            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str(stringify!(#ident))?;
                f.write_str("(")?;
                ::std::fmt::Debug::fmt(self, f)?;
                f.write_str(" (0x")?;
                ::std::fmt::LowerHex::fmt(&self.bits, f)?;
                f.write_str("))")?;
                Ok(())
            }
        }

        impl TryFrom<#repr> for #ident {
            type Error = wiggle::GuestError;
            fn try_from(value: #repr) -> Result<Self, wiggle::GuestError> {
                if #repr::from(!#ident::all()) & value != 0 {
                    Err(wiggle::GuestError::InvalidFlagValue(stringify!(#ident)))
                } else {
                    Ok(#ident { bits: value })
                }
            }
        }

        impl TryFrom<#abi_repr> for #ident {
            type Error = wiggle::GuestError;
            fn try_from(value: #abi_repr) -> Result<Self, wiggle::GuestError> {
                #ident::try_from(#repr::try_from(value)?)
            }
        }

        impl From<#ident> for #repr {
            fn from(e: #ident) -> #repr {
                e.bits
            }
        }

        impl<'a> wiggle::GuestType<'a> for #ident {
            fn guest_size() -> u32 {
                #repr::guest_size()
            }

            fn guest_align() -> usize {
                #repr::guest_align()
            }

            fn read(location: &wiggle::GuestPtr<#ident>) -> Result<#ident, wiggle::GuestError> {
                use std::convert::TryFrom;
                let reprval = #repr::read(&location.cast())?;
                let value = #ident::try_from(reprval)?;
                Ok(value)
            }

            fn write(location: &wiggle::GuestPtr<'_, #ident>, val: Self) -> Result<(), wiggle::GuestError> {
                let val: #repr = #repr::from(val);
                #repr::write(&location.cast(), val)
            }
        }
    }
}