wiggle_generate/types/
error.rs

1use crate::codegen_settings::TrappableErrorType;
2use crate::names;
3
4use proc_macro2::TokenStream;
5use quote::quote;
6
7pub(super) fn define_error(
8    name: &witx::Id,
9    _v: &witx::Variant,
10    e: &TrappableErrorType,
11) -> TokenStream {
12    let abi_error = names::type_(name);
13    let rich_error = e.typename();
14
15    quote! {
16        #[derive(Debug)]
17        pub struct #rich_error {
18            inner: anyhow::Error,
19        }
20
21        impl std::fmt::Display for #rich_error {
22            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23                write!(f, "{}", self.inner)
24            }
25        }
26        impl std::error::Error for #rich_error {
27            fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
28                self.inner.source()
29            }
30        }
31
32        impl #rich_error {
33            pub fn trap(inner: anyhow::Error) -> #rich_error {
34                Self { inner }
35            }
36            pub fn downcast(self) -> Result<#abi_error, anyhow::Error> {
37                self.inner.downcast()
38            }
39            pub fn downcast_ref(&self) -> Option<&#abi_error> {
40                self.inner.downcast_ref()
41            }
42            pub fn context(self, s: impl Into<String>) -> Self {
43                Self { inner: self.inner.context(s.into()) }
44            }
45        }
46
47        impl From<#abi_error> for #rich_error {
48            fn from(abi: #abi_error) -> #rich_error {
49                #rich_error { inner: anyhow::Error::from(abi) }
50            }
51        }
52    }
53}