1use base64::{Engine as _, engine::general_purpose::STANDARD};
2
3pub fn encode_to_base64(input: &str) -> String {
4 STANDARD.encode(input)
5}
6
7pub fn decode_from_base64(input: &str) -> Result<Vec<u8>, base64::DecodeError> {
8 STANDARD.decode(input)
9}
10
11pub fn process_args(args: &[String]) -> String {
12 if is_arg_len_invalid(args) {
13 println!("Invalid number of arguments. Ex: b64 e hello");
14 return String::new();
15 }
16
17 let process = extract_process(args);
18 let input = extract_input(args);
19
20 let result = process_input(process, input);
21
22 println!("{}", result);
23 result
24}
25
26fn is_arg_len_invalid(args: &[String]) -> bool {
27 args.len() > 3 || args.len() < 2
28}
29
30fn extract_process(args: &[String]) -> &str {
31 args.get(1)
32 .expect("Missing process please enter encode or decode, or e or d. Ex: b64 e hello")
33 .trim()
34}
35
36fn extract_input(args: &[String]) -> &str {
37 args.get(2)
38 .expect("Missing input please enter a string to encode or decode")
39 .trim()
40}
41
42fn process_input(process: &str, input: &str) -> String {
43 if process == "decode" || process == "d" {
44 return match decode_from_base64(input) {
45 Ok(bytes) => String::from_utf8_lossy(&bytes).to_string(),
46 Err(err) => {
47 println!("Error: {}", err);
48 panic!("Invalid base64 input");
49 }
50 };
51 } else if process == "encode" || process == "e" {
52 return encode_to_base64(input);
53 }
54 eprintln!("Invalid process");
55 String::new()
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_encode() {
64 let input = "hello";
65 let output = encode_to_base64(input);
66 assert_eq!(output, "aGVsbG8=");
67 }
68
69 #[test]
70 fn test_decode() {
71 let input = "aGVsbG8=";
72 let output = decode_from_base64(input).unwrap();
73 assert_eq!(String::from_utf8_lossy(&output), "hello");
74 }
75
76 #[test]
77 fn test_decode_error() {
78 let input = "aGVsbG8";
79 let output = decode_from_base64(input);
80 assert!(output.is_err());
81 }
82 #[test]
83 fn test_is_arg_len_invalid() {
84 let args = vec![
85 "hello".to_string(),
86 "yo".to_string(),
87 "b".to_string(),
88 "s".to_string(),
89 ];
90 assert!(is_arg_len_invalid(&args));
91 }
92
93 #[test]
94 fn test_extract_process() {
95 let args = vec!["b64".to_string(), "encode".to_string(), "hello".to_string()];
96 let output = extract_process(&args);
97 assert_eq!(output, "encode");
98 }
99
100 #[test]
101 #[should_panic(
102 expected = "Missing process please enter encode or decode, or e or d. Ex: b64 e hello"
103 )]
104 fn test_extract_process_error() {
105 let args = vec!["hello".to_string()];
106 let output = extract_process(&args);
107 assert_eq!(output, "invalid");
108 }
109
110 #[test]
111 fn test_extract_input() {
112 let args = vec!["b64".to_string(), "encode".to_string(), "hello".to_string()];
113 let output = extract_input(&args);
114 assert_eq!(output, "hello");
115 }
116
117 #[test]
118 #[should_panic(expected = "Missing input please enter a string to encode or decode")]
119 fn test_extract_input_error() {
120 let args = vec!["b64".to_string(), "encode".to_string()];
121 extract_input(&args);
122 }
123}