7
7
8
8
Command line argument decoders for Gleam.
9
9
10
- - Clad provides primitives to build a ` dynamic.Decoder ` for command line arguments.
11
- - Arguments can be specified with long names (` --name ` ) or short names (` -n ` ).
12
- - Values are decoded in the form ` --name value ` or ` --name=value ` .
13
- - Boolean flags do not an explicit value. If the flag exists it is ` True ` , and if it is missing it is ` False ` . (i.e. ` --verbose ` )
10
+ Clad aims to make it as easy as possible to parse command line arguments in
11
+ Gleam. The goal is to support simple to medium complexity command line
12
+ interfaces while staying as minimal as possible. It is inspired by
13
+ [ minimist] ( https://github.com/minimistjs/minimist ) and
14
+ [ gleam/json] ( https://hexdocs.pm/gleam_json/ )
14
15
15
16
16
17
## Usage
@@ -24,80 +25,51 @@ This program is in the [examples directory](https://github.com/ryanmiville/clad/
24
25
``` gleam
25
26
import argv
26
27
import clad
27
- import gleam/bool
28
- import gleam/dynamic
29
- import gleam/int
30
- import gleam/io
31
- import gleam/string
32
-
33
- type Order {
34
- Order(flavors: List(String), scoops: Int, cone: Bool)
35
- }
28
+ import decode/zero
36
29
37
- fn order_decoder() {
38
- use flavors <- clad.arg("flavor", "f", dynamic.list(dynamic.string))
39
- use scoops <- clad.arg_with_default("scoops", "s", dynamic.int, default: 1)
40
- use cone <- clad.toggle("cone", "c")
41
- clad.decoded(Order(flavors:, scoops:, cone:))
30
+ pub type Student {
31
+ Student(name: String, age: Int, enrolled: Bool, classes: List(String))
42
32
}
43
33
44
34
pub fn main() {
45
- let order =
46
- order_decoder()
47
- |> clad.decode(argv.load().arguments)
48
-
49
- case order {
50
- Ok(order) -> take_order(order)
51
- _ ->
52
- io.println(
53
- "
54
- Options:
55
- -f, --flavor <FLAVOR> Flavors of ice cream
56
- -s, --scoops <SCOOPS> Number of scoops per flavor [default: 1]
57
- -c, --cone Put ice cream in a cone
58
- ",
59
- )
35
+ let decoder = {
36
+ use name <- zero.field("name", zero.string)
37
+ use age <- zero.field("age", zero.int)
38
+ use enrolled <- zero.field("enrolled", zero.bool)
39
+ use classes <- clad.positional_arguments()
40
+ zero.success(Student(name:, age:, enrolled:, classes:))
60
41
}
61
- }
62
42
63
- fn take_order(order: Order) {
64
- let scoops = bool.guard(order.scoops == 1, " scoop", fn() { " scoops" })
65
- let container = bool.guard(order.cone, "cone", fn() { "cup" })
66
- let flavs = string.join(order.flavors, " and ")
67
- io.println(
68
- int.to_string(order.scoops)
69
- <> scoops
70
- <> " of "
71
- <> flavs
72
- <> " in a "
73
- <> container
74
- <> ", coming right up!",
75
- )
43
+ // args: --name Lucy --age 8 --enrolled true math science art
44
+ let result = clad.decode(argv.load().arguments, decoder)
45
+ let assert Ok(Student("Lucy", 8, True, ["math", "science", "art"])) = result
76
46
}
77
47
```
78
48
79
- Run the program
49
+ Or, for more flexibility:
80
50
81
- ``` sh
82
- ❯ gleam run -m examples/ice_cream -- -f vanilla
83
- 1 scoop of vanilla in a cup, coming right up!
84
- ❯ gleam run -m examples/ice_cream -- --flavor vanilla --flavor chocolate
85
- 1 scoop of vanilla and chocolate in a cup, coming right up!
86
- ❯ gleam run -m examples/ice_cream -- --flavor vanilla --flavor chocolate --scoops 2 --cone
87
- 2 scoops of vanilla and chocolate in a cone, coming right up!
88
- ❯ gleam run -m examples/ice_cream --
89
-
90
- Options:
91
- -f, --flavor < FLAVOR> Flavors of ice cream
92
- -s, --scoops < SCOOPS> Number of scoops per flavor [default: 1]
93
- -c, --cone Put ice cream in a cone
94
- ```
51
+ ``` gleam
52
+ import argv
53
+ import clad
54
+ import decode/zero
95
55
96
- ## Roadmap
56
+ pub type Student {
57
+ Student(name: String, age: Int, enrolled: Bool, classes: List(String))
58
+ }
59
+
60
+ pub fn main() {
61
+ let decoder = {
62
+ use name <- clad.opt("name", "n", zero.string)
63
+ use age <- clad.opt("age", "a", zero.int)
64
+ use enrolled <- clad.opt("enrolled", "e", clad.flag())
65
+ use classes <- clad.positional_arguments()
66
+ zero.success(Student(name:, age:, enrolled:, classes:))
67
+ }
97
68
98
- - [ ] Settle on general API
99
- - [ ] Add support for positional arguments
100
- - [ ] Add support for subcommands
101
- - [ ] Add support for environment variables
69
+ // args: --name=Lucy -ea8 math science art
70
+ let result = clad.decode(argv.load().arguments, decoder)
71
+ let assert Ok(Student("Lucy", 8, True, ["math", "science", "art"])) = result
72
+ }
73
+ ```
102
74
103
75
Further documentation can be found at < https://hexdocs.pm/clad > .
0 commit comments