diff --git a/dcb-exe/src/exe/inst/basic/alu/imm.rs b/dcb-exe/src/exe/inst/basic/alu/imm.rs index a901fcc..a696989 100644 --- a/dcb-exe/src/exe/inst/basic/alu/imm.rs +++ b/dcb-exe/src/exe/inst/basic/alu/imm.rs @@ -52,21 +52,12 @@ impl Kind { /// Returns a displayable with the value of this kind #[must_use] pub fn value_fmt(self) -> impl fmt::Display { - /// Display wrapper - struct FmtValue(Kind); - - impl fmt::Display for FmtValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - // Signed - Kind::Add(rhs) | Kind::AddUnsigned(rhs) | Kind::SetLessThan(rhs) => write!(f, "{:#}", SignedHex(rhs)), - // Unsigned - Kind::SetLessThanUnsigned(rhs) | Kind::And(rhs) | Kind::Or(rhs) | Kind::Xor(rhs) => write!(f, "{rhs:#x}"), - } - } - } - - FmtValue(self) + dcb_util::DisplayWrapper::new(move |f| match self { + // Signed + Self::Add(rhs) | Self::AddUnsigned(rhs) | Self::SetLessThan(rhs) => write!(f, "{:#}", SignedHex(rhs)), + // Unsigned + Self::SetLessThanUnsigned(rhs) | Self::And(rhs) | Self::Or(rhs) | Self::Xor(rhs) => write!(f, "{rhs:#x}"), + }) } } diff --git a/dcb-exe/src/exe/inst/pseudo/alu_assign.rs b/dcb-exe/src/exe/inst/pseudo/alu_assign.rs index f8bfe5c..b74fac6 100644 --- a/dcb-exe/src/exe/inst/pseudo/alu_assign.rs +++ b/dcb-exe/src/exe/inst/pseudo/alu_assign.rs @@ -39,19 +39,10 @@ impl Kind { /// Returns a displayable with the value of this kind #[must_use] pub fn value_fmt(self) -> impl fmt::Display { - /// Display wrapper - struct FmtValue(Kind); - - impl fmt::Display for FmtValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - Kind::Imm { kind } => write!(f, "{}", kind.value_fmt()), - Kind::Reg { rhs, .. } => write!(f, "{}", rhs), - } - } - } - - FmtValue(self) + dcb_util::DisplayWrapper::new(move |f| match self { + Self::Imm { kind } => write!(f, "{}", kind.value_fmt()), + Self::Reg { rhs, .. } => write!(f, "{}", rhs), + }) } } diff --git a/dcb-exe/src/exe/inst/pseudo/load_imm.rs b/dcb-exe/src/exe/inst/pseudo/load_imm.rs index 1794c62..9d2996b 100644 --- a/dcb-exe/src/exe/inst/pseudo/load_imm.rs +++ b/dcb-exe/src/exe/inst/pseudo/load_imm.rs @@ -45,21 +45,13 @@ impl LoadImmKind { /// Returns a displayable with the value of this load kind formatted. pub fn value_fmt(self) -> impl fmt::Display { - struct FmtValue(Self); - - impl fmt::Display for FmtValue { - #[rustfmt::skip] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.0 { - LoadImmKind::Address(address) => write!(f, "{address:#x}"), - LoadImmKind::Word(value) => write!(f, "{value:#x}"), - LoadImmKind::HalfWordUnsigned(value) => write!(f, "{value:#x}"), - LoadImmKind::HalfWordSigned(value) => write!(f, "{}", SignedHex(value)), - } - } - } - - FmtValue(self) + #[rustfmt::skip] + dcb_util::DisplayWrapper::new(move |f| match self { + Self::Address(address) => write!(f, "{address:#x}"), + Self::Word(value) => write!(f, "{value:#x}"), + Self::HalfWordUnsigned(value) => write!(f, "{value:#x}"), + Self::HalfWordSigned(value) => write!(f, "{}", SignedHex(value)), + }) } } diff --git a/dcb-util/src/display_wrapper.rs b/dcb-util/src/display_wrapper.rs new file mode 100644 index 0000000..c8e9bf7 --- /dev/null +++ b/dcb-util/src/display_wrapper.rs @@ -0,0 +1,22 @@ +//! Display wrapper. + +// Imports +use std::{cell::RefCell, fmt}; + +/// A display wrapper using `F` +pub struct DisplayWrapper fmt::Result>(RefCell); + +impl fmt::Result> DisplayWrapper { + /// Creates a new display wrapper + pub fn new(func: F) -> Self { + Self(RefCell::new(func)) + } +} + + +impl fmt::Result> fmt::Display for DisplayWrapper { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Note: `f` cannot be re-entrant, so this cannot fail + self.0.borrow_mut()(f) + } +} diff --git a/dcb-util/src/lib.rs b/dcb-util/src/lib.rs index 0ff3e9e..4bd52da 100644 --- a/dcb-util/src/lib.rs +++ b/dcb-util/src/lib.rs @@ -91,6 +91,7 @@ pub mod null_ascii_string; #[macro_use] pub mod impl_bytes; pub mod discarding_sorted_merge_iter; +pub mod display_wrapper; pub mod next_from_bytes; pub mod peekable_iter; pub mod signed_hex; @@ -99,6 +100,7 @@ pub mod signed_hex; //pub use array_split::{array_split, array_split_mut}; pub use ascii_str_arr::AsciiStrArr; pub use discarding_sorted_merge_iter::DiscardingSortedMergeIter; +pub use display_wrapper::DisplayWrapper; pub use next_from_bytes::NextFromBytes; pub use peekable_iter::PeekableIter; pub use signed_hex::SignedHex;