use anyhow::Result;
use clap::Subcommand;
#[derive(Subcommand)]
pub enum StrToolsAction {
#[command(about = "Reverse a string")]
Reverse {
#[arg(help = "Input text")]
input: String,
},
#[command(about = "Show ASCII/Unicode code points for each character")]
Ord {
#[arg(help = "Input text")]
input: String,
},
#[command(about = "Convert space-separated code points to characters")]
Chr {
#[arg(help = "Space-separated code points (e.g. \"72 101 108 108 111\")")]
input: String,
},
}
pub fn run(action: StrToolsAction) -> Result<()> {
match action {
StrToolsAction::Reverse { input } => {
println!("{}", reverse(&input));
}
StrToolsAction::Ord { input } => {
println!("{}", ord(&input));
}
StrToolsAction::Chr { input } => {
println!("{}", chr(&input)?);
}
}
Ok(())
}
pub fn reverse(input: &str) -> String {
input.chars().rev().collect()
}
pub fn ord(input: &str) -> String {
input
.chars()
.map(|c| format!("{}={}", c, c as u32))
.collect::<Vec<_>>()
.join(" ")
}
pub fn chr(input: &str) -> Result<String> {
if input.is_empty() {
return Ok(String::new());
}
input
.split_whitespace()
.map(|s| {
let n: u32 = s
.parse()
.map_err(|_| anyhow::anyhow!("Invalid code point: {}", s))?;
char::from_u32(n).ok_or_else(|| anyhow::anyhow!("Invalid Unicode code point: {}", n))
})
.collect()
}