Skip to content

Commit 1eb29b2

Browse files
authored
refactor(builtins): migrate base64, date, cut to ArgParser (#897)
Replace manual while i < ctx.args.len() loops with ArgParser in base64, date, and cut builtins. First batch of the incremental migration. Ref #880
1 parent 45c0d75 commit 1eb29b2

File tree

3 files changed

+76
-81
lines changed

3 files changed

+76
-81
lines changed

crates/bashkit/src/builtins/base64.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,38 @@ impl Builtin for Base64 {
2323
let mut wrap = 76usize;
2424
let mut file: Option<String> = None;
2525

26-
let mut i = 0;
27-
while i < ctx.args.len() {
28-
match ctx.args[i].as_str() {
29-
"-d" | "--decode" => decode = true,
30-
"-w" => {
31-
i += 1;
32-
if i >= ctx.args.len() {
26+
let mut p = super::arg_parser::ArgParser::new(ctx.args);
27+
while !p.is_done() {
28+
if p.flag_any(&["-d", "--decode"]) {
29+
decode = true;
30+
} else if let Some(val) = p.current().and_then(|s| s.strip_prefix("--wrap=")) {
31+
wrap = val.parse().unwrap_or(76);
32+
p.advance();
33+
} else {
34+
match p.flag_value("-w", "base64") {
35+
Ok(Some(val)) => wrap = val.parse().unwrap_or(76),
36+
Err(_) => {
3337
return Ok(ExecResult::err(
34-
"base64: option requires an argument -- 'w'\n".to_string(),
38+
"base64: option requires an argument -- 'w'\n",
3539
1,
3640
));
3741
}
38-
wrap = ctx.args[i].parse().unwrap_or(76);
39-
}
40-
s if s.starts_with("--wrap=") => {
41-
wrap = s[7..].parse().unwrap_or(76);
42-
}
43-
"-i" | "--ignore-garbage" => { /* silently accept */ }
44-
s if s.starts_with('-') && s != "-" => {
45-
return Ok(ExecResult::err(
46-
format!("base64: invalid option -- '{}'\n", &s[1..]),
47-
1,
48-
));
49-
}
50-
_ => {
51-
file = Some(ctx.args[i].clone());
42+
Ok(None) => {
43+
if p.flag_any(&["-i", "--ignore-garbage"]) {
44+
// silently accept
45+
} else if let Some(flag) =
46+
p.current().filter(|s| s.starts_with('-') && s.len() > 1)
47+
{
48+
return Ok(ExecResult::err(
49+
format!("base64: invalid option -- '{}'\n", &flag[1..]),
50+
1,
51+
));
52+
} else if let Some(arg) = p.positional() {
53+
file = Some(arg.to_string());
54+
}
55+
}
5256
}
5357
}
54-
i += 1;
5558
}
5659

5760
// Get input: from file, stdin, or empty

crates/bashkit/src/builtins/cuttr.rs

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,54 +41,41 @@ impl Builtin for Cut {
4141
let mut files = Vec::new();
4242

4343
// Parse arguments
44-
let mut i = 0;
45-
while i < ctx.args.len() {
46-
let arg = &ctx.args[i];
47-
if arg == "-d" {
48-
i += 1;
49-
if i < ctx.args.len() {
50-
delimiter = ctx.args[i].chars().next().unwrap_or('\t');
51-
}
52-
} else if let Some(d) = arg.strip_prefix("-d") {
53-
delimiter = d.chars().next().unwrap_or('\t');
54-
} else if arg == "-f" {
55-
i += 1;
56-
if i < ctx.args.len() {
57-
spec = ctx.args[i].clone();
58-
mode = CutMode::Fields;
59-
}
60-
} else if let Some(f) = arg.strip_prefix("-f") {
61-
spec = f.to_string();
44+
let mut p = super::arg_parser::ArgParser::new(ctx.args);
45+
while !p.is_done() {
46+
if let Some(val) = p.flag_value_opt("-d") {
47+
delimiter = val.chars().next().unwrap_or('\t');
48+
} else if let Some(val) = p.flag_value_opt("-f") {
49+
spec = val.to_string();
6250
mode = CutMode::Fields;
63-
} else if arg == "-c" || arg == "-b" {
64-
i += 1;
65-
if i < ctx.args.len() {
66-
spec = ctx.args[i].clone();
67-
mode = CutMode::Chars;
68-
}
69-
} else if let Some(c) = arg.strip_prefix("-c") {
70-
spec = c.to_string();
51+
} else if let Some(val) = p.flag_value_opt("-c") {
52+
spec = val.to_string();
7153
mode = CutMode::Chars;
72-
} else if let Some(b) = arg.strip_prefix("-b") {
73-
spec = b.to_string();
54+
} else if let Some(val) = p.flag_value_opt("-b") {
55+
spec = val.to_string();
7456
mode = CutMode::Chars;
75-
} else if arg == "-s" {
57+
} else if p.flag("-s") {
7658
only_delimited = true;
77-
} else if arg == "-z" {
59+
} else if p.flag("-z") {
7860
zero_terminated = true;
79-
} else if arg == "--complement" {
61+
} else if p.flag("--complement") {
8062
complement = true;
81-
} else if let Some(od) = arg.strip_prefix("--output-delimiter=") {
82-
output_delimiter = Some(od.to_string());
83-
} else if arg == "--output-delimiter" {
84-
i += 1;
85-
if i < ctx.args.len() {
86-
output_delimiter = Some(ctx.args[i].clone());
63+
} else if let Some(val) = p
64+
.current()
65+
.and_then(|s| s.strip_prefix("--output-delimiter="))
66+
{
67+
output_delimiter = Some(val.to_string());
68+
p.advance();
69+
} else if p.flag("--output-delimiter") {
70+
if let Some(val) = p.positional() {
71+
output_delimiter = Some(val.to_string());
8772
}
88-
} else if !arg.starts_with('-') {
89-
files.push(arg.clone());
73+
} else if let Some(arg) = p.current().filter(|s| !s.starts_with('-')) {
74+
files.push(arg.to_string());
75+
p.advance();
76+
} else {
77+
p.advance();
9078
}
91-
i += 1;
9279
}
9380

9481
if spec.is_empty() {

crates/bashkit/src/builtins/date.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -330,30 +330,35 @@ impl Builtin for Date {
330330
let mut rfc2822 = false;
331331
let mut iso8601: Option<String> = None;
332332

333-
let mut i = 0;
334-
while i < ctx.args.len() {
335-
let arg = &ctx.args[i];
336-
if arg == "-u" || arg == "--utc" {
333+
let mut p = super::arg_parser::ArgParser::new(ctx.args);
334+
while !p.is_done() {
335+
if p.flag_any(&["-u", "--utc"]) {
337336
utc = true;
338-
} else if arg == "-d" || arg == "--date" {
339-
i += 1;
340-
if i < ctx.args.len() {
341-
date_str = Some(ctx.args[i].clone());
342-
}
343-
} else if let Some(val) = arg.strip_prefix("--date=") {
337+
} else if let Some(val) = p.current().and_then(|s| s.strip_prefix("--date=")) {
344338
date_str = Some(strip_surrounding_quotes(val).to_string());
345-
} else if arg == "-R" || arg == "--rfc-2822" || arg == "--rfc-email" {
339+
p.advance();
340+
} else if let Some(val) = p.flag_value_opt("-d") {
341+
date_str = Some(val.to_string());
342+
} else if p.flag("--date") {
343+
if let Some(val) = p.positional() {
344+
date_str = Some(val.to_string());
345+
}
346+
} else if p.flag_any(&["-R", "--rfc-2822", "--rfc-email"]) {
346347
rfc2822 = true;
347-
} else if arg == "-I" || arg == "--iso-8601" {
348-
iso8601 = Some("date".to_string());
349-
} else if let Some(val) = arg.strip_prefix("-I") {
348+
} else if let Some(val) = p.current().and_then(|s| s.strip_prefix("--iso-8601=")) {
350349
iso8601 = Some(val.to_string());
351-
} else if let Some(val) = arg.strip_prefix("--iso-8601=") {
350+
p.advance();
351+
} else if p.flag_any(&["-I", "--iso-8601"]) {
352+
iso8601 = Some("date".to_string());
353+
} else if let Some(val) = p.current().and_then(|s| s.strip_prefix("-I")) {
352354
iso8601 = Some(val.to_string());
353-
} else if arg.starts_with('+') {
354-
format_arg = Some(arg.clone());
355+
p.advance();
356+
} else if let Some(arg) = p.current().filter(|s| s.starts_with('+')) {
357+
format_arg = Some(arg.to_string());
358+
p.advance();
359+
} else {
360+
p.advance();
355361
}
356-
i += 1;
357362
}
358363

359364
// Get the datetime to format

0 commit comments

Comments
 (0)