Nathan Fisher
fb389fd309
- one match statement to return a `Box<dyn Cmd>` - one array containing all command names Only two places to register new commands (besides their module), both in crate::cmd::mod.rs. Also removes `once_cell` crate dependency. Replace `base64` crate dependency with `data_encoding::BASE64` so that both base32 and base64 commands use the same crate.
91 lines
2.0 KiB
Rust
91 lines
2.0 KiB
Rust
use crate::Cmd;
|
|
use clap::{value_parser, Arg, ArgMatches, Command};
|
|
use std::{
|
|
error::Error,
|
|
io::{self, BufRead},
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
pub struct Factor {
|
|
name: &'static str,
|
|
path: Option<crate::Path>,
|
|
}
|
|
|
|
impl Default for Factor {
|
|
fn default() -> Self {
|
|
Self {
|
|
name: "factor",
|
|
path: Some(crate::Path::UsrBin),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Cmd for Factor {
|
|
fn name(&self) -> &str {
|
|
self.name
|
|
}
|
|
|
|
fn cli(&self) -> Command {
|
|
Command::new("factor")
|
|
.about("factor numbers")
|
|
.after_help(
|
|
"Print the prime factors of each specified integer NUMBER. If none are\n\
|
|
specified on the command line, read them from standard input.",
|
|
)
|
|
.arg(
|
|
Arg::new("number")
|
|
.help("the numbers to factor")
|
|
.num_args(0..)
|
|
.value_parser(value_parser!(u64)),
|
|
)
|
|
}
|
|
|
|
fn run(&self, matches: Option<&ArgMatches>) -> Result<(), Box<dyn Error>> {
|
|
if let Some(matches) = matches {
|
|
match matches.get_many::<u64>("number") {
|
|
Some(numbers) => {
|
|
numbers.for_each(|n| print_factors(*n));
|
|
}
|
|
None => {
|
|
for line in io::stdin().lock().lines() {
|
|
for num in line?.split_whitespace() {
|
|
print_factors(num.parse()?);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn path(&self) -> Option<crate::Path> {
|
|
self.path
|
|
}
|
|
}
|
|
|
|
fn first_factor(num: u64) -> u64 {
|
|
if num % 2 == 0 {
|
|
return 2;
|
|
}
|
|
for n in (3..=num).step_by(1) {
|
|
if num % n == 0 {
|
|
return n;
|
|
}
|
|
}
|
|
num
|
|
}
|
|
|
|
fn print_factors(num: u64) {
|
|
print!("{num}:");
|
|
let mut n = num;
|
|
loop {
|
|
let f = first_factor(n);
|
|
print!(" {f}");
|
|
if f == n {
|
|
break;
|
|
}
|
|
n /= f;
|
|
}
|
|
println!();
|
|
}
|