Skip to content

Commit 2e25be6

Browse files
author
Ryan Miville
authored
Merge pull request #3 from ryanmiville/minimist
minimist
2 parents 6b0fb48 + 8cc4972 commit 2e25be6

File tree

10 files changed

+509
-896
lines changed

10 files changed

+509
-896
lines changed

README.md

+39-67
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77

88
Command line argument decoders for Gleam.
99

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/)
1415

1516

1617
## Usage
@@ -24,80 +25,51 @@ This program is in the [examples directory](https://github.com/ryanmiville/clad/
2425
```gleam
2526
import argv
2627
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
3629
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))
4232
}
4333
4434
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:))
6041
}
61-
}
6242
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
7646
}
7747
```
7848

79-
Run the program
49+
Or, for more flexibility:
8050

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
9555
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+
}
9768
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+
```
10274

10375
Further documentation can be found at <https://hexdocs.pm/clad>.

gleam.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name = "clad"
2-
version = "0.1.5"
2+
version = "0.2.0"
33

44
# Fill out these fields if you intend to generate HTML documentation or publish
55
# your project to the Hex package manager.
@@ -14,7 +14,9 @@ repository = { type = "github", user = "ryanmiville", repo = "clad" }
1414

1515
[dependencies]
1616
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
17+
decode = ">= 0.4.1 and < 1.0.0"
1718

1819
[dev-dependencies]
1920
gleeunit = ">= 1.0.0 and < 2.0.0"
2021
argv = ">= 1.0.2 and < 2.0.0"
22+
gleam_json = ">= 2.0.0 and < 3.0.0"

manifest.toml

+4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33

44
packages = [
55
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
6+
{ name = "decode", version = "0.4.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "decode", source = "hex", outer_checksum = "90C83E830B380EAF64A0A20D0116C4C173AD753594AF1A37E692C1A699244244" },
7+
{ name = "gleam_json", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "CB10B0E7BF44282FB25162F1A24C1A025F6B93E777CCF238C4017E4EEF2CDE97" },
68
{ name = "gleam_stdlib", version = "0.40.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86606B75A600BBD05E539EB59FABC6E307EEEA7B1E5865AFB6D980A93BCB2181" },
79
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
810
]
911

1012
[requirements]
1113
argv = { version = ">= 1.0.2 and < 2.0.0" }
14+
decode = { version = ">= 0.4.1 and < 1.0.0" }
15+
gleam_json = { version = ">= 2.0.0 and < 3.0.0" }
1216
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
1317
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }

0 commit comments

Comments
 (0)