Skip to content

Commit f94cdf1

Browse files
committed
Add Io to API where io is used.
This is a breaking API change, but I think it makes sense in the context of the Io changes. It adds an Io argument to functions that call other functions that require an io value.
1 parent 22e2b75 commit f94cdf1

File tree

4 files changed

+41
-36
lines changed

4 files changed

+41
-36
lines changed

src/App.zig

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ process_args: ?[]const [:0]u8 = null,
3232
pub fn init(allocator: Allocator, name: []const u8, description: ?[]const u8) App {
3333
return App{
3434
.allocator = allocator,
35-
.command = Command.init(allocator, name, description) catch { @panic("failed to create Command"); }
35+
.command = Command.init(allocator, name, description) catch {
36+
@panic("failed to create Command");
37+
},
3638
};
3739
}
3840

@@ -67,7 +69,9 @@ pub fn deinit(self: *App) void {
6769
/// var subcmd1 = app.createCommand("subcmd1", "First Subcommand");
6870
/// ```
6971
pub fn createCommand(self: *App, name: []const u8, description: ?[]const u8) Command {
70-
return Command.init(self.allocator, name, description) catch { @panic("failed to create Command"); };
72+
return Command.init(self.allocator, name, description) catch {
73+
@panic("failed to create Command");
74+
};
7175
}
7276

7377
/// Returns a pointer to the root `Command` of the application.
@@ -99,11 +103,11 @@ pub fn rootCommand(self: *App) *Command {
99103
///
100104
/// // Add arguments and subcommands using `root`.
101105
///
102-
/// const matches = try app.parseProcess();
106+
/// const matches = try app.parseProcess(io);
103107
/// ```
104-
pub fn parseProcess(self: *App) YazapError!ArgMatches {
108+
pub fn parseProcess(self: *App, io: std.Io) YazapError!ArgMatches {
105109
self.process_args = try std.process.argsAlloc(self.allocator);
106-
return self.parseFrom(self.process_args.?[1..]);
110+
return self.parseFrom(io, self.process_args.?[1..]);
107111
}
108112

109113
/// Parses the given arguments.
@@ -118,9 +122,9 @@ pub fn parseProcess(self: *App) YazapError!ArgMatches {
118122
///
119123
/// // Add arguments and subcommands using `root`.
120124
///
121-
/// const matches = try app.parseFrom(&.{ "arg1", "--some-option" "subcmd" });
125+
/// const matches = try app.parseFrom(io, &.{ "arg1", "--some-option" "subcmd" });
122126
/// ```
123-
pub fn parseFrom(self: *App, argv: []const [:0]const u8) YazapError!ArgMatches {
127+
pub fn parseFrom(self: *App, io: std.Io, argv: []const [:0]const u8) YazapError!ArgMatches {
124128
var parser = Parser.init(self.allocator, argv, self.rootCommand());
125129
var result = parser.parse() catch |err| {
126130
// Don't clutter the test result with error messages.
@@ -132,7 +136,7 @@ pub fn parseFrom(self: *App, argv: []const [:0]const u8) YazapError!ArgMatches {
132136

133137
if (result.getCommandContainingHelpFlag()) |command| {
134138
var buffer: [help_message_buffer_size]u8 = undefined;
135-
var help_writer = HelpMessageWriter.init(command, &buffer);
139+
var help_writer = HelpMessageWriter.init(command, io, &buffer);
136140
try help_writer.write();
137141
result.deinit();
138142
self.deinit();
@@ -162,14 +166,14 @@ pub fn parseFrom(self: *App, argv: []const [:0]const u8) YazapError!ArgMatches {
162166
/// const matches = try app.parseProcess();
163167
///
164168
/// if (!matches.containsArgs()) {
165-
/// try app.displayHelp();
169+
/// try app.displayHelp(io);
166170
/// return;
167171
/// }
168172
/// ```
169-
pub fn displayHelp(self: *App) YazapError!void {
173+
pub fn displayHelp(self: *App, io: std.Io) YazapError!void {
170174
if (self.parse_result) |parse_result| {
171175
var buffer: [help_message_buffer_size]u8 = undefined;
172-
var help_writer = HelpMessageWriter.init(parse_result.getCommand(), &buffer);
176+
var help_writer = HelpMessageWriter.init(parse_result.getCommand(), io, &buffer);
173177
try help_writer.write();
174178
}
175179
}
@@ -197,15 +201,15 @@ pub fn displayHelp(self: *App) YazapError!void {
197201
///
198202
/// if (matches.subcommandMatches("subcmd")) |subcmd_matches| {
199203
/// if (!subcmd_matches.containsArgs()) {
200-
/// try app.displaySubcommandHelp();
204+
/// try app.displaySubcommandHelp(io);
201205
/// }
202206
/// ```
203-
pub fn displaySubcommandHelp(self: *App) YazapError!void {
207+
pub fn displaySubcommandHelp(self: *App, io: std.Io) YazapError!void {
204208
const parse_result = self.parse_result orelse return;
205209

206210
if (parse_result.getActiveSubcommand()) |subcmd| {
207211
var buffer: [help_message_buffer_size]u8 = undefined;
208-
var help_writer = HelpMessageWriter.init(subcmd, &buffer);
212+
var help_writer = HelpMessageWriter.init(subcmd, io, &buffer);
209213
try help_writer.write();
210214
}
211215
}

src/HelpMessageWriter.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const HelpMessageWriter = @This();
22

33
const std = @import("std");
44
const Arg = @import("Arg.zig");
5-
const BufferedWriter = std.fs.File.Writer;
5+
const BufferedWriter = std.Io.File.Writer;
66
const Command = @import("Command.zig");
77
const ParsedCommand = @import("parser/ParseResult.zig").ParsedCommand;
88

@@ -16,9 +16,9 @@ writer: BufferedWriter = undefined,
1616
/// Command whose help to write.
1717
command: *const ParsedCommand = undefined,
1818

19-
pub fn init(command: *const ParsedCommand, buffer: []u8) HelpMessageWriter {
19+
pub fn init(command: *const ParsedCommand, io: std.Io, buffer: []u8) HelpMessageWriter {
2020
return HelpMessageWriter{
21-
.writer = .init(std.fs.File.stderr(), buffer),
21+
.writer = .init(std.Io.File.stderr(), io, buffer),
2222
.command = command,
2323
};
2424
}

src/parser/ParseError.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn setContext(self: *ParseError, ctx: Context) void {
1919
/// Prints the error context in a nice error message.
2020
pub fn print(self: *const ParseError) PrintError!void {
2121
var buffer: [1024]u8 = undefined;
22-
var _writer = std.fs.File.stderr().writer(&buffer);
22+
var _writer = std.Io.File.stderr().writer(&buffer);
2323
const writer = &_writer.interface;
2424

2525
// Print the error prefix for nicer output.
@@ -111,7 +111,7 @@ pub fn print(self: *const ParseError) PrintError!void {
111111
}
112112

113113
/// An error type returned by the `print`.
114-
pub const PrintError = std.fs.File.WriteError || std.Io.Writer.Error;
114+
pub const PrintError = std.Io.Writer.Error;
115115
/// An error type returned by the parser.
116116
pub const Error = error{
117117
UnrecognizedCommand,

src/test.zig

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ test "positional arguments with auto index" {
1414
try app.rootCommand().addArg(Arg.positional("TWO", null, null));
1515
try app.rootCommand().addArg(Arg.positional("THREE", null, null));
1616

17-
const matches = try app.parseFrom(&.{ "val1", "val2", "val3" });
17+
const matches = try app.parseFrom(std.testing.io, &.{ "val1", "val2", "val3" });
1818
try testing.expectEqualStrings("val1", matches.getSingleValue("ONE").?);
1919
try testing.expectEqualStrings("val2", matches.getSingleValue("TWO").?);
2020
try testing.expectEqualStrings("val3", matches.getSingleValue("THREE").?);
@@ -30,7 +30,7 @@ test "positional arguments with manual index" {
3030
try app.rootCommand().addArg(Arg.positional("THREE", null, 3));
3131
try app.rootCommand().addArg(Arg.positional("TWO", null, 2));
3232

33-
const matches = try app.parseFrom(&.{ "val1", "val2", "val3" });
33+
const matches = try app.parseFrom(std.testing.io, &.{ "val1", "val2", "val3" });
3434
try testing.expectEqualStrings("val1", matches.getSingleValue("ONE").?);
3535
try testing.expectEqualStrings("val2", matches.getSingleValue("TWO").?);
3636
try testing.expectEqualStrings("val3", matches.getSingleValue("THREE").?);
@@ -57,7 +57,7 @@ test "command that takes single value" {
5757

5858
try app.rootCommand().addArg(Arg.positional("PATH", null, 1));
5959

60-
const matches = try app.parseFrom(&.{"test.txt"});
60+
const matches = try app.parseFrom(std.testing.io, &.{"test.txt"});
6161
try testing.expectEqualStrings("test.txt", matches.getSingleValue("PATH").?);
6262

6363
app.deinit();
@@ -117,7 +117,7 @@ test "command that takes required positional arg" {
117117

118118
try app.rootCommand().addArg(Arg.positional("PATH", null, null));
119119
app.rootCommand().setProperty(.positional_arg_required);
120-
try testing.expectError(error.PositionalArgumentNotProvided, app.parseFrom(&.{}));
120+
try testing.expectError(error.PositionalArgumentNotProvided, app.parseFrom(std.testing.io, &.{}));
121121

122122
app.deinit();
123123
}
@@ -128,7 +128,7 @@ test "command requires subcommand" {
128128

129129
try app.rootCommand().addSubcommand(app.createCommand("init", null));
130130
app.rootCommand().setProperty(.subcommand_required);
131-
try testing.expectError(error.SubcommandNotProvided, app.parseFrom(&.{}));
131+
try testing.expectError(error.SubcommandNotProvided, app.parseFrom(std.testing.io, &.{}));
132132

133133
app.deinit();
134134
}
@@ -138,7 +138,7 @@ test "Option that does not takes value" {
138138
errdefer app.deinit();
139139

140140
try app.rootCommand().addArg(Arg.booleanOption("version", 'v', null));
141-
try testing.expectError(error.UnexpectedOptionValue, app.parseFrom(&.{"-v=13"}));
141+
try testing.expectError(error.UnexpectedOptionValue, app.parseFrom(std.testing.io, &.{"-v=13"}));
142142

143143
app.deinit();
144144
}
@@ -148,7 +148,7 @@ test "Option that takes single value" {
148148
errdefer app.deinit();
149149

150150
try app.rootCommand().addArg(Arg.singleValueOption("output", 'o', null));
151-
try testing.expectError(error.OptionValueNotProvided, app.parseFrom(&.{"-o"}));
151+
try testing.expectError(error.OptionValueNotProvided, app.parseFrom(std.testing.io, &.{"-o"}));
152152

153153
app.deinit();
154154
}
@@ -162,7 +162,7 @@ test "multiValuesOption provided with single value short" {
162162
// ex: clang sources...
163163
try app.rootCommand().addArg(srcs);
164164

165-
const matches_short = try app.parseFrom(&.{ "-s", "f1" });
165+
const matches_short = try app.parseFrom(std.testing.io, &.{ "-s", "f1" });
166166
try testing.expectEqual(@as(usize, 1), matches_short.getMultiValues("sources").?.len);
167167
}
168168

@@ -175,7 +175,7 @@ test "multiValuesOption provided with single value long" {
175175
// ex: clang sources...
176176
try app.rootCommand().addArg(srcs);
177177

178-
const matches_short = try app.parseFrom(&.{ "--sources", "f1" });
178+
const matches_short = try app.parseFrom(std.testing.io, &.{ "--sources", "f1" });
179179
try testing.expectEqual(@as(usize, 1), matches_short.getMultiValues("sources").?.len);
180180
}
181181

@@ -187,7 +187,7 @@ test "multiValuesOption provided with multiple values short" {
187187

188188
// ex: clang sources...
189189
try app.rootCommand().addArg(srcs);
190-
const matches = try app.parseFrom(&.{ "-s", "f1", "f2", "f3", "f4", "f5" });
190+
const matches = try app.parseFrom(std.testing.io, &.{ "-s", "f1", "f2", "f3", "f4", "f5" });
191191

192192
try testing.expectEqual(@as(usize, 5), matches.getMultiValues("sources").?.len);
193193
}
@@ -200,7 +200,7 @@ test "multiValuesOption provided with multiple values long" {
200200

201201
// ex: clang sources...
202202
try app.rootCommand().addArg(srcs);
203-
const matches = try app.parseFrom(&.{ "--sources", "f1", "f2", "f3", "f4", "f5" });
203+
const matches = try app.parseFrom(std.testing.io, &.{ "--sources", "f1", "f2", "f3", "f4", "f5" });
204204

205205
try testing.expectEqual(@as(usize, 5), matches.getMultiValues("sources").?.len);
206206
}
@@ -217,7 +217,7 @@ test "Option that takes many/multiple values" {
217217

218218
// ex: clang sources...
219219
try app.rootCommand().addArg(srcs);
220-
const matches = try app.parseFrom(&.{ "-s", "f1", "f2", "f3", "f4", "f5" });
220+
const matches = try app.parseFrom(std.testing.io, &.{ "-s", "f1", "f2", "f3", "f4", "f5" });
221221

222222
try testing.expectEqual(@as(usize, 5), matches.getMultiValues("sources").?.len);
223223

@@ -235,7 +235,7 @@ test "Option with min values" {
235235
srcs.setProperty(.takes_value);
236236

237237
try app.rootCommand().addArg(srcs);
238-
try testing.expectError(error.TooFewOptionValue, app.parseFrom(&.{"-s=f1"}));
238+
try testing.expectError(error.TooFewOptionValue, app.parseFrom(std.testing.io, &.{"-s=f1"}));
239239

240240
app.deinit();
241241
}
@@ -249,6 +249,7 @@ test "Option with max values" {
249249

250250
try app.rootCommand().addArg(srcs);
251251
try testing.expectError(error.TooManyOptionValue, app.parseFrom(
252+
std.testing.io,
252253
&.{"-s=f1:f2:f3:f4:f5:f6"},
253254
));
254255

@@ -267,7 +268,7 @@ test "Option with allowed values" {
267268
);
268269

269270
try app.rootCommand().addArg(stdd);
270-
try testing.expectError(error.InvalidOptionValue, app.parseFrom(&.{"--std=c100"}));
271+
try testing.expectError(error.InvalidOptionValue, app.parseFrom(std.testing.io, &.{"--std=c100"}));
271272

272273
app.deinit();
273274
}
@@ -280,7 +281,7 @@ test "passing positional argument before options" {
280281
try app.rootCommand().addArg(Arg.booleanOption("all", 'a', null));
281282
app.rootCommand().setProperty(.positional_arg_required);
282283

283-
const matches = try app.parseFrom(&.{ ".", "-a" });
284+
const matches = try app.parseFrom(std.testing.io, &.{ ".", "-a" });
284285
try testing.expectEqualStrings(".", matches.getSingleValue("PATH").?);
285286
try testing.expectEqual(true, matches.containsArg("all"));
286287

@@ -294,7 +295,7 @@ test "passing positional argument after options" {
294295
try app.rootCommand().addArg(Arg.positional("PATH", null, null));
295296
try app.rootCommand().addArg(Arg.booleanOption("all", 'a', null));
296297

297-
const matches = try app.parseFrom(&.{ "-a", "." });
298+
const matches = try app.parseFrom(std.testing.io, &.{ "-a", "." });
298299
try testing.expectEqualStrings(".", matches.getSingleValue("PATH").?);
299300
try testing.expectEqual(true, matches.containsArg("all"));
300301

@@ -309,7 +310,7 @@ test "passing positional argument before and after options" {
309310
try app.rootCommand().addArg(Arg.booleanOption("all", 'a', null));
310311
try app.rootCommand().addArg(Arg.booleanOption("one-line", '1', null));
311312

312-
const matches = try app.parseFrom(&.{ "-1", ".", "-a" });
313+
const matches = try app.parseFrom(std.testing.io, &.{ "-1", ".", "-a" });
313314
try testing.expectEqualStrings(".", matches.getSingleValue("PATH").?);
314315
try testing.expectEqual(true, matches.containsArg("one-line"));
315316
try testing.expectEqual(true, matches.containsArg("all"));

0 commit comments

Comments
 (0)