use clap::{Parser, Subcommand};
#[derive(Clone, Debug, Subcommand)]
enum Command {
#[command(arg_required_else_help = true)]
#[command(aliases(["e", "enc"]))]
Encode {
secret: String,
},
#[command(aliases(["d", "dec"]))]
Decode,
#[command(aliases(["c", "cap"]))]
Capacity,
}
impl Command {
fn run(&self, text: String) -> Result<String, Box<dyn std::error::Error>> {
Ok(match self {
Command::Encode { secret } => stegtext::encode(secret.as_bytes(), &text)?,
Command::Decode => stegtext::decode(&text)?,
Command::Capacity => stegtext::capacity(&text).to_string(),
})
}
}
#[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(); let text = std::io::read_to_string(std::io::stdin())?; println!("{}", cli.command.run(text)?); Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_command_run_pass() {
let tests = vec![(
Command::Capacity, "aaaaaaaa aaaaaaaa".to_string(), "0".to_string(), ), (
Command::Decode, "аaаaаaaa aaaaaaaa аaaaaaаa".to_string(), "A".to_string(), ), (
Command::Encode { secret: "A".to_string() }, "aaaaaaaa aaaaaaaa aaaaaaaa".to_string(), "аaаaаaaa aaaaaaaa аaaaaaаa".to_string(), )];
for (c, text, exp) in tests {
assert_eq!(c.run(text).unwrap(), exp);
}
}
}