-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9866c86
Showing
248 changed files
with
50,236 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content=" "><title>bpaf::_documentation::_0_intro - Rust</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../static.files/FiraSans-Regular-018c141bf0843ffd.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../static.files/FiraSans-Medium-8f9a781e4970d388.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2"><link rel="stylesheet" href="../../../static.files/normalize-76eba96aa4d2e634.css"><link rel="stylesheet" href="../../../static.files/rustdoc-ac92e1bbe349e143.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="bpaf" data-themes="" data-resource-suffix="" data-rustdoc-version="1.76.0 (07dca489a 2024-02-04)" data-channel="1.76.0" data-search-js="search-2b6ce74ff89ae146.js" data-settings-js="settings-4313503d2e1961c2.js" ><script src="../../../static.files/storage-f2adc0d6ca4d09fb.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../../static.files/main-305769736d49e732.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-feafe1bb7466e4bd.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-16x16-8b506e7a72182f1c.png"><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-422f7d1d52889060.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-2c020d218678b618.svg"></head><body class="rustdoc mod"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="mobile-topbar"><button class="sidebar-menu-toggle">☰</button></nav><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../../bpaf/index.html">bpaf</a><span class="version">0.9.10</span></h2></div><h2 class="location"><a href="#">Module _0_intro</a></h2><div class="sidebar-elems"><h2><a href="../index.html">In bpaf::_documentation</a></h2></div></nav><div class="sidebar-resizer"></div> | ||
<main><div class="width-limiter"><nav class="sub"><form class="search-form"><span></span><div id="sidebar-button" tabindex="-1"><a href="../../../bpaf/all.html" title="show sidebar"></a></div><input class="search-input" name="search" aria-label="Run search in the documentation" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" tabindex="-1"><a href="../../../help.html" title="help">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../static.files/wheel-7b819b6101059cd0.svg"></a></div></form></nav><section id="main-content" class="content"><div class="main-heading"><h1>Module <a href="../../index.html">bpaf</a>::<wbr><a href="../index.html">_documentation</a>::<wbr><a class="mod" href="#">_0_intro</a><button id="copy-path" title="Copy item path to clipboard"><img src="../../../static.files/clipboard-7571035ce49a181d.svg" width="19" height="18" alt="Copy item path"></button></h1><span class="out-of-band"><a class="src" href="../../../src/bpaf/_documentation.rs.html#11">source</a> · <button id="toggle-all-docs" title="collapse all docs">[<span>−</span>]</button></span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p> </p> | ||
<table width='100%' cellspacing='0' style='border: hidden;'><tr> | ||
<td style='width: 33%; text-align: left;'> | ||
</td> | ||
<td style='width: 34%; text-align: center;'> | ||
<p><a href="../index.html" title="mod bpaf::_documentation">↑ Project documentation ↑</a></p> | ||
</td> | ||
<td style='width: 33%; text-align: right;'> | ||
<p><a href="../_1_tutorials/index.html" title="mod bpaf::_documentation::_1_tutorials">Tutorials →</a></p> | ||
</td> | ||
</tr></table> | ||
<h5 id="introduction-and-design-goals"><a href="#introduction-and-design-goals">Introduction and design goals</a></h5> | ||
<p>A quick intro. What, why and how</p> | ||
<p><code>bpaf</code> is a lightweight and flexible command line parser that uses both combinatoric and derive | ||
style API</p> | ||
<p>Combinatoric API usually means a bit more typing but no dependency on proc macros and more help | ||
from the IDE, derive API uses proc macro to save on typing but your IDE will be less likely to | ||
help you. Picking one API style does not lock you out from using the other style, you can mix | ||
and match both in a single parser</p> | ||
<h2 id="examples-of-both-styles"><a href="#examples-of-both-styles">Examples of both styles</a></h2><details><summary>Combinatoric example</summary> | ||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>bpaf::<span class="kw-2">*</span>; | ||
|
||
<span class="attr">#[derive(Debug, Clone)] | ||
</span><span class="kw">pub struct </span>Options { | ||
message: String, | ||
} | ||
|
||
<span class="kw">pub fn </span>options() -> OptionParser<Options> { | ||
<span class="kw">let </span>message = positional(<span class="string">"MESSAGE"</span>).help(<span class="string">"Message to print in a big friendly letters"</span>); | ||
<span class="macro">construct!</span>(Options { message }).to_options() | ||
} | ||
|
||
<span class="kw">fn </span>main() { | ||
<span class="macro">println!</span>(<span class="string">"{:?}"</span>, options().run()) | ||
}</code></pre></div> | ||
</details> | ||
<details><summary>Derive example</summary> | ||
|
||
<div class="example-wrap"><pre class="rust rust-example-rendered"><code><span class="kw">use </span>bpaf::<span class="kw-2">*</span>; | ||
|
||
<span class="attr">#[derive(Debug, Clone, Bpaf)] | ||
#[bpaf(options)] | ||
</span><span class="kw">pub struct </span>Options { | ||
<span class="doccomment">/// Message to print in a big friendly letters | ||
</span><span class="attr">#[bpaf(positional(<span class="string">"MESSAGE"</span>))] | ||
</span>message: String, | ||
} | ||
|
||
<span class="kw">fn </span>main() { | ||
<span class="macro">println!</span>(<span class="string">"{:?}"</span>, options().run()) | ||
}</code></pre></div> | ||
</details> | ||
<details><summary>Output</summary> | ||
<p>With everything in place users should be able to pass their arguments</p> | ||
<div class='bpaf-doc'> | ||
$ app "Hello world"<br> | ||
Options { message: "Hello world" } | ||
</div> | ||
<p>As well as read the help message generated by the library</p> | ||
<div class='bpaf-doc'> | ||
$ app --help<br> | ||
<p><b>Usage</b>: <tt><b>app</b></tt> <tt><i>MESSAGE</i></tt></p><p><div> | ||
<b>Available positional items:</b></div><dl><dt><tt><i>MESSAGE</i></tt></dt> | ||
<dd>Message to print in a big friendly letters</dd> | ||
</dl> | ||
</p><p><div> | ||
<b>Available options:</b></div><dl><dt><tt><b>-h</b></tt>, <tt><b>--help</b></tt></dt> | ||
<dd>Prints help information</dd> | ||
</dl> | ||
</p> | ||
<style> | ||
div.bpaf-doc { | ||
padding: 14px; | ||
background-color:var(--code-block-background-color); | ||
font-family: "Source Code Pro", monospace; | ||
margin-bottom: 0.75em; | ||
} | ||
div.bpaf-doc dt { margin-left: 1em; } | ||
div.bpaf-doc dd { margin-left: 3em; } | ||
div.bpaf-doc dl { margin-top: 0; padding-left: 1em; } | ||
div.bpaf-doc { padding-left: 1em; } | ||
</style> | ||
</div> | ||
</details> | ||
<h2 id="design-goals"><a href="#design-goals">Design goals</a></h2><h3 id="parse-dont-validate"><a href="#parse-dont-validate">Parse, don’t validate</a></h3> | ||
<p><code>bpaf</code> tries hard to let you move as many invariants about the user input you are | ||
trying to parse into rust types: for mutually exclusive options you can get <code>enum</code> with | ||
exclusive items going into separate branches, and you can collect results into types like | ||
<a href="https://doc.rust-lang.org/1.76.0/alloc/collections/btree/set/struct.BTreeSet.html" title="struct alloc::collections::btree::set::BTreeSet"><code>BTreeSet</code></a>, or whatever custom type you might have with | ||
custom parsing. Ideas for | ||
<a href="https://geeklaunch.io/blog/make-invalid-states-unrepresentable/">making invalid states unrepresentable</a> | ||
and <a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/">using parsing over validation</a> | ||
are not new.</p> | ||
<p>That said you can also validate your inputs if this fits your situation better. If you want to | ||
ensure that the sum of every numeric field must be divisible by both 3 and 5, but only when it’s | ||
Thursday - you can do that too.</p> | ||
<h3 id="flexibility"><a href="#flexibility">Flexibility</a></h3> | ||
<p>While aiming to be a general-purpose command line parser <code>bpaf</code> offers a few backdoors that | ||
allow you to parse pretty much anything you want: chained commands, custom blocks of options, | ||
DOS-style options (<code>/ofile.pas</code>), <code>dd</code> style options (<code>if=file of=out</code>), etc. A similar idea applies | ||
to what the parser can produce - if your app operates with boxed string slices internally - <code>bpaf</code> | ||
will give you <code>Box<str></code> instead of <code>String</code> if you ask it to.</p> | ||
<p>The only restriction is that you cannot use information from items parsed earlier (but not | ||
the fact that something was parsed successfully or not) to decide to how to parse further | ||
options, and even then you can side step this restriction by passing some shared state as a | ||
parameter to the parsers.</p> | ||
<h3 id="reusability"><a href="#reusability">Reusability</a></h3> | ||
<p>Parsers in <code>bpaf</code> are not monolithic and you can share their parts across multiple binaries, | ||
workspace members or even independent projects. Say you have multiple binaries in a workspace | ||
that perform different operations on some input. You can declare a parser for the input | ||
specifically, along with all the validations, help messages or shell dynamic completion | ||
functions you need and use it across all the binaries alongside the arguments specific to | ||
those binaries.</p> | ||
<h3 id="composition-transformation"><a href="#composition-transformation">Composition, transformation</a></h3> | ||
<p>Parsers in <code>bpaf</code> are not finalized either, say you have a parser that describes a single input | ||
for your program, it can take multiple arguments or perform extra validations, etc. You can | ||
always compose this parser with any other parser to produce tuples of both results for example. | ||
Or to make it so parser runs multiple times and collects results into a <code>Vec</code>.</p> | ||
<h3 id="performance"><a href="#performance">Performance</a></h3> | ||
<p>While performance is an explicit non-goal - <code>bpaf</code> does nothing that would pessimize it either, | ||
so performance is on par or better compared to other fully featured parsers.</p> | ||
<h3 id="correctness"><a href="#correctness">Correctness</a></h3> | ||
<p><code>bpaf</code> would parse only items it can represent and will reject anything it cannot represent | ||
in the output. Say your parser accepts both <code>--intel</code> and <code>--att</code> flags, but encodes the result | ||
into <code>enum Style { Intel, Att }</code>, <code>bpaf</code> will accept those flags separately, but not if they | ||
are used both at once. If the parser later collects multiple styles into a <code>Vec<Style></code> then it | ||
will accept any combinationof those flags.</p> | ||
<h3 id="user-friendly"><a href="#user-friendly">User friendly</a></h3> | ||
<p><code>bpaf</code> tries to provide user-friendly error messages, and suggestions for typos but also scripts | ||
for shell completion, <code>man</code> pages and markdown documentation for the web.</p> | ||
<p> </p> | ||
<table width='100%' cellspacing='0' style='border: hidden;'><tr> | ||
<td style='width: 33%; text-align: left;'> | ||
</td> | ||
<td style='width: 34%; text-align: center;'> | ||
<p><a href="../index.html" title="mod bpaf::_documentation">↑ Project documentation ↑</a></p> | ||
</td> | ||
<td style='width: 33%; text-align: right;'> | ||
<p><a href="../_1_tutorials/index.html" title="mod bpaf::_documentation::_1_tutorials">Tutorials →</a></p> | ||
</td> | ||
</tr></table> | ||
</div></details></section></div></main></body></html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
window.SIDEBAR_ITEMS = {}; |
Oops, something went wrong.