fcmlib 0.1.0

Library to read and write Brother's FCM plotter files
Documentation
use std::fs;

use nom::combinator::map;
use nom::sequence::tuple;
use nom::IResult;

use crate::cut_data::CutData;
use crate::encode::Encode;
use crate::error::Error;
use crate::file_header::FileHeader;
use crate::piece_table::PieceTable;
use crate::{cut_data, file_header, piece_table};

#[derive(Debug)]
pub struct FcmFile {
    pub file_header: FileHeader,
    pub cut_data: CutData,
    pub piece_table: PieceTable,
}

impl FcmFile {
    pub fn from_bytes(data: &[u8]) -> Result<FcmFile, Error> {
        let (_, file) = read_fcm_file(data).map_err(|e| Error {
            message: format!("Could not parse file: {0}", e),
        })?;
        Ok(file)
    }

    pub fn from_file<T: AsRef<std::path::Path>>(file: T) -> Result<FcmFile, Error> {
        let data = fs::read(file.as_ref()).map_err(|e| Error {
            message: format!("Could not open file: {0}", e),
        })?;
        FcmFile::from_bytes(data.as_slice())
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, Error> {
        self.encode_to_vec().map_err(|e| Error {
            message: format!("Could not serialize file: {0}", e),
        })
    }

    pub fn to_file<T: AsRef<std::path::Path>>(&self, file: T) -> Result<(), Error> {
        fs::write(file, self.to_bytes()?.as_slice()).map_err(|e| Error {
            message: format!("Could not write to file: {0}", e),
        })
    }
}

pub(crate) fn read_fcm_file(input: &[u8]) -> IResult<&[u8], FcmFile> {
    map(
        tuple((
            file_header::read_file_header,
            cut_data::read_cut_data,
            piece_table::read_piece_table,
        )),
        |(file_header, cut_data, piece_table)| FcmFile {
            file_header,
            cut_data,
            piece_table,
        },
    )(input)
}

impl Encode for FcmFile {
    fn encode(&self, buffer: &mut Vec<u8>) -> std::io::Result<()> {
        self.file_header.encode(buffer)?;
        self.cut_data.encode(buffer)?;
        self.piece_table.encode(buffer)?;
        Ok(())
    }
}