#[cfg(feature = "alloc")]
use alloc::boxed::Box;
use core::fmt;
pub trait Miss: MaybeMiss {
fn miss(address: u64) -> Self;
}
impl<T, E: Miss> Miss for Result<T, E> {
fn miss(address: u64) -> Self {
Err(<E as Miss>::miss(address))
}
}
#[cfg(feature = "alloc")]
impl Miss for Box<dyn MaybeMiss> {
fn miss(address: u64) -> Self {
Box::new(NoInstruction::miss(address))
}
}
#[cfg(feature = "alloc")]
impl Miss for Box<dyn MaybeMissError> {
fn miss(address: u64) -> Self {
Box::new(NoInstruction::miss(address))
}
}
pub trait MaybeMiss {
fn is_miss(&self) -> bool;
}
impl<T, E: MaybeMiss> MaybeMiss for Result<T, E> {
fn is_miss(&self) -> bool {
match self {
Ok(_) => false,
Err(e) => e.is_miss(),
}
}
}
#[cfg(feature = "alloc")]
impl<E: MaybeMiss + ?Sized> MaybeMiss for Box<E> {
fn is_miss(&self) -> bool {
E::is_miss(self.as_ref())
}
}
pub trait MaybeMissError: MaybeMiss + core::error::Error {}
impl<T: MaybeMiss + core::error::Error + ?Sized> MaybeMissError for T {}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum SegmentError {
AddressNotCovered,
ExceededHostUSize(core::num::TryFromIntError),
InvalidInstruction,
}
impl Miss for SegmentError {
fn miss(_: u64) -> Self {
Self::AddressNotCovered
}
}
impl MaybeMiss for SegmentError {
fn is_miss(&self) -> bool {
matches!(self, Self::AddressNotCovered)
}
}
impl core::error::Error for SegmentError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Self::ExceededHostUSize(e) => Some(e),
_ => None,
}
}
}
impl fmt::Display for SegmentError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AddressNotCovered => write!(f, "Given address not covered"),
Self::ExceededHostUSize(_) => write!(
f,
"An offset exceeds what can be represented with host native addresses"
),
Self::InvalidInstruction => write!(f, "No valid instruction at address"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct NoInstruction;
impl Miss for NoInstruction {
fn miss(_: u64) -> Self {
NoInstruction
}
}
impl MaybeMiss for NoInstruction {
fn is_miss(&self) -> bool {
true
}
}
impl core::error::Error for NoInstruction {}
impl fmt::Display for NoInstruction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "No Instruction availible")
}
}