-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: support base64 encode/decode cli
- Loading branch information
Showing
12 changed files
with
229 additions
and
46 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
W3BhY2thZ2VdCm5hbWUgPSAicmNsaSIKdmVyc2lvbiA9ICIwLjEuMCIKYXV0aG9ycyA9IFsiVHlyIENoZW4gPHR5ci5jaGVuQGdtYWlsLmNvbT4iXQplZGl0aW9uID0gIjIwMjEiCmxpY2Vuc2UgPSAiTUlUIgoKIyBTZWUgbW9yZSBrZXlzIGFuZCB0aGVpciBkZWZpbml0aW9ucyBhdCBodHRwczovL2RvYy5ydXN0LWxhbmcub3JnL2NhcmdvL3JlZmVyZW5jZS9tYW5pZmVzdC5odG1sCgpbZGVwZW5kZW5jaWVzXQphbnlob3cgPSAiMS4wLjgxIgpiYXNlNjQgPSAiMC4yMi4wIgpjbGFwID0geyB2ZXJzaW9uID0gIjQuNS4zIiwgZmVhdHVyZXMgPSBbImRlcml2ZSJdIH0KY3N2ID0gIjEuMy4wIgpyYW5kID0gIjAuOC41IgpzZXJkZSA9IHsgdmVyc2lvbiA9ICIxLjAuMTk3IiwgZmVhdHVyZXMgPSBbImRlcml2ZSJdIH0Kc2VyZGVfanNvbiA9ICIxLjAuMTE0IgpzZXJkZV95YW1sID0gIjAuOS4zMyIKenhjdmJuID0gIjIuMi4yIgo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use std::{fmt, str::FromStr}; | ||
|
||
use clap::Parser; | ||
|
||
use super::verify_input_file; | ||
|
||
#[derive(Debug, Parser)] | ||
pub enum Base64SubCommand { | ||
#[command(name = "encode", about = "Encode a string to base64")] | ||
Encode(Base64EncodeOpts), | ||
#[command(name = "decode", about = "Decode a base64 string")] | ||
Decode(Base64DecodeOpts), | ||
} | ||
|
||
#[derive(Debug, Parser)] | ||
pub struct Base64EncodeOpts { | ||
#[arg(short, long, value_parser = verify_input_file, default_value = "-")] | ||
pub input: String, | ||
#[arg(long, value_parser = parse_base64_format, default_value = "standard")] | ||
pub format: Base64Format, | ||
} | ||
|
||
#[derive(Debug, Parser)] | ||
pub struct Base64DecodeOpts { | ||
#[arg(short, long, value_parser = verify_input_file, default_value = "-")] | ||
pub input: String, | ||
#[arg(long, value_parser = parse_base64_format, default_value = "standard")] | ||
pub format: Base64Format, | ||
} | ||
|
||
#[derive(Debug, Clone, Copy)] | ||
pub enum Base64Format { | ||
Standard, | ||
UrlSafe, | ||
} | ||
|
||
fn parse_base64_format(format: &str) -> Result<Base64Format, anyhow::Error> { | ||
format.parse() | ||
} | ||
|
||
impl FromStr for Base64Format { | ||
type Err = anyhow::Error; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
match s { | ||
"standard" => Ok(Base64Format::Standard), | ||
"urlsafe" => Ok(Base64Format::UrlSafe), | ||
_ => Err(anyhow::anyhow!("Invalid format")), | ||
} | ||
} | ||
} | ||
|
||
impl From<Base64Format> for &'static str { | ||
fn from(format: Base64Format) -> Self { | ||
match format { | ||
Base64Format::Standard => "standard", | ||
Base64Format::UrlSafe => "urlsafe", | ||
} | ||
} | ||
} | ||
|
||
impl fmt::Display for Base64Format { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "{}", Into::<&str>::into(*self)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use clap::Parser; | ||
|
||
#[derive(Debug, Parser)] | ||
pub struct GenPassOpts { | ||
#[arg(short, long, default_value_t = 16)] | ||
pub length: u8, | ||
|
||
#[arg(long, default_value_t = true)] | ||
pub uppercase: bool, | ||
|
||
#[arg(long, default_value_t = true)] | ||
pub lowercase: bool, | ||
|
||
#[arg(long, default_value_t = true)] | ||
pub number: bool, | ||
|
||
#[arg(long, default_value_t = true)] | ||
pub symbol: bool, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
mod base64; | ||
mod csv; | ||
mod genpass; | ||
|
||
use std::path::Path; | ||
|
||
use self::{csv::CsvOpts, genpass::GenPassOpts}; | ||
use clap::Parser; | ||
|
||
pub use self::{ | ||
base64::{Base64Format, Base64SubCommand}, | ||
csv::OutputFormat, | ||
}; | ||
|
||
#[derive(Debug, Parser)] | ||
#[command(name = "rcli", version, author, about, long_about = None)] | ||
pub struct Opts { | ||
#[command(subcommand)] | ||
pub cmd: SubCommand, | ||
} | ||
|
||
#[derive(Debug, Parser)] | ||
pub enum SubCommand { | ||
#[command(name = "csv", about = "Show CSV, or convert CSV to other formats")] | ||
Csv(CsvOpts), | ||
#[command(name = "genpass", about = "Generate a random password")] | ||
GenPass(GenPassOpts), | ||
#[command(subcommand)] | ||
Base64(Base64SubCommand), | ||
} | ||
|
||
fn verify_input_file(filename: &str) -> Result<String, &'static str> { | ||
// if input is "-" or file exists | ||
if filename == "-" || Path::new(filename).exists() { | ||
Ok(filename.into()) | ||
} else { | ||
Err("File does not exist") | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_verify_input_file() { | ||
assert_eq!(verify_input_file("-"), Ok("-".into())); | ||
assert_eq!(verify_input_file("*"), Err("File does not exist")); | ||
assert_eq!(verify_input_file("Cargo.toml"), Ok("Cargo.toml".into())); | ||
assert_eq!(verify_input_file("not-exist"), Err("File does not exist")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
mod opts; | ||
mod cli; | ||
mod process; | ||
|
||
pub use opts::{Opts, SubCommand}; | ||
pub use cli::{Base64Format, Base64SubCommand, Opts, SubCommand}; | ||
pub use process::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use crate::Base64Format; | ||
use anyhow::Result; | ||
use base64::{ | ||
engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD}, | ||
Engine as _, | ||
}; | ||
use std::{fs::File, io::Read}; | ||
|
||
pub fn process_encode(input: &str, format: Base64Format) -> Result<()> { | ||
let mut reader = get_reader(input)?; | ||
let mut buf = Vec::new(); | ||
reader.read_to_end(&mut buf)?; | ||
let encoded = match format { | ||
Base64Format::Standard => STANDARD.encode(&buf), | ||
Base64Format::UrlSafe => URL_SAFE_NO_PAD.encode(&buf), | ||
}; | ||
println!("{}", encoded); | ||
Ok(()) | ||
} | ||
|
||
pub fn process_decode(input: &str, format: Base64Format) -> Result<()> { | ||
let mut reader = get_reader(input)?; | ||
let mut buf = String::new(); | ||
reader.read_to_string(&mut buf)?; | ||
// avoid accidental newlines | ||
let buf = buf.trim(); | ||
|
||
let decoded = match format { | ||
Base64Format::Standard => STANDARD.decode(buf)?, | ||
Base64Format::UrlSafe => URL_SAFE_NO_PAD.decode(buf)?, | ||
}; | ||
// TODO: decoded data might not be string (but for this example, we assume it is) | ||
let decoded = String::from_utf8(decoded)?; | ||
println!("{}", decoded); | ||
Ok(()) | ||
} | ||
|
||
fn get_reader(input: &str) -> Result<Box<dyn Read>> { | ||
let reader: Box<dyn Read> = if input == "-" { | ||
Box::new(std::io::stdin()) | ||
} else { | ||
Box::new(File::open(input)?) | ||
}; | ||
Ok(reader) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_process_encode() { | ||
let input = "Cargo.toml"; | ||
let format = Base64Format::Standard; | ||
assert!(process_encode(input, format).is_ok()); | ||
} | ||
|
||
#[test] | ||
fn test_process_decode() { | ||
let input = "fixtures/b64.txt"; | ||
let format = Base64Format::UrlSafe; | ||
process_decode(input, format).unwrap(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
mod b64; | ||
mod csv_convert; | ||
mod gen_pass; | ||
|
||
pub use b64::{process_decode, process_encode}; | ||
pub use csv_convert::process_csv; | ||
pub use gen_pass::process_genpass; |