summaryrefslogtreecommitdiff
path: root/src/args.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/args.zig')
-rw-r--r--src/args.zig46
1 files changed, 17 insertions, 29 deletions
diff --git a/src/args.zig b/src/args.zig
index 304596c..8706ebc 100644
--- a/src/args.zig
+++ b/src/args.zig
@@ -6,51 +6,42 @@ const heap = std.heap;
6const mem = std.mem; 6const mem = std.mem;
7const os = std.os; 7const os = std.os;
8 8
9/// A interface for iterating over command line arguments 9/// An example of what methods should be implemented on an arg iterator.
10pub fn Iterator(comptime E: type) type { 10pub const ExampleArgIterator = struct {
11 return struct { 11 const Error = error{};
12 const Self = @This();
13 const Error = E;
14
15 nextFn: fn (iter: *Self) Error!?[]const u8,
16 12
17 pub fn next(iter: *Self) Error!?[]const u8 { 13 pub fn next(iter: *ExampleArgIterator) Error!?[]const u8 {
18 return iter.nextFn(iter); 14 return "2";
19 } 15 }
20 }; 16};
21}
22 17
23/// An ::ArgIterator, which iterates over a slice of arguments. 18/// An argument iterator which iterates over a slice of arguments.
24/// This implementation does not allocate. 19/// This implementation does not allocate.
25pub const SliceIterator = struct { 20pub const SliceIterator = struct {
26 const Error = error{}; 21 const Error = error{};
27 22
28 args: []const []const u8, 23 args: []const []const u8,
29 index: usize, 24 index: usize,
30 iter: Iterator(Error),
31 25
32 pub fn init(args: []const []const u8) SliceIterator { 26 pub fn init(args: []const []const u8) SliceIterator {
33 return SliceIterator{ 27 return SliceIterator{
34 .args = args, 28 .args = args,
35 .index = 0, 29 .index = 0,
36 .iter = Iterator(Error){ .nextFn = nextFn },
37 }; 30 };
38 } 31 }
39 32
40 fn nextFn(iter: *Iterator(Error)) Error!?[]const u8 { 33 pub fn next(iter: *SliceIterator) Error!?[]const u8 {
41 const self = @fieldParentPtr(SliceIterator, "iter", iter); 34 if (iter.args.len <= iter.index)
42 if (self.args.len <= self.index)
43 return null; 35 return null;
44 36
45 defer self.index += 1; 37 defer iter.index += 1;
46 return self.args[self.index]; 38 return iter.args[iter.index];
47 } 39 }
48}; 40};
49 41
50test "clap.args.SliceIterator" { 42test "clap.args.SliceIterator" {
51 const args = [][]const u8{ "A", "BB", "CCC" }; 43 const args = [][]const u8{ "A", "BB", "CCC" };
52 var slice_iter = SliceIterator.init(args); 44 var iter = SliceIterator.init(args);
53 const iter = &slice_iter.iter;
54 45
55 for (args) |a| { 46 for (args) |a| {
56 const b = try iter.next(); 47 const b = try iter.next();
@@ -58,20 +49,18 @@ test "clap.args.SliceIterator" {
58 } 49 }
59} 50}
60 51
61/// An ::ArgIterator, which wraps the ArgIterator in ::std. 52/// An argument iterator which wraps the ArgIterator in ::std.
62/// On windows, this iterator allocates. 53/// On windows, this iterator allocates.
63pub const OsIterator = struct { 54pub const OsIterator = struct {
64 const Error = os.ArgIterator.NextError; 55 const Error = os.ArgIterator.NextError;
65 56
66 arena: heap.ArenaAllocator, 57 arena: heap.ArenaAllocator,
67 args: os.ArgIterator, 58 args: os.ArgIterator,
68 iter: Iterator(Error),
69 59
70 pub fn init(allocator: *mem.Allocator) OsIterator { 60 pub fn init(allocator: *mem.Allocator) OsIterator {
71 return OsIterator{ 61 return OsIterator{
72 .arena = heap.ArenaAllocator.init(allocator), 62 .arena = heap.ArenaAllocator.init(allocator),
73 .args = os.args(), 63 .args = os.args(),
74 .iter = Iterator(Error){ .nextFn = nextFn },
75 }; 64 };
76 } 65 }
77 66
@@ -79,12 +68,11 @@ pub const OsIterator = struct {
79 iter.arena.deinit(); 68 iter.arena.deinit();
80 } 69 }
81 70
82 fn nextFn(iter: *Iterator(Error)) Error!?[]const u8 { 71 pub fn next(iter: *OsIterator) Error!?[]const u8 {
83 const self = @fieldParentPtr(OsIterator, "iter", iter);
84 if (builtin.os == builtin.Os.windows) { 72 if (builtin.os == builtin.Os.windows) {
85 return try self.args.next(&self.arena.allocator) orelse return null; 73 return try iter.args.next(&iter.arena.allocator) orelse return null;
86 } else { 74 } else {
87 return self.args.nextPosix(); 75 return iter.args.nextPosix();
88 } 76 }
89 } 77 }
90}; 78};