ttvm 0.4.2

tt64 emulator API for Rust
Documentation
use super::*;
use std::fs::File;
use std::io::Read;
use std::path::Path;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Storage {
    inner: Box<[u8]>,
    capacity: usize,
}

impl Storage {
    pub fn new() -> Self {
        Storage::with_capacity(1 << 30)
    }

    pub fn with_capacity(capacity: usize) -> Self {
        Storage {
            inner: vec![0; capacity].into_boxed_slice(),
            capacity,
        }
    }

    pub fn from<P: AsRef<Path>>(path: P) -> Result<Self, StorageError> {
        let mut file = match File::open(path.as_ref()) {
            Ok(ok) => ok,
            Err(err) => {
                return Err(StorageError::new(format!(
                    "failed to open file `{}`: {}",
                    path.as_ref().display(),
                    err
                )))
            }
        };

        let mut buf: Vec<u8> = Vec::new();

        match file.read_to_end(&mut buf) {
            Ok(ok) => {
                if ok == 0 {
                    return Err(StorageError::new(format!(
                        "file `{}` is empty",
                        path.as_ref().display()
                    )));
                } else {
                    Ok(Storage {
                        inner: buf.into_boxed_slice(),
                        capacity: ok,
                    })
                }
            }
            Err(err) => {
                return Err(StorageError::new(format!(
                    "failed to read file `{}`: {}",
                    path.as_ref().display(),
                    err
                )))
            }
        }
    }
}

impl IO for Storage {
    fn read(&self, addr: usize, byte: &mut u8) {
        if addr < self.capacity {
            *byte = self.inner[addr];
        }
    }

    fn write(&mut self, addr: usize, byte: u8) {
        if addr < self.capacity {
            self.inner[addr] = byte;
        }
    }

    fn capacity(&self) -> usize {
        self.capacity
    }
}

pub trait StorageSupport {
    fn connect(&mut self, storage: &mut Storage, port: usize);
    fn disconnect(&mut self, port: usize);
    fn is_connected(&self, port: usize) -> bool;
}

pub type StorageError = mtk::Error;