use crate::instruction::{self, Instruction, info};
use crate::types::{Context, trap};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Item<I: info::Info = Option<instruction::Kind>> {
pc: u64,
kind: Kind<I>,
}
impl<I: info::Info> Item<I> {
pub fn new(pc: u64, kind: Kind<I>) -> Self {
Self { pc, kind }
}
pub fn pc(&self) -> u64 {
self.pc
}
pub fn kind(&self) -> &Kind<I> {
&self.kind
}
pub fn instruction(&self) -> Option<&Instruction<I>> {
match &self.kind {
Kind::Regular(insn) => Some(insn),
_ => None,
}
}
pub fn trap(&self) -> Option<&trap::Info> {
match &self.kind {
Kind::Trap(info) => Some(info),
_ => None,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Kind<I: info::Info = Option<instruction::Kind>> {
Regular(Instruction<I>),
Trap(trap::Info),
Context(Context),
}
impl<I: info::Info> From<Instruction<I>> for Kind<I> {
fn from(insn: Instruction<I>) -> Self {
Self::Regular(insn)
}
}
impl From<instruction::Kind> for Kind<Option<instruction::Kind>> {
fn from(insn: instruction::Kind) -> Self {
Self::Regular(insn.into())
}
}
impl<I: info::Info> From<trap::Info> for Kind<I> {
fn from(info: trap::Info) -> Self {
Self::Trap(info)
}
}
impl<I: info::Info> From<Context> for Kind<I> {
fn from(context: Context) -> Self {
Self::Context(context)
}
}