png-rusty 0.1.0

A library to parse, encode, decode, manipulate PNG chunks
Documentation
use clap::{Parser, Subcommand};
use std::fs;
use std::path::PathBuf;
use std::str::FromStr;

use png_rusty::chunk::Chunk;
use png_rusty::chunk_type::ChunkType;
use png_rusty::errors::{Error, Result};
use png_rusty::png::Png;

#[derive(Parser, Debug)]
#[command(version, about, long_about=None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand, Debug)]
enum Commands {
    Encode {
        file: PathBuf,
        chunk_type: String,
        secret_message: String,
    },
    Decode {
        file: PathBuf,
        chunk_type: String,
    },
    Remove {
        file: PathBuf,
        chunk_type: String,
    },
    Print {
        file: PathBuf,
    },
}

fn main() -> Result<()> {
    let cli = Cli::parse();

    // Check for subcommands
    match &cli.command {
        Commands::Encode {
            file,
            chunk_type,
            secret_message,
        } => {
            let file_bytes = fs::read(file)?;
            let mut png = Png::try_from(file_bytes.as_slice())?;

            let chunk_type = ChunkType::from_str(chunk_type)?;
            let new_chunk = Chunk::new(chunk_type, secret_message.as_bytes().to_vec());

            png.append_chunk(new_chunk);

            fs::write("img/hidden.png", png.as_bytes())?;
        }
        Commands::Decode { file, chunk_type } => {
            let file_bytes = fs::read(file)?;
            let png = Png::try_from(file_bytes.as_slice())?;

            let chunk = match png.chunk_by_type(chunk_type) {
                Some(chunk) => chunk,
                None => {
                    return Err(Error::from("No chunk found for specified chunk type"));
                }
            };

            let hidden_string = chunk.data_as_string()?;

            println!("Hidden message:'{hidden_string}'");
        }
        Commands::Remove { file, chunk_type } => {
            let file_bytes = fs::read(file)?;
            let mut png = Png::try_from(file_bytes.as_slice())?;

            let chunk = png.remove_first_chunk(chunk_type.as_str())?;
            println!("Removed chunk : {chunk}");

            fs::write("img/removed_chunk.png", png.as_bytes())?;
        }
        Commands::Print { file } => {
            let file_bytes = fs::read(file)?;
            let png = Png::try_from(file_bytes.as_slice())?;

            println!("PNG file content : {png}");
        }
    }
    Ok(())
}