wiggle: new error configuration for generating a "trappable error" (#5276)
* Add a new "trappable" mode for wiggle to make an error type start refactoring how errors are generated and configured put a pin in this - you can now configure a generated error but i need to go fix Names Names is no longer a struct, rt is hardcoded to wiggle rest of fixes to pass tests its called a trappable error now don't generate UserErrorConversion trait if empty mention in macro docs * undo omitting the user error conversion trait when empty
This commit is contained in:
@@ -27,6 +27,7 @@ mod kw {
|
||||
syn::custom_keyword!(wasmtime);
|
||||
syn::custom_keyword!(tracing);
|
||||
syn::custom_keyword!(disable_for);
|
||||
syn::custom_keyword!(trappable);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -274,14 +275,14 @@ impl Parse for ErrorConf {
|
||||
content.parse_terminated(Parse::parse)?;
|
||||
let mut m = HashMap::new();
|
||||
for i in items {
|
||||
match m.insert(i.abi_error.clone(), i.clone()) {
|
||||
match m.insert(i.abi_error().clone(), i.clone()) {
|
||||
None => {}
|
||||
Some(prev_def) => {
|
||||
return Err(Error::new(
|
||||
i.err_loc,
|
||||
*i.err_loc(),
|
||||
format!(
|
||||
"duplicate definition of rich error type for {:?}: previously defined at {:?}",
|
||||
i.abi_error, prev_def.err_loc,
|
||||
i.abi_error(), prev_def.err_loc(),
|
||||
),
|
||||
))
|
||||
}
|
||||
@@ -291,20 +292,23 @@ impl Parse for ErrorConf {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ErrorConfField {
|
||||
pub abi_error: Ident,
|
||||
pub rich_error: syn::Path,
|
||||
pub err_loc: Span,
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ErrorConfField {
|
||||
Trappable(TrappableErrorConfField),
|
||||
User(UserErrorConfField),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ErrorConfField {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ErrorConfField")
|
||||
.field("abi_error", &self.abi_error)
|
||||
.field("rich_error", &"(...)")
|
||||
.field("err_loc", &self.err_loc)
|
||||
.finish()
|
||||
impl ErrorConfField {
|
||||
pub fn abi_error(&self) -> &Ident {
|
||||
match self {
|
||||
Self::Trappable(t) => &t.abi_error,
|
||||
Self::User(u) => &u.abi_error,
|
||||
}
|
||||
}
|
||||
pub fn err_loc(&self) -> &Span {
|
||||
match self {
|
||||
Self::Trappable(t) => &t.err_loc,
|
||||
Self::User(u) => &u.err_loc,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,12 +317,48 @@ impl Parse for ErrorConfField {
|
||||
let err_loc = input.span();
|
||||
let abi_error = input.parse::<Ident>()?;
|
||||
let _arrow: Token![=>] = input.parse()?;
|
||||
let rich_error = input.parse::<syn::Path>()?;
|
||||
Ok(ErrorConfField {
|
||||
abi_error,
|
||||
rich_error,
|
||||
err_loc,
|
||||
})
|
||||
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(kw::trappable) {
|
||||
let _ = input.parse::<kw::trappable>()?;
|
||||
let rich_error = input.parse()?;
|
||||
Ok(ErrorConfField::Trappable(TrappableErrorConfField {
|
||||
abi_error,
|
||||
rich_error,
|
||||
err_loc,
|
||||
}))
|
||||
} else {
|
||||
let rich_error = input.parse::<syn::Path>()?;
|
||||
Ok(ErrorConfField::User(UserErrorConfField {
|
||||
abi_error,
|
||||
rich_error,
|
||||
err_loc,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TrappableErrorConfField {
|
||||
pub abi_error: Ident,
|
||||
pub rich_error: Ident,
|
||||
pub err_loc: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UserErrorConfField {
|
||||
pub abi_error: Ident,
|
||||
pub rich_error: syn::Path,
|
||||
pub err_loc: Span,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for UserErrorConfField {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ErrorConfField")
|
||||
.field("abi_error", &self.abi_error)
|
||||
.field("rich_error", &"(...)")
|
||||
.field("err_loc", &self.err_loc)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user