arch-ops 0.1.1

A library to encode and decode instructions for several architectures
Documentation
use std::io::Write;

use crate::traits::{Address, InsnWrite, Reloc};

pub struct TestWriter {
    pub inner: Vec<u8>,
}

impl Write for TestWriter {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.inner.write(buf)
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.inner.flush()
    }
}

impl InsnWrite for TestWriter {
    fn write_addr(&mut self, size: usize, addr: Address, rel: bool) -> std::io::Result<()> {
        match (addr, rel) {
            (Address::Disp(disp), true) => self.write_all(&disp.to_le_bytes()[..(size / 8)]),
            (Address::Abs(addr), false) => self.write_all(&addr.to_le_bytes()[..(size / 8)]),
            (_, _) => panic!(),
        }
    }

    fn offset(&self) -> usize {
        self.inner.len()
    }

    fn write_reloc(&mut self, _: Reloc) -> std::io::Result<()> {
        panic!("Cannot write Reloc to TestWriter")
    }
}

#[test]
fn test_sanity_writer_write() {
    let mut w = TestWriter { inner: Vec::new() };
    w.write(&[0u8]).unwrap();
    assert_eq!(&*w.inner, &[0u8]);
}

#[test]
fn test_sanity_writer_write_many() {
    let mut w = TestWriter { inner: Vec::new() };
    w.write(&[0u8, 1u8, 2u8, 3u8]).unwrap();
    assert_eq!(&*w.inner, &[0u8, 1u8, 2u8, 3u8]);
}

#[test]
fn test_sanity_writer_write_addr() {
    let mut w = TestWriter { inner: Vec::new() };
    w.write_addr(32, Address::Disp(1), true).unwrap();
    assert_eq!(&*w.inner, &[1u8, 0u8, 0u8, 0u8]);
}

#[test]
fn test_sanity_writer_write_addr_m1() {
    let mut w = TestWriter { inner: Vec::new() };
    w.write_addr(32, Address::Disp(-1), true).unwrap();
    assert_eq!(&*w.inner, &[0xffu8, 0xffu8, 0xffu8, 0xffu8]);
}

#[test]
fn test_sanity_writer_write_addr_abs() {
    let mut w = TestWriter { inner: Vec::new() };
    w.write_addr(32, Address::Abs(32767), false).unwrap();
    assert_eq!(&*w.inner, &[0xffu8, 0x7fu8, 0u8, 0u8]);
}