Skip to content

Commit ef3a0e7

Browse files
refactor: extract CLI arg parsing into cli_args.zig
1 parent 792daca commit ef3a0e7

File tree

2 files changed

+110
-115
lines changed

2 files changed

+110
-115
lines changed

src/cli_args.zig

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
const std = @import("std");
2+
3+
const opts = @import("opts.zig");
4+
5+
pub const CliConfig = struct {
6+
opt: opts.FilesOptions,
7+
path: []const u8,
8+
};
9+
10+
pub inline fn parseCliConfig(allocator: std.mem.Allocator, res: anytype) !CliConfig {
11+
var opt = opts.FilesOptions{ .recursion_level = 0 };
12+
var path: []const u8 = ".";
13+
14+
if (res.args.long != 0) {
15+
opt.show_detail = true;
16+
if (res.args.git != 0) {
17+
opt.show_git = true;
18+
}
19+
}
20+
21+
if (res.args.a != 0) {
22+
opt.show_hidden = true;
23+
}
24+
25+
if (res.args.sort) |sort| {
26+
opt.sort_type = sort;
27+
}
28+
29+
if (res.args.pure != 0) {
30+
opt.pure = true;
31+
}
32+
33+
if (res.args.report != 0) {
34+
opt.report = true;
35+
}
36+
37+
if (res.args.dir != 0) {
38+
opt.only_dir = true;
39+
}
40+
41+
if (res.args.no_dir != 0) {
42+
opt.only_file = true;
43+
}
44+
45+
if (opt.only_dir and opt.only_file) {
46+
opt.only_dir = false;
47+
opt.only_file = false;
48+
}
49+
50+
if (res.args.recursive != 0) {
51+
opt.recursive = true;
52+
opt.show_detail = false;
53+
opt.show_git = false;
54+
}
55+
56+
if (res.args.level) |level| {
57+
opt.recursive = true;
58+
opt.recursion_level = level;
59+
opt.show_detail = false;
60+
opt.show_git = false;
61+
}
62+
63+
opt.exts = try parseCsvArgs(allocator, res.args.ext);
64+
opt.matches = try parseCsvArgs(allocator, res.args.match);
65+
66+
if (res.positionals[0].len > 0) {
67+
path = res.positionals[0][0];
68+
}
69+
opt.path = path;
70+
71+
return .{
72+
.opt = opt,
73+
.path = path,
74+
};
75+
}
76+
77+
inline fn parseCsvArgs(allocator: std.mem.Allocator, values: []const []const u8) !?[]const []const u8 {
78+
if (values.len == 0) {
79+
return null;
80+
}
81+
82+
var items = try std.ArrayList([]const u8).initCapacity(allocator, values.len);
83+
errdefer items.deinit(allocator);
84+
85+
for (values) |value| {
86+
var token_it = std.mem.splitScalar(u8, value, ',');
87+
while (token_it.next()) |token| {
88+
const trimmed = std.mem.trim(u8, token, " \t\r\n");
89+
if (trimmed.len == 0) continue;
90+
try items.append(allocator, trimmed);
91+
}
92+
}
93+
94+
if (items.items.len == 0) {
95+
items.deinit(allocator);
96+
return null;
97+
}
98+
99+
return items.items;
100+
}

src/main.zig

Lines changed: 10 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const std = @import("std");
22

33
const clap = @import("clap");
4+
const cli_args = @import("cli_args.zig");
45
const fs = @import("files.zig");
56
const opts = @import("opts.zig");
67

@@ -57,128 +58,22 @@ pub fn main(init: std.process.Init.Minimal) !void {
5758
},
5859
);
5960

