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
pub mod error;
pub mod opcode;
use num_traits::FromPrimitive;
use std::io::Read;
use crate::error::DecodeError;
use crate::opcode::{Instruction, Opcode};
pub fn decode<R: Read>(source: &mut R) -> Result<Instruction, DecodeError> {
let mut opcode_buffer = [0u8];
let bytes_read = source.read(&mut opcode_buffer)?;
if bytes_read != opcode_buffer.len() {
return Err(error::DecodeError::InvalidBytesRead);
}
let opcode = Opcode::from_u8(opcode_buffer[0])
.map_or(Err(DecodeError::UnknownOpcode(opcode_buffer[0])), Ok)?;
let arg = if opcode.has_arg() {
let mut argument_buffer = [0u8, 0u8];
let bytes_read = source.read(&mut argument_buffer)?;
if bytes_read != argument_buffer.len() {
return Err(error::DecodeError::InvalidBytesRead);
}
Some(u16::from_le_bytes(argument_buffer))
} else {
None
};
Ok(Instruction { opcode, arg })
}