stegtext 0.1.0

Text steganography command-line tool and library.
Documentation
//! Command-line text steganography tool.
//!
//! # Example
//!
//! ```sh
//! # view contents of `input.txt`
//! $ cat input.txt
//! The Hitchhiker's Guide to the Galaxy is a 1979 science fiction comedy
//! novel by English author Douglas Adams, adapted from the first four parts
//! of his radio comedy series of the same name. It centres on the
//! misadventures of Arthur Dent, the only man to survive the destruction of
//! Earth, as he roams the cosmos and learns the truth behind his very
//! existence. The novel's namesake is an in-universe electronic travel
//! guide written in the form of an encyclopaedia, through which the story
//! is framed.
//!
//! # check capacity
//! $ cargo run -q --bin stegtext capacity < input.txt
//! 23
//!
//! # embed secret, write results to `encoded.txt`
//! $ cargo run -q --bin stegtext encode 'secret message' < input.txt > encoded.txt
//!
//! # view contents of `encoded.txt`
//! $ cat encoded.txt
//! Тhe Нitchhіkеr'ѕ Guide to the Galaxy іѕ a 1979 sсіеncе fiсtion соmedу
//! nоvel by Englіѕh author Dоuglas Аdаmѕ, adаptеd from the fіrѕt four partѕ
//! of hіѕ rаdio comedy ѕeriеs оf thе sаmе namе. It сentreѕ оn the
//! mіѕadventurеѕ оf Arthur Dеnt, thе only mаn tо ѕurvivе the destructіоn of
//! Еаrth, аs he rоаms thе cоsmoѕ аnd learns the truth behind his very
//! existence. The novel's namesake is an in-universe electronic travel
//! guide written in the form of an encyclopaedia, through which the story
//! is framed.
//!
//! # extract secret from `encoded.txt`
//! $ cargo run -q --bin stegtext decode < encoded.txt
//! secret message
//! ```

use clap::{Parser, Subcommand};

#[derive(Clone, Debug, Subcommand)]
enum Command {
  /// Read text from stdin, embed secret, then print result.
  #[command(arg_required_else_help = true)]
  #[command(aliases(["e", "enc"]))]
  Encode {
    /// Secret value to embed.
    secret: String,
  },

  /// Read text from stdin, extract secret, then print secret.
  #[command(aliases(["d", "dec"]))]
  Decode,

  /// Read text from stdin, then print encoding capacity.
  #[command(aliases(["c", "cap"]))]
  Capacity,
}

/// Text steganography tool.
#[derive(Debug, Parser)]
#[command(name = "stegtext")]
struct Cli {
  #[command(subcommand)]
  command: Command,
}

pub fn main() -> Result<(), Box<dyn std::error::Error>> {
  let cli = Cli::parse(); // parse cli args
  let text = std::io::read_to_string(std::io::stdin())?; // read text

  // handle command, print result
  println!("{}", match cli.command {
    Command::Encode { secret } => stegtext::encode(secret.as_bytes(), &text)?,
    Command::Decode => stegtext::decode(&text)?,
    Command::Capacity => stegtext::capacity(&text).to_string(),
  });

  Ok(())
}