60-
var show_hidden: bool = false;
61-
var show_detail: bool = false;
62-
var pure: bool = false;
63-
var report: bool = false;
64-
var sort_type: opts.SortType = .name;
65-
var only_dir: bool = false;
66-
var only_file: bool = false;
67-
var recursive: bool = false;
68-
var recursion_level: i8 = 0; // 0 means infinite
69-
var git: bool = false;
70-
var exts: ?[]const []const u8 = null;
71-
var matches: ?[]const []const u8 = null;
72-
73-
var ext_list = try std.ArrayList([]const u8).initCapacity(allocator, 0);
74-
var match_list = try std.ArrayList([]const u8).initCapacity(allocator, 0);
75-
76-
var path: []const u8 = ".";
77-
78-
// process parsed args
7961
if (res.args.help != 0) {
8062
// show hellp msg
8163
std.debug.print("{s}\n", .{params_desc});
8264
return;
8365
}
84-
if (res.args.long != 0) {
85-
// set long listing mode
86-
show_detail = true;
87-
if (res.args.git != 0) {
88-
git = true;
89-
}
90-
}
91-
if (res.args.a != 0) {
92-
// show hidden files
93-
show_hidden = true;
94-
}
95-
// set sort type
96-
if (res.args.sort) |sort| {
97-
sort_type = sort;
98-
}
99-
// set pure mode
100-
if (res.args.pure != 0) {
101-
pure = true;
102-
}
103-
if (res.args.report != 0) {
104-
report = true;
105-
}
106-
// only show directories or files
107-
if (res.args.dir != 0) {
108-
only_dir = true;
109-
}
110-
if (res.args.no_dir != 0) {
111-
only_file = true;
112-
}
113-
if (only_dir and only_file) {
114-
// if both -d and -D are set, neither is effective
115-
only_dir = false;
116-
only_file = false;
117-
}
118-
if (res.args.recursive != 0) {
119-
// set recursive mode
120-
recursive = true;
121-
// no necessity to show detail in recursive mode
122-
show_detail = false;
123-
// git status is not shown in recursive mode
124-
git = false;
125-
}
126-
if (res.args.level) |level| {
127-
// set recursive mode and recursion level
128-
recursive = true;
129-
recursion_level = level;
130-
show_detail = false;
131-
git = false;
132-
}
133-
if (res.args.ext.len > 0) {
134-
const ext_args = res.args.ext;
135-
for (ext_args) |arg| {
136-
var token_it = std.mem.splitScalar(u8, arg, ',');
137-
while (token_it.next()) |token| {
138-
const trimmed = std.mem.trim(u8, token, " \t\r\n");
139-
if (trimmed.len == 0) {
140-
continue;
141-
}
142-
143-
try ext_list.append(allocator, trimmed);
144-
}
145-
}
146-
if (ext_list.items.len > 0) {
147-
exts = ext_list.items;
148-
}
149-
}
150-
if (res.args.match.len > 0) {
151-
const match_args = res.args.match;
152-
for (match_args) |arg| {
153-
var token_it = std.mem.splitScalar(u8, arg, ',');
154-
while (token_it.next()) |token| {
155-
const trimmed = std.mem.trim(u8, token, " \t\r\n");
156-
if (trimmed.len == 0) {
157-
continue;
158-
}
159-
160-
try match_list.append(allocator, trimmed);
161-
}
162-
}
163-
if (match_list.items.len > 0) {
164-
matches = match_list.items;
165-
}
166-
}
167-
168-
// get file path from args
169-
if (res.positionals[0].len > 0) {
170-
path = res.positionals[0][0];
171-
}
66+
const cli = try cli_args.parseCliConfig(allocator, res);
17267

17368
const cwd = std.Io.Dir.cwd();
174-
const dir = try cwd.openDir(io, path, .{ .iterate = true });
69+
const dir = try cwd.openDir(io, cli.path, .{ .iterate = true });
17570
defer dir.close(io);
17671

17772
var files = try fs.Files.init(
17873
allocator,
17974
io,
18075
dir,
181-
.{ .show_detail = show_detail, .show_hidden = show_hidden, .sort_type = sort_type, .recursive = recursive, .pure = pure, .only_dir = only_dir, .only_file = only_file, .recursion_level = recursion_level, .report = report, .show_git = git, .path = path, .exts = exts, .matches = matches },
76+
cli.opt,
18277
);
18378
defer files.deinit();
18479

@@ -202,30 +97,30 @@ pub fn main(init: std.process.Init.Minimal) !void {
20297
// get term
20398
const term = try files.getTerminal(&stdout_writer.interface, stdout_file);
20499

205-
if (show_detail) {
100+
if (cli.opt.show_detail) {
206101
// zl -l
207-
switch (pure) {
102+
switch (cli.opt.pure) {
208103
// pure mode
209104
true => try files.listDetail(term, .{ .pure = true }),
210105
false => try files.listDetail(term, .{ .pure = false }),
211106
}
212-
} else if (recursive) {
107+
} else if (cli.opt.recursive) {
213108
// zl -r
214-
switch (pure) {
109+
switch (cli.opt.pure) {
215110
// pure mode
216111
true => try files.listRecursive(term, "", true, dir, .{ .pure = true }),
217112
false => try files.listRecursive(term, "", true, dir, .{ .pure = false }),
218113
}
219114
} else {
220115
// just ls command
221-
switch (pure) {
116+
switch (cli.opt.pure) {
222117
// pure mode
223118
true => try files.list(term, stdout_file.handle, .{ .pure = true }),
224119
false => try files.list(term, stdout_file.handle, .{ .pure = false }),
225120
}
226121
}
227122

228-
if (report) {
123+
if (cli.opt.report) {
229124
try files.printReport(&stdout_writer.interface);
230125
}
231126

0 commit comments

Comments
 (0)