maurice 1.3.0

Maurice, a Thomson MO5 emulator
Documentation
use egui::DroppedFile;
use log::info;
use std::fs;
use std::io::{Cursor, Read};
use std::path::PathBuf;

#[derive(Debug)]
pub struct K7 {
    name: String,
    len: u32,
    bytes: Cursor<Vec<u8>>,
}

impl K7 {
    pub(crate) fn len(&self) -> u32 {
        self.len
    }

    pub(crate) fn name(&self) -> &str {
        &self.name
    }

    pub(crate) fn reset(&mut self) {
        self.bytes.set_position(0);
    }

    pub(crate) fn read(&mut self) -> Option<u8> {
        let mut b = [0];
        self.bytes.read_exact(&mut b).ok();
        Some(b[0])
    }
}

impl TryFrom<String> for K7 {
    type Error = String;

    fn try_from(value: String) -> Result<Self, Self::Error> {
        let bytes = fs::read(&value).map_err(|e| e.to_string())?;
        Ok(K7 {
            name: value,
            len: bytes.len() as u32,
            bytes: Cursor::new(bytes),
        })
    }
}

impl TryFrom<PathBuf> for K7 {
    type Error = String;

    fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
        let name = value
            .file_name()
            .and_then(|s| s.to_str())
            .unwrap_or_default()
            .to_string();
        Self::try_from(name)
    }
}

impl TryFrom<&DroppedFile> for K7 {
    type Error = String;

    fn try_from(file: &DroppedFile) -> Result<Self, Self::Error> {
        let name = if let Some(path) = &file.path {
            path.file_name()
                .and_then(|s| s.to_str())
                .unwrap_or_default()
                .to_string()
        } else {
            file.name.clone()
        };
        let bytes;
        if let Some(path) = &file.path {
            info!("Dropped file: {name} reading path");
            bytes = fs::read(path).map_err(|e| e.to_string())?;
        } else if let Some(b) = &file.bytes {
            info!("Dropped file: {name} data length {}b", b.len());
            bytes = b.to_vec();
        } else {
            return Err("No path or bytes".to_string());
        }

        Ok(Self {
            name,
            len: bytes.len() as u32,
            bytes: Cursor::new(bytes),
        })
    }
}