Added color to base64 file header; Ran clippy lints and fixed all but
missing docs;
This commit is contained in:
parent
36835dd322
commit
6b6cc314e8
@ -2,9 +2,9 @@ use super::Cmd;
|
|||||||
use clap::{value_parser, Arg, ArgAction, Command};
|
use clap::{value_parser, Arg, ArgAction, Command};
|
||||||
use data_encoding::BASE32;
|
use data_encoding::BASE32;
|
||||||
use std::{
|
use std::{
|
||||||
|
error::Error,
|
||||||
fs,
|
fs,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
process,
|
|
||||||
};
|
};
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
|
|
||||||
@ -70,11 +70,11 @@ impl Cmd for Base32 {
|
|||||||
return Err(io::Error::new(io::ErrorKind::Other, "No input").into());
|
return Err(io::Error::new(io::ErrorKind::Other, "No input").into());
|
||||||
};
|
};
|
||||||
let files: Vec<_> = match matches.get_many::<String>("INPUT") {
|
let files: Vec<_> = match matches.get_many::<String>("INPUT") {
|
||||||
Some(c) => c.map(|x| x.clone()).collect(),
|
Some(c) => c.cloned().collect(),
|
||||||
None => vec![String::from("-")],
|
None => vec![String::from("-")],
|
||||||
};
|
};
|
||||||
let len = files.len();
|
let len = files.len();
|
||||||
let color = match matches.get_one::<String>("color").map(|x| x.as_str()) {
|
let color = match matches.get_one::<String>("color").map(String::as_str) {
|
||||||
Some("always") => ColorChoice::Always,
|
Some("always") => ColorChoice::Always,
|
||||||
Some("ansi") => ColorChoice::AlwaysAnsi,
|
Some("ansi") => ColorChoice::AlwaysAnsi,
|
||||||
Some("auto") => {
|
Some("auto") => {
|
||||||
@ -98,9 +98,9 @@ impl Cmd for Base32 {
|
|||||||
} else if index > 0 {
|
} else if index > 0 {
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
let contents = get_contents(&file);
|
let contents = get_contents(&file)?;
|
||||||
if matches.get_flag("DECODE") {
|
if matches.get_flag("DECODE") {
|
||||||
decode_base32(contents, matches.get_flag("IGNORE"));
|
decode_base32(contents, matches.get_flag("IGNORE"))?;
|
||||||
} else {
|
} else {
|
||||||
encode_base32(
|
encode_base32(
|
||||||
&contents,
|
&contents,
|
||||||
@ -121,60 +121,34 @@ impl Cmd for Base32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_base32(mut contents: String, ignore: bool) {
|
fn decode_base32(mut contents: String, ignore: bool) -> Result<(), Box<dyn Error>> {
|
||||||
if ignore {
|
if ignore {
|
||||||
contents.retain(|c| !c.is_whitespace());
|
contents.retain(|c| !c.is_whitespace());
|
||||||
} else {
|
} else {
|
||||||
contents = contents.replace('\n', "");
|
contents = contents.replace('\n', "");
|
||||||
}
|
}
|
||||||
let decoded = match BASE32.decode(contents.as_bytes()) {
|
let decoded = BASE32.decode(contents.as_bytes())?;
|
||||||
Ok(c) => c,
|
let output = String::from_utf8(decoded)?;
|
||||||
Err(e) => {
|
|
||||||
eprintln!("base32: {e}");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let output = match String::from_utf8(decoded) {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("base32: {e}");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
println!("{}", output.trim_end());
|
println!("{}", output.trim_end());
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_base32(contents: &str, wrap: usize) {
|
fn encode_base32(contents: &str, wrap: usize) {
|
||||||
let encoded = BASE32
|
BASE32
|
||||||
.encode(contents.as_bytes())
|
.encode(contents.as_bytes())
|
||||||
.chars()
|
.chars()
|
||||||
.collect::<Vec<char>>()
|
.collect::<Vec<char>>()
|
||||||
.chunks(wrap)
|
.chunks(wrap)
|
||||||
.map(|c| c.iter().collect::<String>())
|
.map(|c| c.iter().collect::<String>())
|
||||||
.collect::<Vec<String>>();
|
.for_each(|line| println!("{line}"));
|
||||||
for line in &encoded {
|
|
||||||
println!("{line}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents(file: &str) -> String {
|
fn get_contents(file: &str) -> Result<String, Box<dyn Error>> {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
if file == "-" {
|
if file == "-" {
|
||||||
match io::stdin().read_to_string(&mut contents) {
|
io::stdin().read_to_string(&mut contents)?;
|
||||||
Ok(_) => true,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("base32: {e}");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
contents = match fs::read_to_string(file) {
|
contents = fs::read_to_string(file)?;
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("base32: {e}");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
contents
|
Ok(contents)
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,9 @@ use clap::{value_parser, Arg, ArgAction, ArgMatches, Command};
|
|||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
fs,
|
fs,
|
||||||
io::{self, Read},
|
io::{self, Read, Write},
|
||||||
};
|
};
|
||||||
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Base64 {
|
pub struct Base64 {
|
||||||
@ -47,6 +48,10 @@ impl Cmd for Base64 {
|
|||||||
.long("wrap")
|
.long("wrap")
|
||||||
.default_value("76")
|
.default_value("76")
|
||||||
.value_parser(value_parser!(usize)),
|
.value_parser(value_parser!(usize)),
|
||||||
|
Arg::new("color")
|
||||||
|
.short('c')
|
||||||
|
.long("color")
|
||||||
|
.value_parser(["always", "ansi", "auto", "never"]),
|
||||||
Arg::new("VERBOSE")
|
Arg::new("VERBOSE")
|
||||||
.help("Display a header naming each file")
|
.help("Display a header naming each file")
|
||||||
.short('v')
|
.short('v')
|
||||||
@ -65,16 +70,31 @@ impl Cmd for Base64 {
|
|||||||
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "No input")));
|
return Err(Box::new(io::Error::new(io::ErrorKind::Other, "No input")));
|
||||||
};
|
};
|
||||||
let files: Vec<_> = match matches.get_many::<String>("INPUT") {
|
let files: Vec<_> = match matches.get_many::<String>("INPUT") {
|
||||||
Some(c) => c.map(|x| x.clone()).collect(),
|
Some(c) => c.cloned().collect(),
|
||||||
None => vec![String::from("-")],
|
None => vec![String::from("-")],
|
||||||
};
|
};
|
||||||
let len = files.len();
|
let len = files.len();
|
||||||
|
let color = match matches.get_one::<String>("color").map(String::as_str) {
|
||||||
|
Some("always") => ColorChoice::Always,
|
||||||
|
Some("ansi") => ColorChoice::AlwaysAnsi,
|
||||||
|
Some("auto") => {
|
||||||
|
if atty::is(atty::Stream::Stdout) {
|
||||||
|
ColorChoice::Auto
|
||||||
|
} else {
|
||||||
|
ColorChoice::Never
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => ColorChoice::Never,
|
||||||
|
};
|
||||||
for (index, file) in files.into_iter().enumerate() {
|
for (index, file) in files.into_iter().enumerate() {
|
||||||
if { len > 1 || matches.get_flag("VERBOSE") } && !matches.get_flag("QUIET") {
|
if { len > 1 || matches.get_flag("VERBOSE") } && !matches.get_flag("QUIET") {
|
||||||
|
let mut stdout = StandardStream::stdout(color);
|
||||||
|
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
|
||||||
match index {
|
match index {
|
||||||
0 => println!("===> {file} <==="),
|
0 => writeln!(stdout, "===> {file} <==="),
|
||||||
_ => println!("\n===> {file} <==="),
|
_ => writeln!(stdout, "\n===> {file} <==="),
|
||||||
};
|
}?;
|
||||||
|
stdout.reset()?;
|
||||||
} else if index > 0 {
|
} else if index > 0 {
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
@ -105,22 +125,19 @@ fn decode_base64(mut contents: String, ignore: bool) -> Result<(), Box<dyn Error
|
|||||||
} else {
|
} else {
|
||||||
contents = contents.replace('\n', "");
|
contents = contents.replace('\n', "");
|
||||||
}
|
}
|
||||||
let decoded = decode(&contents)?.to_vec();
|
let decoded = decode(&contents)?.clone();
|
||||||
let output = String::from_utf8(decoded)?;
|
let output = String::from_utf8(decoded)?;
|
||||||
println!("{}", output.trim_end());
|
println!("{}", output.trim_end());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_base64(contents: &str, wrap: usize) {
|
fn encode_base64(contents: &str, wrap: usize) {
|
||||||
let encoded = encode(contents.as_bytes())
|
encode(contents.as_bytes())
|
||||||
.chars()
|
.chars()
|
||||||
.collect::<Vec<char>>()
|
.collect::<Vec<char>>()
|
||||||
.chunks(wrap)
|
.chunks(wrap)
|
||||||
.map(|c| c.iter().collect::<String>())
|
.map(|c| c.iter().collect::<String>())
|
||||||
.collect::<Vec<String>>();
|
.for_each(|line| println!("{line}"));
|
||||||
for line in &encoded {
|
|
||||||
println!("{line}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_contents(file: &str) -> Result<String, Box<dyn Error>> {
|
fn get_contents(file: &str) -> Result<String, Box<dyn Error>> {
|
||||||
|
@ -6,7 +6,6 @@ use std::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
fs,
|
fs,
|
||||||
io::{self, stdin, Read, Write},
|
io::{self, stdin, Read, Write},
|
||||||
process,
|
|
||||||
};
|
};
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
|
|
||||||
@ -108,7 +107,7 @@ impl Cmd for Head {
|
|||||||
};
|
};
|
||||||
let header =
|
let header =
|
||||||
!matches.get_flag("QUIET") && { files.len() > 1 || matches.get_flag("HEADER") };
|
!matches.get_flag("QUIET") && { files.len() > 1 || matches.get_flag("HEADER") };
|
||||||
let color = match matches.get_one::<String>("color").map(|x| x.as_str()) {
|
let color = match matches.get_one::<String>("color").map(String::as_str) {
|
||||||
Some("always") => ColorChoice::Always,
|
Some("always") => ColorChoice::Always,
|
||||||
Some("ansi") => ColorChoice::AlwaysAnsi,
|
Some("ansi") => ColorChoice::AlwaysAnsi,
|
||||||
Some("auto") => {
|
Some("auto") => {
|
||||||
@ -143,22 +142,9 @@ fn head(
|
|||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
if file == "-" {
|
if file == "-" {
|
||||||
match stdin().read_to_string(&mut contents) {
|
stdin().read_to_string(&mut contents)?;
|
||||||
Ok(_) => true,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("head: {e}");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
let buf = fs::read_to_string(file);
|
contents = fs::read_to_string(file)?;
|
||||||
contents = match buf {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("head: {e}");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if header {
|
if header {
|
||||||
let mut stdout = StandardStream::stdout(color);
|
let mut stdout = StandardStream::stdout(color);
|
||||||
@ -167,7 +153,7 @@ fn head(
|
|||||||
stdout.reset()?;
|
stdout.reset()?;
|
||||||
}
|
}
|
||||||
if bytes {
|
if bytes {
|
||||||
for (index, char) in contents.chars().into_iter().enumerate() {
|
for (index, char) in contents.chars().enumerate() {
|
||||||
if index < count {
|
if index < count {
|
||||||
print!("{char}");
|
print!("{char}");
|
||||||
} else {
|
} else {
|
||||||
@ -177,7 +163,7 @@ fn head(
|
|||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
} else {
|
} else {
|
||||||
for (index, line) in contents.lines().into_iter().enumerate() {
|
for (index, line) in contents.lines().enumerate() {
|
||||||
if index < count {
|
if index < count {
|
||||||
println!("{line}");
|
println!("{line}");
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,6 +46,7 @@ pub use {
|
|||||||
echo::{Echo, ECHO},
|
echo::{Echo, ECHO},
|
||||||
factor::{Factor, FACTOR},
|
factor::{Factor, FACTOR},
|
||||||
head::{Head, HEAD},
|
head::{Head, HEAD},
|
||||||
|
mountpoint::{Mountpoint, MOUNTPOINT},
|
||||||
nologin::{Nologin, NOLOGIN},
|
nologin::{Nologin, NOLOGIN},
|
||||||
r#false::{False, FALSE},
|
r#false::{False, FALSE},
|
||||||
r#true::{True, TRUE},
|
r#true::{True, TRUE},
|
||||||
|
@ -31,6 +31,7 @@ impl Cmd for Mountpoint {
|
|||||||
.help("Show the major/minor numbers of the given blockdevice on standard output.")
|
.help("Show the major/minor numbers of the given blockdevice on standard output.")
|
||||||
.short('x')
|
.short('x')
|
||||||
.long("devno")
|
.long("devno")
|
||||||
|
.conflicts_with("fs-devno")
|
||||||
.action(ArgAction::SetTrue),
|
.action(ArgAction::SetTrue),
|
||||||
Arg::new("quiet")
|
Arg::new("quiet")
|
||||||
.help("Be quiet - don’t print anything.")
|
.help("Be quiet - don’t print anything.")
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::{
|
use super::{
|
||||||
Cmd, BASE_32, BASE_64, BOOTSTRAP, DIRNAME, ECHO, FACTOR, FALSE, HEAD, HOSTNAME, NOLOGIN, SLEEP,
|
Cmd, BASE_32, BASE_64, BOOTSTRAP, DIRNAME, ECHO, FACTOR, FALSE, HEAD, HOSTNAME, MOUNTPOINT,
|
||||||
TRUE,
|
NOLOGIN, SLEEP, TRUE,
|
||||||
};
|
};
|
||||||
use clap::Command;
|
use clap::Command;
|
||||||
use std::{
|
use std::{
|
||||||
@ -41,6 +41,7 @@ impl Cmd for Shitbox {
|
|||||||
FALSE.cli(),
|
FALSE.cli(),
|
||||||
FACTOR.cli(),
|
FACTOR.cli(),
|
||||||
HEAD.cli(),
|
HEAD.cli(),
|
||||||
|
MOUNTPOINT.cli(),
|
||||||
NOLOGIN.cli(),
|
NOLOGIN.cli(),
|
||||||
HOSTNAME.cli(),
|
HOSTNAME.cli(),
|
||||||
SLEEP.cli(),
|
SLEEP.cli(),
|
||||||
@ -61,6 +62,7 @@ impl Cmd for Shitbox {
|
|||||||
Some(("factor", matches)) => FACTOR.run(Some(matches))?,
|
Some(("factor", matches)) => FACTOR.run(Some(matches))?,
|
||||||
Some(("false", _matches)) => FALSE.run(None)?,
|
Some(("false", _matches)) => FALSE.run(None)?,
|
||||||
Some(("head", matches)) => HEAD.run(Some(matches))?,
|
Some(("head", matches)) => HEAD.run(Some(matches))?,
|
||||||
|
Some(("mountpoint", matches)) => MOUNTPOINT.run(Some(matches))?,
|
||||||
Some(("nologin", _matches)) => NOLOGIN.run(None)?,
|
Some(("nologin", _matches)) => NOLOGIN.run(None)?,
|
||||||
Some(("hostname", matches)) => HOSTNAME.run(Some(matches))?,
|
Some(("hostname", matches)) => HOSTNAME.run(Some(matches))?,
|
||||||
Some(("sleep", matches)) => SLEEP.run(Some(matches))?,
|
Some(("sleep", matches)) => SLEEP.run(Some(matches))?,
|
||||||
|
19
src/lib.rs
19
src/lib.rs
@ -4,7 +4,7 @@ use std::{env, error::Error, path::PathBuf, string::ToString};
|
|||||||
pub mod cmd;
|
pub mod cmd;
|
||||||
pub use cmd::{
|
pub use cmd::{
|
||||||
Cmd, Commands, BASE_32, BASE_64, BOOTSTRAP, DIRNAME, ECHO, FACTOR, FALSE, HEAD, HOSTNAME,
|
Cmd, Commands, BASE_32, BASE_64, BOOTSTRAP, DIRNAME, ECHO, FACTOR, FALSE, HEAD, HOSTNAME,
|
||||||
NOLOGIN, SHITBOX, SLEEP, TRUE,
|
MOUNTPOINT, NOLOGIN, SHITBOX, SLEEP, TRUE,
|
||||||
};
|
};
|
||||||
pub mod math;
|
pub mod math;
|
||||||
|
|
||||||
@ -41,8 +41,20 @@ pub fn run() -> Result<(), Box<dyn Error>> {
|
|||||||
cmd::COMMANDS
|
cmd::COMMANDS
|
||||||
.set(Commands {
|
.set(Commands {
|
||||||
items: vec![
|
items: vec![
|
||||||
&BASE_32, &BASE_64, &BOOTSTRAP, &DIRNAME, &ECHO, &FALSE, &FACTOR, &HEAD,
|
&BASE_32,
|
||||||
&HOSTNAME, &NOLOGIN, &TRUE, &SLEEP, &SHITBOX,
|
&BASE_64,
|
||||||
|
&BOOTSTRAP,
|
||||||
|
&DIRNAME,
|
||||||
|
&ECHO,
|
||||||
|
&FALSE,
|
||||||
|
&FACTOR,
|
||||||
|
&HEAD,
|
||||||
|
&HOSTNAME,
|
||||||
|
&MOUNTPOINT,
|
||||||
|
&NOLOGIN,
|
||||||
|
&TRUE,
|
||||||
|
&SLEEP,
|
||||||
|
&SHITBOX,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
.expect("Cannot register commands");
|
.expect("Cannot register commands");
|
||||||
@ -59,6 +71,7 @@ pub fn run() -> Result<(), Box<dyn Error>> {
|
|||||||
HEAD.run(Some(&HEAD.cli().get_matches()))?;
|
HEAD.run(Some(&HEAD.cli().get_matches()))?;
|
||||||
}
|
}
|
||||||
"hostname" => HOSTNAME.run(Some(&HOSTNAME.cli().get_matches()))?,
|
"hostname" => HOSTNAME.run(Some(&HOSTNAME.cli().get_matches()))?,
|
||||||
|
"mountpoint" => MOUNTPOINT.run(Some(&MOUNTPOINT.cli().get_matches()))?,
|
||||||
"nologin" => NOLOGIN.run(None)?,
|
"nologin" => NOLOGIN.run(None)?,
|
||||||
"true" => TRUE.run(None)?,
|
"true" => TRUE.run(None)?,
|
||||||
"shitbox" => {
|
"shitbox" => {
|
||||||
|
Loading…
Reference in New Issue
Block a user