aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
blob: 89b3579182267ef5e43a72f1004c5340fe360f58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#![no_std]

#[cfg(feature = "std")]
#[macro_use]
extern crate std;

use core::fmt::{self, Debug, Display};
use core::hash::Hash;

extern crate num_traits;
#[cfg(feature="use-serde")]
extern crate serde;
#[cfg(feature="use-serde")]
#[macro_use] extern crate serde_derive;
#[cfg(feature="colors")]
extern crate crossterm;

#[cfg(feature="use-serde")]
use serde::{Serialize, Deserialize};

mod address;
pub use address::{Address, AddressBase, AddressDiff, AddressDiffAmount, AddressDisplay};
pub use address::{AddressDisplayUsize, AddressDisplayU64, AddressDisplayU32, AddressDisplayU16};
#[cfg(feature="address-parse")]
pub use address::AddrParse;

mod color;
pub use color::{Colorize, NoColors, YaxColors};

#[cfg(feature="colors")]
pub use color::ColorSettings;

pub mod display;

pub trait DecodeError {
    fn data_exhausted(&self) -> bool;
    fn bad_opcode(&self) -> bool;
    fn bad_operand(&self) -> bool;
}

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum StandardDecodeError {
    ExhaustedInput,
    InvalidOpcode,
    InvalidOperand,
}

impl fmt::Display for StandardDecodeError {
    fn fmt(&self, f:  &mut fmt::Formatter) -> fmt::Result {
        match self {
            StandardDecodeError::ExhaustedInput => write!(f, "exhausted input"),
            StandardDecodeError::InvalidOpcode => write!(f, "invalid opcode"),
            StandardDecodeError::InvalidOperand => write!(f, "invalid operand"),
        }
    }
}

impl DecodeError for StandardDecodeError {
    fn data_exhausted(&self) -> bool { *self == StandardDecodeError::ExhaustedInput }
    fn bad_opcode(&self) -> bool { *self == StandardDecodeError::InvalidOpcode }
    fn bad_operand(&self) -> bool { *self == StandardDecodeError::InvalidOperand }
}

    fn decode<T: Reader<A::Word>>(&self, bytes: &mut T) -> Result<A::Instruction, Self::Error> {
        let mut inst = A::Instruction::default();
        self.decode_into(&mut inst, bytes).map(|_: ()| inst)
    }

    fn decode_into<T: Reader<A::Word>>(&self, inst: &mut A::Instruction, bytes: &mut T) -> Result<(), Self::Error>;
}

#[cfg(feature="use-serde")]
pub trait Arch {
    type Word: Debug + Display + PartialEq + Eq;
    type Address: Address + Debug + Hash + PartialEq + Eq + Serialize + for<'de> Deserialize<'de>;
    type Instruction: Instruction + LengthedInstruction<Unit=AddressDiff<Self::Address>> + Debug + Default + Sized;
    type DecodeError: DecodeError + Debug + Display;
    type Decoder: Decoder<Self, Error=Self::DecodeError> + Default;
    type Operand;
}

#[cfg(not(feature="use-serde"))]
pub trait Arch {
    type Word: Debug + Display + PartialEq + Eq;
    type Address: Address + Debug + Hash + PartialEq + Eq;
    type Instruction: Instruction + LengthedInstruction<Unit=AddressDiff<Self::Address>> + Debug + Default + Sized;
    type DecodeError: DecodeError + Debug + Display;
    type Decoder: Decoder<Self, Error=Self::DecodeError> + Default;
    type Operand;
}

pub trait LengthedInstruction {
    type Unit;
    fn len(&self) -> Self::Unit;
    fn min_size() -> Self::Unit;
}

pub trait Instruction {
    fn well_defined(&self) -> bool;
}

pub trait ShowContextual<Addr, Ctx: ?Sized, T: fmt::Write, Y: YaxColors> {
    fn contextualize(&self, colors: &Y, address: Addr, context: Option<&Ctx>, out: &mut T) -> fmt::Result;
}

/*
impl <C: ?Sized, T: fmt::Write, U: Colorize<T>> ShowContextual<C, T> for U {
    fn contextualize(&self, colors: Option<&ColorSettings>, context: Option<&C>, out: &mut T) -> fmt::Result {
        self.colorize(colors, out)
    }
}
*/