diff options
| author | 2019-02-10 14:47:12 +0100 | |
|---|---|---|
| committer | 2019-02-10 14:47:12 +0100 | |
| commit | 810ef3671d9c2cea5ce5524f51bf2d947a6cb5bf (patch) | |
| tree | 90b8a1fa5276d23360fb7afcfb47083eda7a53b7 /src/args.zig | |
| parent | Updated to newest testing API (diff) | |
| parent | Removed duplicate in readme (diff) | |
| download | zig-clap-810ef3671d9c2cea5ce5524f51bf2d947a6cb5bf.tar.gz zig-clap-810ef3671d9c2cea5ce5524f51bf2d947a6cb5bf.tar.xz zig-clap-810ef3671d9c2cea5ce5524f51bf2d947a6cb5bf.zip | |
Merge branch 'master' of github.com:Hejsil/zig-clap
Diffstat (limited to 'src/args.zig')
| -rw-r--r-- | src/args.zig | 46 |
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; | |||
| 6 | const mem = std.mem; | 6 | const mem = std.mem; |
| 7 | const os = std.os; | 7 | const 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. |
| 10 | pub fn Iterator(comptime E: type) type { | 10 | pub 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. |
| 25 | pub const SliceIterator = struct { | 20 | pub 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 | ||
| 50 | test "clap.args.SliceIterator" { | 42 | test "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. |
| 63 | pub const OsIterator = struct { | 54 | pub 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 | }; |