diff options
| author | 2018-05-31 22:01:15 +0200 | |
|---|---|---|
| committer | 2018-05-31 22:01:15 +0200 | |
| commit | ccf82622ad9c9c9e405187bc59470ce834df2978 (patch) | |
| tree | 0ab3a59d9433528c1efd1ffe07b6109944412c5f /src | |
| parent | Started work on the proper structure for the lib (diff) | |
| download | zig-clap-ccf82622ad9c9c9e405187bc59470ce834df2978.tar.gz zig-clap-ccf82622ad9c9c9e405187bc59470ce834df2978.tar.xz zig-clap-ccf82622ad9c9c9e405187bc59470ce834df2978.zip | |
Added example of how to parse Zig args with clap.core
Diffstat (limited to 'src')
| -rw-r--r-- | src/core.zig | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/src/core.zig b/src/core.zig index a3fb44c..22b5df2 100644 --- a/src/core.zig +++ b/src/core.zig | |||
| @@ -217,26 +217,26 @@ pub fn Clap(comptime Id: type) type { | |||
| 217 | 217 | ||
| 218 | arena: heap.ArenaAllocator, | 218 | arena: heap.ArenaAllocator, |
| 219 | params: []const Param(Id), | 219 | params: []const Param(Id), |
| 220 | inner: &ArgIterator, | 220 | iter: &ArgIterator, |
| 221 | state: State, | 221 | state: State, |
| 222 | 222 | ||
| 223 | pub fn init(params: []const Param(Id), inner: &ArgIterator, allocator: &mem.Allocator) Self { | 223 | pub fn init(params: []const Param(Id), iter: &ArgIterator, allocator: &mem.Allocator) Self { |
| 224 | var res = Self { | 224 | var res = Self { |
| 225 | .arena = heap.ArenaAllocator.init(allocator), | 225 | .arena = heap.ArenaAllocator.init(allocator), |
| 226 | .params = params, | 226 | .params = params, |
| 227 | .inner = inner, | 227 | .iter = iter, |
| 228 | .state = State.Normal, | 228 | .state = State.Normal, |
| 229 | }; | 229 | }; |
| 230 | 230 | ||
| 231 | return res; | 231 | return res; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | pub fn deinit(iter: &Self) void { | 234 | pub fn deinit(clap: &Self) void { |
| 235 | iter.arena.deinit(); | 235 | clap.arena.deinit(); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | /// Get the next ::Arg that matches a ::Param. | 238 | /// Get the next ::Arg that matches a ::Param. |
| 239 | pub fn next(iter: &Self) !?Arg(Id) { | 239 | pub fn next(clap: &Self) !?Arg(Id) { |
| 240 | const ArgInfo = struct { | 240 | const ArgInfo = struct { |
| 241 | const Kind = enum { Long, Short, Bare }; | 241 | const Kind = enum { Long, Short, Bare }; |
| 242 | 242 | ||
| @@ -244,9 +244,9 @@ pub fn Clap(comptime Id: type) type { | |||
| 244 | kind: Kind, | 244 | kind: Kind, |
| 245 | }; | 245 | }; |
| 246 | 246 | ||
| 247 | switch (iter.state) { | 247 | switch (clap.state) { |
| 248 | State.Normal => { | 248 | State.Normal => { |
| 249 | const full_arg = (try iter.innerNext()) ?? return null; | 249 | const full_arg = (try clap.nextNoParse()) ?? return null; |
| 250 | const arg_info = blk: { | 250 | const arg_info = blk: { |
| 251 | var arg = full_arg; | 251 | var arg = full_arg; |
| 252 | var kind = ArgInfo.Kind.Bare; | 252 | var kind = ArgInfo.Kind.Bare; |
| @@ -272,7 +272,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 272 | switch (kind) { | 272 | switch (kind) { |
| 273 | ArgInfo.Kind.Bare, | 273 | ArgInfo.Kind.Bare, |
| 274 | ArgInfo.Kind.Long => { | 274 | ArgInfo.Kind.Long => { |
| 275 | for (iter.params) |*param| { | 275 | for (clap.params) |*param| { |
| 276 | const match = switch (kind) { | 276 | const match = switch (kind) { |
| 277 | ArgInfo.Kind.Bare => param.names.bare ?? continue, | 277 | ArgInfo.Kind.Bare => param.names.bare ?? continue, |
| 278 | ArgInfo.Kind.Long => param.names.long ?? continue, | 278 | ArgInfo.Kind.Long => param.names.long ?? continue, |
| @@ -294,14 +294,14 @@ pub fn Clap(comptime Id: type) type { | |||
| 294 | if (maybe_value) |v| | 294 | if (maybe_value) |v| |
| 295 | break :blk v; | 295 | break :blk v; |
| 296 | 296 | ||
| 297 | break :blk (try iter.innerNext()) ?? return error.MissingValue; | 297 | break :blk (try clap.nextNoParse()) ?? return error.MissingValue; |
| 298 | }; | 298 | }; |
| 299 | 299 | ||
| 300 | return Arg(Id).init(param.id, value); | 300 | return Arg(Id).init(param.id, value); |
| 301 | } | 301 | } |
| 302 | }, | 302 | }, |
| 303 | ArgInfo.Kind.Short => { | 303 | ArgInfo.Kind.Short => { |
| 304 | return try iter.chainging(State.Chaining { | 304 | return try clap.chainging(State.Chaining { |
| 305 | .arg = full_arg, | 305 | .arg = full_arg, |
| 306 | .index = (full_arg.len - arg.len), | 306 | .index = (full_arg.len - arg.len), |
| 307 | }); | 307 | }); |
| @@ -310,7 +310,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 310 | 310 | ||
| 311 | // We do a final pass to look for value parameters matches | 311 | // We do a final pass to look for value parameters matches |
| 312 | if (kind == ArgInfo.Kind.Bare) { | 312 | if (kind == ArgInfo.Kind.Bare) { |
| 313 | for (iter.params) |*param| { | 313 | for (clap.params) |*param| { |
| 314 | if (param.names.bare) |_| continue; | 314 | if (param.names.bare) |_| continue; |
| 315 | if (param.names.short) |_| continue; | 315 | if (param.names.short) |_| continue; |
| 316 | if (param.names.long) |_| continue; | 316 | if (param.names.long) |_| continue; |
| @@ -321,26 +321,26 @@ pub fn Clap(comptime Id: type) type { | |||
| 321 | 321 | ||
| 322 | return error.InvalidArgument; | 322 | return error.InvalidArgument; |
| 323 | }, | 323 | }, |
| 324 | @TagType(State).Chaining => |state| return try iter.chainging(state), | 324 | @TagType(State).Chaining => |state| return try clap.chainging(state), |
| 325 | } | 325 | } |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | fn chainging(iter: &Self, state: &const State.Chaining) !?Arg(Id) { | 328 | fn chainging(clap: &Self, state: &const State.Chaining) !?Arg(Id) { |
| 329 | const arg = state.arg; | 329 | const arg = state.arg; |
| 330 | const index = state.index; | 330 | const index = state.index; |
| 331 | const next_index = index + 1; | 331 | const next_index = index + 1; |
| 332 | 332 | ||
| 333 | for (iter.params) |param| { | 333 | for (clap.params) |param| { |
| 334 | const short = param.names.short ?? continue; | 334 | const short = param.names.short ?? continue; |
| 335 | if (short != arg[index]) | 335 | if (short != arg[index]) |
| 336 | continue; | 336 | continue; |
| 337 | 337 | ||
| 338 | // Before we return, we have to set the new state of the iterator | 338 | // Before we return, we have to set the new state of the clap |
| 339 | defer { | 339 | defer { |
| 340 | if (arg.len <= next_index or param.takes_value) { | 340 | if (arg.len <= next_index or param.takes_value) { |
| 341 | iter.state = State.Normal; | 341 | clap.state = State.Normal; |
| 342 | } else { | 342 | } else { |
| 343 | iter.state = State { .Chaining = State.Chaining { | 343 | clap.state = State { .Chaining = State.Chaining { |
| 344 | .arg = arg, | 344 | .arg = arg, |
| 345 | .index = next_index, | 345 | .index = next_index, |
| 346 | }}; | 346 | }}; |
| @@ -351,7 +351,7 @@ pub fn Clap(comptime Id: type) type { | |||
| 351 | return Arg(Id).init(param.id, null); | 351 | return Arg(Id).init(param.id, null); |
| 352 | 352 | ||
| 353 | if (arg.len <= next_index) { | 353 | if (arg.len <= next_index) { |
| 354 | const value = (try iter.innerNext()) ?? return error.MissingValue; | 354 | const value = (try clap.nextNoParse()) ?? return error.MissingValue; |
| 355 | return Arg(Id).init(param.id, value); | 355 | return Arg(Id).init(param.id, value); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| @@ -365,8 +365,10 @@ pub fn Clap(comptime Id: type) type { | |||
| 365 | return error.InvalidArgument; | 365 | return error.InvalidArgument; |
| 366 | } | 366 | } |
| 367 | 367 | ||
| 368 | fn innerNext(iter: &Self) !?[]const u8 { | 368 | // Returns the next arg in the underlying arg iterator |
| 369 | return try iter.inner.next(&iter.arena.allocator); | 369 | pub fn nextNoParse(clap: &Self) !?[]const u8 { |
| 370 | clap.state = State.Normal; | ||
| 371 | return try clap.iter.next(&clap.arena.allocator); | ||
| 370 | } | 372 | } |
| 371 | }; | 373 | }; |
| 372 | } | 374 | } |