Closed Feoramund closed 3 months ago
With the current parser implementation, is it possible to add an Odin style option with no hyphens? Or is that outside of the scope of this package? I tend to have a preference towards no hyphens but I don't mind either way.
With the current parser implementation, is it possible to add an Odin style option with no hyphens? Or is that outside of the scope of this package? I tend to have a preference towards no hyphens but I don't mind either way.
With that style, how do you distinguish between positional and non-positional arguments, or do positionals just not exist in this method? Is there a program you have in mind that parses arguments like this that I could look at?
I'll be looking at this again in a bit. It's been a week, and I've only had one pressing idea that's come to mind: supporting the UNIX-style --
flag that consumes all following arguments. After that, I should be able to mark it as ready.
Ready to go.
With that style, how do you distinguish between positional and non-positional arguments, or do positionals just not exist in this method? Is there a program you have in mind that parses arguments like this that I could look at?
@Feoramund I'm sorry for the late reply. I have no idea honestly. I don't knowingly use them. Normally if I want this style I'll make a unique one for it. And I'll probably just continue to. Here's quick generic example, it may bugs. https://gist.github.com/blob1807/74d0d507887da913b2a109a6893dce75
@blob1807 Hyphenless flags is not something I want.
I have no idea honestly. I don't knowingly use them. Normally if I want this style I'll make a unique one for it. And I'll probably just continue to.
The internal organization of core:flags
is modular and simple enough that I believe you could take a copy of it and just remove the checks for -
and calls to push_positional
to get what you want.
core:flags
, the rewriteIt's time for the Joy of Parsing Arguments.
Do you want to be able to use a struct as your data format for your command-line arguments?
Yes, it's that simple.
Demo
Have a look.
Supported Types
bit_set
sstring
andcstring
rune
os.Handle
time.Time
datetime.DateTime
net.Host_Or_Endpoint
dynamic
arrays with element types of the abovemap[string]
s ormap[cstring]
s with value types of the aboveWhat else can it do?
You can give it your own type setter
proc
for custom named types and a flag checkerproc
for the validation phase, to make sure all of the values are what you expect. The flag checker will only receive flags that have been set, so no need to add in extra logic to figure out what's what there.How does it work?
core:flags
makes extensive use of Odin's run-time type information system to determine where data in your struct is stored, what type it is, and it makes use of recursion to support dynamic arrays, maps, and maps of dynamic arrays (if amap[string][dynamic]T
solves a problem for you).The power of this is not to be underestimated. It's the same power that makes
core:encoding/json
work and what inspired this package in its original incarnation.There are a myriad of subtags for specifying how each flag should be named, positioned, if it should be hidden from help, if it's required (and in what number), how to handle files, and such.
Documentation
Everything has been thoroughly documented, and there is a full example included in the
example
subdirectory of the package. I mostly avoided the use of short variable names to help improve code reading. Notes and comments are left around where I thought they might be useful to clarify some of my thought processes.There is also a test suite including 50+ tests to ensure long-term stability and that expectations are met.
If asserts are not disabled, the parser will make sure the struct you give it is of a sensible construction. I.e. no
file
subtag on types that aren'tos.Handle
. That should help reduce confusion.odin-varg
This package originally started as
odin-varg
, a small library I wrote in a few hours after realizing howcore:encoding/json
worked. This is the fully rewritten, vetted and tested version, for Odin proper.If you used
odin-varg
at all, here's an incomplete summary of changes between then and now:variadic
,file
,perms
,indistinct
.Unix
.min<max
.core
types.proc
is now fully documented.-a:=3
,-a=:3
, et cetera.SUBTAG_POS
has been split off intoINTERNAL_VARIADIC_FLAG
, so the two can be named differently.pos
field has been renamed tovarg
which should be more unique, in the case you wanted to usepos
as a flag name.Notes
The
bit_set
parsing is experimental. In my mind at least, it made more sense to parse1
s and0
s from left to right as Least Significant Bit to Most Significant Bit. If it's a sensible way to parse them, I may be able to boot it intocore:strconv
at some point.I know several programs have a "command" style of mode, Odin included, where they accept the first argument as a way to switch between different actions. Odin has test, build, et cetera. I just want to note that I'm aware of this method, and I've considered it as a possible future expansion to
core:flags
, pending how this goes.I'm also aware of how some programs will have a
-v
to exit early and show the version information while disregarding other flags. That can kind of work here, if none of your flag values error, but there's no special handling for it. I'm more of the mind that showing version information makes more sense as a command, or perhaps a banner.I made a special case for
-h
and-help
because it's so ubiquitous and I could not fathom another way to display the usage documentation in the case where a program was started with no required arguments.variadic
flags being able to specify how many arguments they take at once was an easy feature, but I'm not sure how useful or fitting it is. Could probably use some feedback on that one.I'm uncertain if a banner feature is necessary, like a string that joins up with the usage as a header, sort of like how I handle
os.args[0]
.I'm leaving this as a draft for a bit to hear some thoughts and ideas.
Feedback
I'm looking for feedback, of any sort, code or aesthetics. Some of this is aesthetic, of course, and people have their different preferences for flags and how they're interpreted and displayed. Any oversights I may have made would be nice to know too. It's not a huge package, but it's a bit feature-dense and it took some time to get just right. I've reviewed it from top to bottom a few times, and more eyes are always appreciated.
I spent a few days taking notes on some common use cases for command-line argument parsing, but I could've missed your particular use case. This is why I added filename parsing-and-opening to the package, since it's such a common use case, and I could imagine a lot of boilerplate code being written if I didn't include that feature. Simplifies the whole process and saves some developer time while making things more of a joy, hopefully.