feat: first working version

This commit is contained in:
Christoph J. Scherr 2024-05-10 15:55:24 +02:00
parent 6ffe30986b
commit 6c66c285a0
3 changed files with 150 additions and 9 deletions

View File

@ -1,16 +1,19 @@
[package]
name = "template"
name = "numf"
version = "0.1.0"
edition = "2021"
publish = false
authors = ["Christoph J. Scherr <software@cscherr.de>"]
license = "MIT"
description = "No description yet"
description = "Convert numbes between formats"
readme = "README.md"
homepage = "https://git.cscherr.de/PlexSheep/rs-base"
repository = "https://git.cscherr.de/PlexSheep/rs-base"
keywords = ["template"]
homepage = "https://git.cscherr.de/PlexSheep/numf"
repository = "https://git.cscherr.de/PlexSheep/numf"
keywords = ["cli"]
[dependencies]
anyhow = "1.0.83"
clap = { version = "4.5.4", features = ["derive"] }
clap-num = "1.1.1"

View File

@ -1,3 +1,4 @@
# rs-base
# numf
Base repository for rust projects
This is just a trivial program that format's it's arguments in binary, hex or
octal.

View File

@ -1,3 +1,140 @@
fn main() {
println!("Hello, world!");
//! # numf
//!
//! This binary should just take any amount of numbers and print them out formatted to some other
//! system.
use clap::{ArgGroup, Parser};
use clap_num::maybe_hex;
use std::process::exit;
pub type Num = usize;
#[derive(Copy, Clone, Debug)]
enum Format {
Dec,
Hex,
Bin,
Octal,
}
impl Format {
fn prefix(&self) -> String {
match self {
Format::Dec => "0d",
Format::Hex => "0x",
Format::Bin => "0b",
Format::Octal => "0o",
}
.to_string()
}
fn format(&self, num: Num, prefix: bool) -> String {
let mut buf = String::new();
if prefix {
buf += &self.prefix();
}
match self {
Format::Hex => {
buf += &format!("{num:X}");
}
Format::Bin => {
buf += &format!("{num:b}");
}
Format::Octal => {
buf += &format!("{num:o}");
}
Format::Dec => {
buf += &format!("{num}");
}
}
buf
}
}
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
#[clap(group(
ArgGroup::new("format")
.required(true)
.args(&["hex", "bin", "oct", "dec"]),
))]
struct Cli {
#[arg(short, long)]
/// add a prefix (like "0x" for hex)
prefix: bool,
#[arg(short = 'x', long)]
/// format to hexadecimal
hex: bool,
#[arg(short, long)]
/// format to binary
bin: bool,
#[arg(short, long)]
/// format to decimal
dec: bool,
#[arg(short, long)]
/// format to octal
oct: bool,
#[clap(value_parser=maybe_hex::<Num>)]
/// at least one number that should be formatted
///
/// supports either base 10 or base 16 inputs (with 0xaaaa)
numbers: Vec<Num>,
}
impl Cli {
fn format(&self) -> Format {
if self.oct {
Format::Octal
} else if self.bin {
Format::Bin
} else if self.dec {
Format::Dec
} else {
Format::Hex
}
}
}
fn main() {
match formatter() {
Ok(_) => (),
Err(_err) => usage(),
}
}
fn formatter() -> anyhow::Result<()> {
let cli = Cli::parse();
let mut out: Vec<String> = Vec::new();
for num in &cli.numbers {
out.push(cli.format().format(*num, cli.prefix));
}
for o in out {
println!("{o}")
}
Ok(())
}
fn help() {
let help: String = format!(
r##"numf {}
-h, --help print this help
-p, --prefix print a prefix before the formatted number
-b, --binary format to binary
-o, --octal format to octal
-x, --hex format to hex (default)
Author: Christoph J. Scherr 2024
"##,
env!("CARGO_PKG_VERSION")
);
println!("{help}");
exit(1);
}
fn usage() {
println!("Usage: numf -hpbox NUMBER\n");
exit(1);
}