mila 0.1.5

A library for interacting with common formats from FE9-FE15.
Documentation
use crate::{BinArchive, ArchiveError};

type Result<T> = std::result::Result<T, ArchiveError>;

pub struct BinArchiveReader<'a> {
    archive: &'a BinArchive,
    position: usize
}

pub struct BinArchiveWriter<'a> {
    archive: &'a mut BinArchive,
    position: usize
}

impl<'a> BinArchiveReader<'a> {
    pub fn new(archive: &'a BinArchive, position: usize) -> Self {
        BinArchiveReader {
            archive,
            position
        }
    }

    pub fn archive(&self) -> &'a BinArchive {
        self.archive
    }

    pub fn seek(&mut self, position: usize) {
        self.position = position;
    }

    pub fn skip(&mut self, amount: usize) {
        self.position += amount;
    }

    pub fn tell(&self) -> usize {
        return self.position;
    }

    pub fn read_u8(&mut self) -> Result<u8> {
        let value = self.archive.read_u8(self.position)?;
        self.position += 1;
        Ok(value)
    }

    pub fn read_u16(&mut self) -> Result<u16> {
        let value = self.archive.read_u16(self.position)?;
        self.position += 2;
        Ok(value)
    }

    pub fn read_u32(&mut self) -> Result<u32> {
        let value = self.archive.read_u32(self.position)?;
        self.position += 4;
        Ok(value)
    }

    pub fn read_i8(&mut self) -> Result<i8> {
        let value = self.read_u8()?;
        Ok(value as i8)
    }

    pub fn read_i16(&mut self) -> Result<i16> {
        let value = self.read_u16()?;
        Ok(value as i16)
    }

    pub fn read_i32(&mut self) -> Result<i32> {
        let value = self.read_u32()?;
        Ok(value as i32)
    }

    pub fn read_bytes(&mut self, count: usize) -> Result<Vec<u8>> {
        let mut result: Vec<u8> = Vec::new();
        for _ in 0..count {
            result.push(self.read_u8()?);
        }
        Ok(result)
    }

    pub fn read_f32(&mut self) -> Result<f32> {
        let value = self.archive.read_f32(self.position)?;
        self.position += 4;
        Ok(value)
    }

    pub fn read_string(&mut self) -> Result<Option<String>> {
        let value = self.archive.read_string(self.position)?;
        self.position += 4;
        Ok(value)
    }

    pub fn read_label(&mut self, index: usize) -> Result<Option<String>> {
        Ok(match self.archive.read_labels(index)? {
            Some(bucket) => bucket.first().map(|x| x.to_owned()),
            None => None
        })
    }

    pub fn read_labels(&mut self) -> Result<Option<Vec<String>>> {
        self.archive.read_labels(self.position)
    }

    pub fn read_pointer(&mut self) -> Result<Option<usize>> {
        let value = self.archive.read_pointer(self.position)?;
        self.position += 4;
        Ok(value)
    }
}

impl<'a> BinArchiveWriter<'a> {
    pub fn new(archive: &'a mut BinArchive, position: usize) -> Self {
        BinArchiveWriter {
            archive,
            position
        }
    }

    pub fn size(&self) -> usize {
        self.archive.size()
    }

    pub fn seek(&mut self, position: usize) {
        self.position = position;
    }

    pub fn skip(&mut self, amount: usize) {
        self.position += amount;
    }

    pub fn tell(&self) -> usize {
        return self.position;
    }

    pub fn length(&self) -> usize {
        return self.archive.size()
    }

    pub fn allocate(&mut self, amount: usize) -> Result<()> {
        if self.position == self.archive.size() {
            self.archive.allocate_at_end(amount);
        } else {
            self.archive.allocate(self.position, amount)?;
        }
        Ok(())
    }

    pub fn allocate_at_end(&mut self, amount: usize) {
        self.archive.allocate_at_end(amount)
    }

    pub fn write_u8(&mut self, value: u8) -> Result<()> {
        self.archive.write_u8(self.position, value)?;
        self.position += 1;
        Ok(())
    }

    pub fn write_u16(&mut self, value: u16) -> Result<()> {
        self.archive.write_u16(self.position, value)?;
        self.position += 2;
        Ok(())
    }

    pub fn write_u32(&mut self, value: u32) -> Result<()> {
        self.archive.write_u32(self.position, value)?;
        self.position += 4;
        Ok(())
    }

    pub fn write_i8(&mut self, value: i8) -> Result<()> {
        self.write_u8(value as u8)
    }

    pub fn write_i16(&mut self, value: i16) -> Result<()> {
        self.write_u16(value as u16)
    }

    pub fn write_i32(&mut self, value: i32) -> Result<()> {
        self.write_u32(value as u32)
    }

    pub fn write_bytes(&mut self, value: &[u8]) -> Result<()> {
        for byte in value {
            self.write_u8(*byte)?;
        }
        Ok(())
    }

    pub fn write_f32(&mut self, value: f32) -> Result<()> {
        self.archive.write_f32(self.position, value)?;
        self.position += 4;
        Ok(())
    }

    pub fn write_string(&mut self, value: Option<&str>) -> Result<()> {
        self.archive.write_string(self.position, value)?;
        self.position += 4;
        Ok(())
    }

    pub fn write_label(&mut self, value: &str) -> Result<()> {
        self.archive.write_label(self.position, value)
    }

    pub fn write_pointer(&mut self, value: Option<usize>) -> Result<()> {
        self.archive.write_pointer(self.position, value)?;
        self.position += 4;
        Ok(())
    }
}