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;)*
|
#(#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 {
|
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||||
type Error = wiggle_runtime::GuestError;
|
type Error = wiggle_runtime::GuestError;
|
||||||
fn try_from(value: #repr) -> Result<Self, 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 all_values_token = Literal::u128_unsuffixed(all_values);
|
||||||
|
|
||||||
|
let ident_str = ident.to_string();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Copy, Clone, Debug, ::std::hash::Hash, Eq, PartialEq)]
|
#[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 {
|
impl ::std::ops::BitAnd for #ident {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn bitand(self, rhs: Self) -> Self::Output {
|
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,
|
witx::IntRepr::U64 => witx::AtomType::I64,
|
||||||
});
|
});
|
||||||
|
|
||||||
let variant_names = e.variants.iter().map(|v| names.enum_variant(&v.name));
|
let mut variant_names = vec![];
|
||||||
let tryfrom_repr_cases = e.variants.iter().enumerate().map(|(n, v)| {
|
let mut tryfrom_repr_cases = vec![];
|
||||||
let variant_name = names.enum_variant(&v.name);
|
let mut to_repr_cases = vec![];
|
||||||
quote!(#n => Ok(#ident::#variant_name))
|
let mut to_display = vec![];
|
||||||
});
|
|
||||||
let to_repr_cases = e.variants.iter().enumerate().map(|(n, v)| {
|
for (n, variant) in e.variants.iter().enumerate() {
|
||||||
let variant_name = names.enum_variant(&v.name);
|
let variant_name = names.enum_variant(&variant.name);
|
||||||
quote!(#ident::#variant_name => #n as #repr)
|
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! {
|
quote! {
|
||||||
#[repr(#repr)]
|
#[repr(#repr)]
|
||||||
@@ -303,6 +323,15 @@ fn define_enum(names: &Names, name: &witx::Id, e: &witx::EnumDatatype) -> TokenS
|
|||||||
#(#variant_names),*
|
#(#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 {
|
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||||
type Error = wiggle_runtime::GuestError;
|
type Error = wiggle_runtime::GuestError;
|
||||||
fn try_from(value: #repr) -> Result<#ident, wiggle_runtime::GuestError> {
|
fn try_from(value: #repr) -> Result<#ident, wiggle_runtime::GuestError> {
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
(typename $errno
|
(typename $errno
|
||||||
(enum u32
|
(enum u32
|
||||||
|
;;; Success
|
||||||
$ok
|
$ok
|
||||||
|
;;; Invalid argument
|
||||||
$invalid_arg
|
$invalid_arg
|
||||||
|
;;; I really don't want to
|
||||||
$dont_want_to
|
$dont_want_to
|
||||||
|
;;; I am physically unable to
|
||||||
$physically_unable
|
$physically_unable
|
||||||
|
;;; Well, that's a picket line alright!
|
||||||
$picket_line))
|
$picket_line))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user