better error trait design

This commit is contained in:
Pat Hickey
2020-01-23 11:21:04 -08:00
parent 7cc0073a3e
commit cb24fd97c0
5 changed files with 29 additions and 72 deletions

View File

@@ -1,57 +0,0 @@
use crate::names::Names;
use heck::SnakeCase;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use std::collections::HashSet;
use witx::{Document, TypeRef};
/// The context struct needs to implement a trait for converting memory and value errors into the
/// witx doc's error types.
///
// XXX im rethinking this. maybe each error type should impl
// pub trait WitxErrorType {
// type Context;
// fn is_success(&self) -> bool;
// fn from_memory_error(memory_error: MemoryError, ctx: &mut Context) -> Self;
// fn from_value_error(value_error: GuestValueError, ctx: &mut Context) -> Self;
// }
//
// where Context is mapped to their wasi ctx.
// It seems less "magic" to leave that impl up to the user, and the error message may be simpler?
//
pub fn define_error_trait(names: &Names, doc: &Document) -> TokenStream {
// All non-anonymous first return types are used to pass errors.
let error_typenames = doc
.modules()
.flat_map(|m| {
m.funcs()
.filter_map(|f| {
f.results.get(0).and_then(|r| match &r.tref {
TypeRef::Name(nt) => Some(nt.name.clone()),
_ => None,
})
})
.collect::<HashSet<witx::Id>>()
})
.collect::<HashSet<witx::Id>>();
let methods = error_typenames.iter().map(|typename| {
let tname = names.type_(typename);
let methodfragment = typename.as_str().to_snake_case();
let success = format_ident!("success_to_{}", methodfragment);
let memory_error = format_ident!("memory_error_to_{}", methodfragment);
let value_error = format_ident!("value_error_to_{}", methodfragment);
quote! {
fn #success(&mut self) -> #tname;
fn #memory_error(&mut self, err: ::memory::MemoryError) -> #tname;
fn #value_error(&mut self, err: ::memory::GuestValueError) -> #tname;
}
});
quote!(
pub trait WitxErrorConversion {
#(#methods)*
}
)
}

View File

@@ -1,6 +1,5 @@
extern crate proc_macro;
mod errors;
mod funcs;
mod names;
mod parse;
@@ -10,7 +9,6 @@ use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use errors::define_error_trait;
use funcs::define_func;
use names::Names;
use types::define_datatype;
@@ -39,12 +37,9 @@ pub fn from_witx(args: TokenStream) -> TokenStream {
)
});
let error_trait = define_error_trait(&names, &doc);
TokenStream::from(quote!(
mod types {
#(#types)*
#error_trait
}
#(#modules)*
))