Implement fmt::Display for enums, flags, and ints (#18)
* Implement fmt::Display for enums `wasi_common` relies on `strerror` to nicely format error messages. `strerror` is autoimplemented in `wig`. I thought it might be useful to provide a Rust-idiomatic alternative which boils down to autoimplementing `fmt::Display` for all enums. * Implement fmt::Display for flags * Implement fmt::Display for ints
This commit is contained in:
@@ -72,6 +72,12 @@ fn define_int(names: &Names, name: &witx::Id, i: &witx::IntDatatype) -> TokenStr
|
||||
#(#consts;)*
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for #ident {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||
type Error = wiggle_runtime::GuestError;
|
||||
fn try_from(value: #repr) -> Result<Self, wiggle_runtime::GuestError> {
|
||||
@@ -153,6 +159,8 @@ fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDatatype) -> Toke
|
||||
}
|
||||
let all_values_token = Literal::u128_unsuffixed(all_values);
|
||||
|
||||
let ident_str = ident.to_string();
|
||||
|
||||
quote! {
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Debug, ::std::hash::Hash, Eq, PartialEq)]
|
||||
@@ -167,6 +175,12 @@ fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDatatype) -> Toke
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for #ident {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
write!(f, "{}({:#b})", #ident_str, self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitAnd for #ident {
|
||||
type Output = Self;
|
||||
fn bitand(self, rhs: Self) -> Self::Output {
|
||||
@@ -286,15 +300,21 @@ fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenS
|
||||
witx::IntRepr::U64 => witx::AtomType::I64,
|
||||
});
|
||||
|
||||
let variant_names = e.variants.iter().map(|v| names.enum_variant(&v.name));
|
||||
let tryfrom_repr_cases = e.variants.iter().enumerate().map(|(n, v)| {
|
||||
let variant_name = names.enum_variant(&v.name);
|
||||
quote!(#n => Ok(#ident::#variant_name))
|
||||
});
|
||||
let to_repr_cases = e.variants.iter().enumerate().map(|(n, v)| {
|
||||
let variant_name = names.enum_variant(&v.name);
|
||||
quote!(#ident::#variant_name => #n as #repr)
|
||||
});
|
||||
let mut variant_names = vec![];
|
||||
let mut tryfrom_repr_cases = vec![];
|
||||
let mut to_repr_cases = vec![];
|
||||
let mut to_display = vec![];
|
||||
|
||||
for (n, variant) in e.variants.iter().enumerate() {
|
||||
let variant_name = names.enum_variant(&variant.name);
|
||||
let docs = variant.docs.trim();
|
||||
let ident_str = ident.to_string();
|
||||
let variant_str = variant_name.to_string();
|
||||
tryfrom_repr_cases.push(quote!(#n => Ok(#ident::#variant_name)));
|
||||
to_repr_cases.push(quote!(#ident::#variant_name => #n as #repr));
|
||||
to_display.push(quote!(#ident::#variant_name => format!("{} ({}::{}({}))", #docs, #ident_str, #variant_str, #repr::from(*self))));
|
||||
variant_names.push(variant_name);
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[repr(#repr)]
|
||||
@@ -303,6 +323,15 @@ fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenS
|
||||
#(#variant_names),*
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for #ident {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
let to_str = match self {
|
||||
#(#to_display,)*
|
||||
};
|
||||
write!(f, "{}", to_str)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||
type Error = wiggle_runtime::GuestError;
|
||||
fn try_from(value: #repr) -> Result<#ident, wiggle_runtime::GuestError> {
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
(typename $errno
|
||||
(enum u32
|
||||
;;; Success
|
||||
$ok
|
||||
;;; Invalid argument
|
||||
$invalid_arg
|
||||
;;; I really don't want to
|
||||
$dont_want_to
|
||||
;;; I am physically unable to
|
||||
$physically_unable
|
||||
;;; Well, that's a picket line alright!
|
||||
$picket_line))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user