1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use base64_stream::{FromBase64Reader, ToBase64Reader};
use clap::Parser;
use rustutils_runnable::Runnable;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
#[derive(Parser, Clone, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct Base64 {
#[clap(long, short, default_value = "76")]
wrap: u16,
#[clap(long, short, conflicts_with = "wrap")]
no_wrap: bool,
#[clap(long, short)]
decode: bool,
#[clap(long, short, requires = "decode")]
ignore_garbage: bool,
file: Option<PathBuf>,
}
impl Base64 {
pub fn wrapping(&self) -> Option<u16> {
if self.no_wrap || self.wrap == 0 {
None
} else {
Some(self.wrap)
}
}
pub fn run(&self) -> Result<(), Box<dyn Error>> {
let input: Box<dyn Read> = match &self.file {
Some(file) if file.as_os_str() != "-" => Box::new(File::open(file)?),
_ => Box::new(std::io::stdin()),
};
match self.decode {
false => self.encode(input)?,
true => self.decode(input)?,
}
Ok(())
}
pub fn encode(&self, stream: Box<dyn Read>) -> Result<(), Box<dyn Error>> {
let mut encoder = ToBase64Reader::new(stream);
let mut stdout = std::io::stdout();
std::io::copy(&mut encoder, &mut stdout)?;
Ok(())
}
pub fn decode(&self, stream: Box<dyn Read>) -> Result<(), Box<dyn Error>> {
let mut encoder = FromBase64Reader::new(stream);
let mut stdout = std::io::stdout();
std::io::copy(&mut encoder, &mut stdout)?;
Ok(())
}
}
impl Runnable for Base64 {
fn run(&self) -> Result<(), Box<dyn Error>> {
self.run()?;
Ok(())
}
}