7 Commits
0.0.1 ... 0.0.4

Author SHA1 Message Date
10ba753ee3 cli: better to-map 2020-01-31 10:43:42 +01:00
0b185aa3b9 cli: add morphers 2020-01-30 16:43:58 +01:00
b5eb3a917b cli: fix memerror in usage 2020-01-30 16:01:11 +01:00
cb5c9f0bfe docs: fix typos 2020-01-29 21:13:13 +01:00
7bd0817c27 update docs 2020-01-29 21:09:48 +01:00
493d0016d5 vbump 2020-01-29 21:08:47 +01:00
aaf413ac04 cli: fix printing of types and do not override previous errors 2020-01-29 21:07:31 +01:00
3 changed files with 98 additions and 37 deletions

View File

@@ -3,7 +3,7 @@
A simple CLI library for Carp. A simple CLI library for Carp.
```clojure ```clojure
(load "https://veitheller.de/git/carpentry/cli@master") (load "https://veitheller.de/git/carpentry/cli@0.0.2")
(defn main [] (defn main []
(let [p (=> (CLI.new @"My super cool tool!") (let [p (=> (CLI.new @"My super cool tool!")
@@ -18,7 +18,7 @@ A simple CLI library for Carp.
## Installation ## Installation
```clojure ```clojure
(load "https://veitheller.de/git/carpentry/cli@master") (load "https://veitheller.de/git/carpentry/cli@0.0.2")
``` ```
## Usage ## Usage

View File

@@ -6,7 +6,7 @@
(doc CLI "is a simple CLI library for Carp. (doc CLI "is a simple CLI library for Carp.
```clojure ```clojure
(load \"https://veitheller.de/git/carpentry/cli@0.0.1\") (load \"https://veitheller.de/git/carpentry/cli@0.0.2\")
(defn main [] (defn main []
(let [p (=> (CLI.new @\"My super cool tool!\") (let [p (=> (CLI.new @\"My super cool tool!\")
@@ -21,7 +21,7 @@
## Installation ## Installation
```clojure ```clojure
(load \"https://veitheller.de/git/carpentry/cli@0.0.1\") (load \"https://veitheller.de/git/carpentry/cli@0.0.2\")
``` ```
## Usage ## Usage
@@ -46,8 +46,8 @@ manually.
Once youre done building your flag structure, you can run `CLI.parse`. It Once youre done building your flag structure, you can run `CLI.parse`. It
will not abort the program on error, instead it will tell you what went wrong will not abort the program on error, instead it will tell you what went wrong
in a `Result.Error`. If it succeeds, the `Result.Success` contains a `Map` from in a `Result.Error`. If it succeeds, the `Result.Success` contains a `Map` from
the long flag name to the value (the values are `Maybe`s, since they might be the long flag name to the value. The values are not in the map if they are
optional arguments.") unset.")
(defmodule CLI (defmodule CLI
(hidden Type) (hidden Type)
(private Type) (private Type)
@@ -55,11 +55,16 @@ optional arguments.")
(Integer [Long]) (Integer [Long])
(Floating [Double]) (Floating [Double])
(Str [String]) (Str [String])
(None [])
) )
(defmodule Type (defmodule Type
(defn = [a b] (defn = [a b]
(match @a (match @a
(None)
(match @b
(None) true
_ false)
(Integer i) (Integer i)
(match @b (match @b
(Integer j) (= i j) (Integer j) (= i j)
@@ -78,6 +83,39 @@ optional arguments.")
(Integer i) (Long.format s i) (Integer i) (Long.format s i)
(Floating f) (Double.format s f) (Floating f) (Double.format s f)
(Str s2) (String.format s &s2))) (Str s2) (String.format s &s2)))
(defn str [t]
(match @t
(Integer i) (str i)
(Floating f) (str f)
(Str s) (str s)))
(defn to-int [x]
(match x
(Integer l) (Long.to-int l)
_ 0))
(defn to-long [x]
(match x
(Integer l) l
_ 0l))
(defn to-str [x]
(match x
(Str s) s
_ @""))
(defn to-float [x]
(match x
(Floating d) (Double.to-float d)
_ 0.0f))
(defn to-double [x]
(match x
(Floating d) d
_ 0.0))
(defn zero [] (None))
) )
(hidden Tag) (hidden Tag)
@@ -97,7 +135,7 @@ optional arguments.")
) )
(doc Option "is the option type. To construct an `Option`, please use (doc Option "is the option type. To construct an `Option`, please use
[`int`](#int), [`float`](#float), or [`str](#str).") [`int`](#int), [`float`](#float), or [`str`](#str).")
(deftype Option [ (deftype Option [
type- Tag type- Tag
long String long String
@@ -109,7 +147,7 @@ optional arguments.")
]) ])
(doc Parser "is the parser type. To construct a `Parser`, please use (doc Parser "is the parser type. To construct a `Parser`, please use
[`new](#new).") [`new`](#new).")
(deftype Parser [ (deftype Parser [
description String description String
options (Array Option) options (Array Option)
@@ -197,7 +235,10 @@ optional arguments.")
(defn to-map [m] (defn to-map [m]
(Array.reduce (Array.reduce
&(fn [a v] (Map.put a (Pair.a (Pair.a v)) (Pair.b (Pair.b v)))) &(fn [a v]
(match @(Pair.b (Pair.b v))
(Maybe.Just e) (Map.put a (Pair.a (Pair.a v)) &e)
(Maybe.Nothing) a))
{} {}
(values m))) (values m)))
) )
@@ -265,7 +306,7 @@ optional arguments.")
(Option.long arg) (Option.short arg) (Option.description arg))) (Option.long arg) (Option.short arg) (Option.description arg)))
(when @(Option.required? arg) (IO.print " REQUIRED")) (when @(Option.required? arg) (IO.print " REQUIRED"))
(when (Maybe.just? (Option.default arg)) (when (Maybe.just? (Option.default arg))
(IO.print &(fmt " (default: %s)" &(Maybe.unsafe-from @(Option.default arg))))) (IO.print &(fmt " (default: %s)" &(str &(Maybe.unsafe-from @(Option.default arg))))))
(match @(Option.options arg) (match @(Option.options arg)
(Maybe.Just o) (Maybe.Just o)
(IO.print &(fmt " (options: %s)" &(join ", " &(Array.copy-map &str &o)))) (IO.print &(fmt " (options: %s)" &(join ", " &(Array.copy-map &str &o))))
@@ -309,6 +350,7 @@ mesage is empty, `--help` was requested. If you dont want to provide a
(do (do
(set! res (Result.Error (fmt "Unexpected argument: %s" x))) (set! res (Result.Error (fmt "Unexpected argument: %s" x)))
(break))))) (break)))))
(when (Result.success? &res)
(foreach [o options] (foreach [o options]
(cond (cond
(and @(Option.required? o) (and @(Option.required? o)
@@ -328,7 +370,7 @@ mesage is empty, `--help` was requested. If you dont want to provide a
&(CmdMap.get &values (Option.long o)) &(CmdMap.get &values (Option.long o))
&(join ", " &(Array.copy-map &str &opts))))) &(join ", " &(Array.copy-map &str &opts)))))
(break)))) (break))))
())) ())))
(match res (match res
(Result.Success _) (Result.Success (CmdMap.to-map &values)) (Result.Success _) (Result.Success (CmdMap.to-map &values))
(Result.Error x) (Result.Error x)))) (Result.Error x) (Result.Error x))))

View File

@@ -30,7 +30,7 @@
</h1> </h1>
<div class="module-description"> <div class="module-description">
<p>is a simple CLI library for Carp.</p> <p>is a simple CLI library for Carp.</p>
<pre><code class="language-clojure">(load &quot;https://veitheller.de/git/carpentry/cli@0.0.1&quot;) <pre><code class="language-clojure">(load &quot;https://veitheller.de/git/carpentry/cli@0.0.2&quot;)
(defn main [] (defn main []
(let [p (=&gt; (CLI.new @&quot;My super cool tool!&quot;) (let [p (=&gt; (CLI.new @&quot;My super cool tool!&quot;)
@@ -42,7 +42,7 @@
(Result.Error msg) (do (IO.errorln &amp;msg) (CLI.usage &amp;p))))) (Result.Error msg) (do (IO.errorln &amp;msg) (CLI.usage &amp;p)))))
</code></pre> </code></pre>
<h2>Installation</h2> <h2>Installation</h2>
<pre><code class="language-clojure">(load &quot;https://veitheller.de/git/carpentry/cli@0.0.1&quot;) <pre><code class="language-clojure">(load &quot;https://veitheller.de/git/carpentry/cli@0.0.2&quot;)
</code></pre> </code></pre>
<h2>Usage</h2> <h2>Usage</h2>
<p><code>CLI</code> should be built using combinators, as in the example above. It has, as of <p><code>CLI</code> should be built using combinators, as in the example above. It has, as of
@@ -61,10 +61,29 @@ manually.</p>
<p>Once youre done building your flag structure, you can run <code>CLI.parse</code>. It <p>Once youre done building your flag structure, you can run <code>CLI.parse</code>. It
will not abort the program on error, instead it will tell you what went wrong will not abort the program on error, instead it will tell you what went wrong
in a <code>Result.Error</code>. If it succeeds, the <code>Result.Success</code> contains a <code>Map</code> from in a <code>Result.Error</code>. If it succeeds, the <code>Result.Success</code> contains a <code>Map</code> from
the long flag name to the value (the values are <code>Maybe</code>s, since they might be the long flag name to the value. The values are not in the map if they are
optional arguments.</p> unset.</p>
</div> </div>
<div class="binder">
<a class="anchor" href="#(defdynamic CLI.*gensym-counter* 1001)">
<h3 id="(defdynamic CLI.*gensym-counter* 1001)">
(defdynamic CLI.*gensym-counter* 1001)
</h3>
</a>
<div class="description">
dynamic
</div>
<p class="sig">
Dynamic
</p>
<span>
</span>
<p class="doc">
</p>
</div>
<div class="binder"> <div class="binder">
<a class="anchor" href="#Option"> <a class="anchor" href="#Option">
<h3 id="Option"> <h3 id="Option">
@@ -82,7 +101,7 @@ optional arguments.</p>
</span> </span>
<p class="doc"> <p class="doc">
<p>is the option type. To construct an <code>Option</code>, please use <p>is the option type. To construct an <code>Option</code>, please use
<a href="#int"><code>int</code></a>, <a href="#float"><code>float</code></a>, or <a href="#str">`str</a>.</p> <a href="#int"><code>int</code></a>, <a href="#float"><code>float</code></a>, or <a href="#str"><code>str</code></a>.</p>
</p> </p>
</div> </div>
@@ -103,7 +122,7 @@ optional arguments.</p>
</span> </span>
<p class="doc"> <p class="doc">
<p>is the parser type. To construct a <code>Parser</code>, please use <p>is the parser type. To construct a <code>Parser</code>, please use
<a href="#new">`new</a>.</p> <a href="#new"><code>new</code></a>.</p>
</p> </p>
</div> </div>
@@ -197,7 +216,7 @@ optional arguments.</p>
defn defn
</div> </div>
<p class="sig"> <p class="sig">
(λ [(Ref Parser)] (Result (Map String (Maybe Type)) String)) (λ [(Ref Parser)] (Result (Map String Type) String))
</p> </p>
<pre class="args"> <pre class="args">
(parse p) (parse p)