pub mod gcode_block;
pub mod inflate;
mod block_header;
mod compression_type;
mod default_params;
mod file_handler;
mod file_metadata_block;
mod print_metadata_block;
mod printer_metadata_block;
mod slicer_block;
mod thumbnail_block;
use core::fmt::Display;
use file_handler::FileHeader;
use file_handler::file_header_parser;
use file_metadata_block::FileMetadataBlock;
use file_metadata_block::file_metadata_parser;
use file_metadata_block::file_metadata_parser_with_checksum;
use nom::IResult;
use nom::Parser;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::opt;
use nom::error::ErrorKind;
use nom::error::ParseError;
use nom::multi::many_till;
use nom::multi::many0;
use compression_type::CompressionType;
use gcode_block::GCodeBlock;
use gcode_block::gcode_parser;
use gcode_block::gcode_parser_with_checksum;
use print_metadata_block::PrintMetadataBlock;
use print_metadata_block::print_metadata_parser;
use print_metadata_block::print_metadata_parser_with_checksum;
use printer_metadata_block::PrinterMetadataBlock;
use printer_metadata_block::printer_metadata_parser;
use printer_metadata_block::printer_metadata_parser_with_checksum;
use slicer_block::SlicerBlock;
use slicer_block::slicer_parser;
use slicer_block::slicer_parser_with_checksum;
use thumbnail_block::ThumbnailBlock;
use thumbnail_block::thumbnail_parser;
use thumbnail_block::thumbnail_parser_with_checksum;
pub trait Markdown {
fn markdown<W>(&self, f: &mut W) -> core::fmt::Result
where
W: core::fmt::Write;
}
#[derive(Debug)]
pub enum BlockError {
FileHeader,
FileMetaData,
Gcode,
PrinterMetaData,
PrintMetaData,
Slicer,
Thumbnail,
EOF,
ParseError,
}
impl<I> ParseError<I> for BlockError
where
I: std::fmt::Debug,
{
fn from_error_kind(_input: I, _kind: ErrorKind) -> Self {
Self::EOF
}
fn append(_input: I, _kind: ErrorKind, _other: Self) -> Self {
Self::ParseError
}
fn from_char(input: I, c: char) -> Self {
let message = format!("'{c}':\t{input:?}\n",);
println!("{message}");
Self::ParseError
}
fn or(self, _other: Self) -> Self {
Self::ParseError
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Bgcode<'a> {
fh: FileHeader,
pub file_metadata: Option<FileMetadataBlock<'a>>,
pub printer_metadata: PrinterMetadataBlock<'a>,
pub thumbnails: Vec<ThumbnailBlock<'a>>,
pub print_metadata: PrintMetadataBlock<'a>,
pub slicer: SlicerBlock<'a>,
pub gcode: Vec<GCodeBlock<'a>>,
}
impl Display for Bgcode<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "{}", self.fh)?;
if let Some(file_metadata) = &self.file_metadata {
writeln!(f, "{file_metadata}")?;
} else {
writeln!(f, "No optional file metadata block")?;
}
writeln!(f, "{}", &self.printer_metadata)?;
if self.thumbnails.is_empty() {
writeln!(f, "No optional thumbnail block")?;
} else {
for thumb in &self.thumbnails {
writeln!(f, "{thumb}")?;
}
}
writeln!(f, "{}", self.print_metadata)?;
writeln!(f, "{}", self.slicer)?;
if self.gcode.is_empty() {
writeln!(f, "No optional thumbnail block")?;
} else {
for g in &self.gcode {
writeln!(f, "{g}")?;
}
}
Ok(())
}
}
impl Markdown for Bgcode<'_> {
fn markdown<W>(&self, f: &mut W) -> core::fmt::Result
where
W: std::fmt::Write,
{
self.fh.markdown(&mut *f)?;
if let Some(file_metadata) = &self.file_metadata {
file_metadata.markdown(&mut *f)?;
} else {
writeln!(f, "No optional file metadata block")?;
}
self.printer_metadata.markdown(&mut *f)?;
self.thumbnails.markdown(&mut *f)?;
self.print_metadata.markdown(&mut *f)?;
self.slicer.markdown(&mut *f)?;
self.gcode.markdown(f)?;
Ok(())
}
}
pub fn bgcode_parser(input: &[u8]) -> IResult<&[u8], Bgcode<'_>, BlockError> {
map(
(
file_header_parser,
opt(file_metadata_parser),
printer_metadata_parser,
many0(thumbnail_parser),
print_metadata_parser,
slicer_parser,
many_till(gcode_parser, eof),
),
|(
fh,
file_metadata,
printer_metadata,
thumbnail,
print_metadata,
slicer,
(gcode, _remain),
)| {
log::info!("File has been validated");
Bgcode {
fh,
file_metadata,
printer_metadata,
thumbnails: thumbnail,
print_metadata,
slicer,
gcode,
}
},
)
.parse(input)
}
pub fn bgcode_parser_with_checksum(input: &[u8]) -> IResult<&[u8], Bgcode<'_>, BlockError> {
map(
(
file_header_parser,
opt(file_metadata_parser_with_checksum),
printer_metadata_parser_with_checksum,
many0(thumbnail_parser_with_checksum),
print_metadata_parser_with_checksum,
slicer_parser_with_checksum,
many_till(gcode_parser_with_checksum, eof),
),
|(
fh,
file_metadata,
printer_metadata,
thumbnail,
print_metadata,
slicer,
(gcode, _remain),
)| {
log::info!("File has been validated");
Bgcode {
fh,
file_metadata,
printer_metadata,
thumbnails: thumbnail,
print_metadata,
slicer,
gcode,
}
},
)
.parse(input)
}