summaryrefslogtreecommitdiffstats
path: root/README.md
blob: 26e77d4cecf34eded2713e2a7d455091084c119e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# Coalpit

Coalpit is a library for
building
[command-line program interfaces](https://defanor.uberspace.net/notes/command-line-program-interface.html):
the goal is to get interfaces between programs quickly and easily,
while keeping them language-agnostic and more user- and shell
scripting-friendly than JSON and similar formats.

Given a type, it derives instances to print and parse it as
command-line arguments or DSVs, as well as to compose usage
instructions. The resulting deserialization wouldn't be as nice as
that of
e.g.
[optparse-generic](https://hackage.haskell.org/package/optparse-generic),
but the aim here is to handle more or less arbitrary types.

Warning: it is possible to run into ambiguity by defining a recursive
structure with optional named elements while using default options.
Unit type can be used to avoid that, or `omitNamedOptions` can be
disabled.

Not production-ready yet, merely a prototype.

## Example

An example is available in `Example.hs`. Given the following Haskell
value:

```haskell
Input { something = Nothing
      , fooBar = Just (Foo (FooArgs { arg1 = 1
                                    , arg2 = "a string"}))
      , fooBar2 = Bar}
```

With the default options, its serialized version should look like
this:

```haskell
["--foobar","foo","1","a string","bar"]
```

What would look like this in a shell:

```sh
--foobar foo 1 'a string' bar
```

And its usage string -- like this:

```
[--something STRING] [--foobar (foo INT STRING | bar)] (foo INT STRING | bar)
```

More verbose versions can be produced and parsed with
`alwaysUseSelName = True` and/or `omitNamedOptions = False`:

```sh
--foobar foo --arg1 1 --arg2 'a string' --foobar2 bar
nothing just foo 1 'a string' bar
--something nothing --foobar just foo --arg1 1 --arg2 'a string' --foobar2 bar
```

And here is output of the `help` function from the same file, with all
the (alwaysUseSelName, omitNamedOptions) combinations:

```
(True,True)
--foo : 1 : 2 : 3 [] --bar "a string"
--foo ([] | : INT ([] | :...)) [--bar STRING]
(True,True)
--foo : 1 : 2 : 3 []
--foo ([] | : INT ([] | :...)) [--bar STRING]
(True,False)
--foo : 1 : 2 : 3 [] --bar just "a string"
--foo ([] | : INT ([] | :...)) --bar (nothing | just STRING)
(True,False)
--foo : 1 : 2 : 3 [] --bar nothing
--foo ([] | : INT ([] | :...)) --bar (nothing | just STRING)
(False,True)
: 1 : 2 : 3 [] --bar "a string"
([] | : INT ([] | :...)) [--bar STRING]
(False,True)
: 1 : 2 : 3 []
([] | : INT ([] | :...)) [--bar STRING]
(False,False)
: 1 : 2 : 3 [] just "a string"
([] | : INT ([] | :...)) (nothing | just STRING)
(False,False)
: 1 : 2 : 3 [] nothing
([] | : INT ([] | :...)) (nothing | just STRING)
```