123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- use std::{
- fs::File,
- io::{Cursor, Read, Write},
- path::PathBuf,
- time::Instant,
- };
- use binrw::{BinRead, BinWrite, BinWriterExt};
- use clap::Parser;
- use clap_verbosity_flag::{InfoLevel, Verbosity};
- use diff::Diff;
- use env_logger::Target;
- use ezcad::file::EzCadHeader;
- use log::{info, trace, warn};
- use crate::config::{Config, Operations};
- mod config;
- #[derive(Debug, Parser)]
- struct Cli {
- /// Input file to parse
- #[arg(short, long)]
- input: PathBuf,
- /// File to diff input against
- #[arg(short, long)]
- diff: Option<PathBuf>,
- /// Output file to write to
- #[arg(short, long)]
- output: Option<PathBuf>,
- /// Configuration file
- #[arg(short, long)]
- config: Option<PathBuf>,
- #[command(flatten)]
- verbose: Verbosity<InfoLevel>,
- }
- fn main() {
- let cli: Cli = Cli::parse();
- env_logger::builder()
- .format_timestamp(None)
- .format_target(false)
- .filter_level(cli.verbose.log_level_filter())
- .target(Target::Stdout)
- .init();
- info!("Reading input file '{}'", cli.input.to_string_lossy());
- let mut input: File = File::open(cli.input).expect("Failed to open input file");
- // Deserialize to memory buffer for perf
- let mut input_file: Cursor<Vec<u8>> = Cursor::new(vec![]);
- input
- .read_to_end(input_file.get_mut())
- .expect("Failed to read input file");
- // Deserialize as EZCAD format
- let time: Instant = Instant::now();
- let mut file: EzCadHeader =
- EzCadHeader::read_le(&mut input_file).expect("Failed to parse input file as EZCAD format");
- trace!("Input file decode time: {:?}", time.elapsed());
- // Sanity check that re-encoded input file matches original
- info!("Validating re-encoding of input file");
- let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
- let time: Instant = Instant::now();
- file.write_le(&mut buffer)
- .expect("Failed to reserialize input file as EZCAD format");
- trace!("Input file re-encode time: {:?}", time.elapsed());
- if buffer.into_inner().as_slice().ne(input_file.get_ref()) {
- warn!("Re-encoded input file does not match original file!");
- }
- // Print info on pens with non-default settings
- for (index, pen) in file
- .pens_offset
- .data
- .pens
- .iter()
- .filter(|x| *x.use_default == 0)
- .enumerate()
- {
- trace!("Pen {}: {:#?}", index, pen);
- }
- // Print all objects
- for (layer_index, layer) in file.layers_offset.iter().enumerate() {
- for (object_index, object) in layer.objects.iter().enumerate() {
- trace!(
- "Layer {}, Object {}: {:#?}",
- layer_index,
- object_index,
- object
- );
- }
- }
- // Process diff
- cli.diff.map(|diff| {
- info!("Processing diff file '{}'", diff.to_string_lossy());
- let mut diff: File = File::open(diff).expect("Failed to open diff file");
- let diff_file: EzCadHeader =
- EzCadHeader::read_le(&mut diff).expect("Failed to parse diff file as EZCAD format");
- // Diff pens
- info!(
- "{:#?}",
- file.pens_offset
- .data
- .pens
- .diff(&diff_file.pens_offset.data.pens)
- );
- // Diff objects
- info!(
- "{:#?}",
- file.layers_offset
- .value
- .diff(&diff_file.layers_offset.value)
- );
- });
- // Process config
- cli.config.map(|config| {
- info!("Processing config file '{}'", config.to_string_lossy());
- let config: String = std::fs::read_to_string(config).expect("Failed to open config file");
- let config: Config = serde_yaml::from_str(&config).expect("Failed to parse config file");
- // Patch pen settings
- let time: Instant = Instant::now();
- config
- .ops
- .apply(&mut file.pens_offset.data.pens, &mut file.layers_offset);
- trace!("Config processing time: {:?}", time.elapsed());
- });
- // Process output
- cli.output.map(|output| {
- info!("Writing output file '{}'", output.to_string_lossy());
- // Serialize to memory buffer for perf
- let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
- let time: Instant = Instant::now();
- buffer
- .write_le(&file)
- .expect("Failed to serialize contents as EZCAD format");
- trace!("Output file encode time: {:?}", time.elapsed());
- // Write buffer to output file
- let mut output: File = File::create(output).expect("Failed to open output file");
- output
- .write_all(buffer.into_inner().as_slice())
- .expect("Failed to write to output file");
- });
- }
|