aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Walbran <qwandor@google.com>2022-01-21 13:09:51 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-01-21 13:09:51 +0000
commit12420bc5779524e68c651bf118d70f2989d13999 (patch)
treefc8f622bc356dba116f5665acf523c2b5e20f303
parent5dcbbb6c33ede2f6ca1d29ac6e75644c28d075d2 (diff)
parentd68b68e34fd1c3275fa57850a7888aaaf8fe3e16 (diff)
downloadargh_shared-12420bc5779524e68c651bf118d70f2989d13999.tar.gz
Initial import. am: 6c7113ea11 am: d68b68e34f
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/argh_shared/+/1955042 Change-Id: Ia935b701d7b9052883170cbcace94fdf30a01eb9
-rw-r--r--.cargo_vcs_info.json6
-rw-r--r--Android.bp18
-rw-r--r--Cargo.toml20
-rw-r--r--Cargo.toml.orig9
-rw-r--r--LICENSE27
-rw-r--r--METADATA19
-rw-r--r--MODULE_LICENSE_BSD_LIKE0
-rw-r--r--OWNERS1
-rw-r--r--README.md177
-rw-r--r--cargo2android.json9
-rw-r--r--src/lib.rs80
11 files changed, 366 insertions, 0 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..116e262
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+ "git": {
+ "sha1": "f1f85d2d89cbe09314dc1b59e581b8a43531cf3e"
+ },
+ "path_in_vcs": "argh_shared"
+} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..3d05aa8
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,18 @@
+// This file is generated by cargo2android.py --config cargo2android.json.
+// Do not modify this file as changes will be overridden on upgrade.
+
+
+
+rust_library {
+ name: "libargh_shared",
+ host_supported: true,
+ crate_name: "argh_shared",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.1.7",
+ srcs: ["src/lib.rs"],
+ edition: "2018",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.virt",
+ ],
+}
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..d54a07f
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,20 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "argh_shared"
+version = "0.1.7"
+authors = ["Taylor Cramer <cramertj@google.com>", "Benjamin Brittain <bwb@google.com>", "Erick Tryzelaar <etryzelaar@google.com>"]
+description = "Derive-based argument parsing optimized for code size"
+readme = "README.md"
+license = "BSD-3-Clause"
+repository = "https://github.com/google/argh"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..1f7e694
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,9 @@
+[package]
+name = "argh_shared"
+version = "0.1.7"
+authors = ["Taylor Cramer <cramertj@google.com>", "Benjamin Brittain <bwb@google.com>", "Erick Tryzelaar <etryzelaar@google.com>"]
+edition = "2018"
+license = "BSD-3-Clause"
+description = "Derive-based argument parsing optimized for code size"
+repository = "https://github.com/google/argh"
+readme = "README.md"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..87f152c
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2019 The Fuchsia Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..e3c64c5
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,19 @@
+name: "argh_shared"
+description: "Derive-based argument parsing optimized for code size"
+third_party {
+ url {
+ type: HOMEPAGE
+ value: "https://crates.io/crates/argh_shared"
+ }
+ url {
+ type: ARCHIVE
+ value: "https://static.crates.io/crates/argh_shared/argh_shared-0.1.7.crate"
+ }
+ version: "0.1.7"
+ license_type: NOTICE
+ last_upgrade_date {
+ year: 2022
+ month: 1
+ day: 13
+ }
+}
diff --git a/MODULE_LICENSE_BSD_LIKE b/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD_LIKE
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..45dc4dd
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:master:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4e949e4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,177 @@
+# Argh
+**Argh is an opinionated Derive-based argument parser optimized for code size**
+
+[![crates.io](https://img.shields.io/crates/v/argh.svg)](https://crates.io/crates/argh)
+[![license](https://img.shields.io/badge/license-BSD3.0-blue.svg)](https://github.com/google/argh/LICENSE)
+[![docs.rs](https://docs.rs/argh/badge.svg)](https://docs.rs/crate/argh/)
+![Argh](https://github.com/google/argh/workflows/Argh/badge.svg)
+
+Derive-based argument parsing optimized for code size and conformance
+to the Fuchsia commandline tools specification
+
+The public API of this library consists primarily of the `FromArgs`
+derive and the `from_env` function, which can be used to produce
+a top-level `FromArgs` type from the current program's commandline
+arguments.
+
+## Basic Example
+
+```rust,no_run
+use argh::FromArgs;
+
+#[derive(FromArgs)]
+/// Reach new heights.
+struct GoUp {
+ /// whether or not to jump
+ #[argh(switch, short = 'j')]
+ jump: bool,
+
+ /// how high to go
+ #[argh(option)]
+ height: usize,
+
+ /// an optional nickname for the pilot
+ #[argh(option)]
+ pilot_nickname: Option<String>,
+}
+
+fn main() {
+ let up: GoUp = argh::from_env();
+}
+```
+
+`./some_bin --help` will then output the following:
+
+```
+Usage: cmdname [-j] --height <height> [--pilot-nickname <pilot-nickname>]
+
+Reach new heights.
+
+Options:
+ -j, --jump whether or not to jump
+ --height how high to go
+ --pilot-nickname an optional nickname for the pilot
+ --help display usage information
+```
+
+The resulting program can then be used in any of these ways:
+- `./some_bin --height 5`
+- `./some_bin -j --height 5`
+- `./some_bin --jump --height 5 --pilot-nickname Wes`
+
+Switches, like `jump`, are optional and will be set to true if provided.
+
+Options, like `height` and `pilot_nickname`, can be either required,
+optional, or repeating, depending on whether they are contained in an
+`Option` or a `Vec`. Default values can be provided using the
+`#[argh(default = "<your_code_here>")]` attribute, and in this case an
+option is treated as optional.
+
+```rust
+use argh::FromArgs;
+
+fn default_height() -> usize {
+ 5
+}
+
+#[derive(FromArgs)]
+/// Reach new heights.
+struct GoUp {
+ /// an optional nickname for the pilot
+ #[argh(option)]
+ pilot_nickname: Option<String>,
+
+ /// an optional height
+ #[argh(option, default = "default_height()")]
+ height: usize,
+
+ /// an optional direction which is "up" by default
+ #[argh(option, default = "String::from(\"only up\")")]
+ direction: String,
+}
+
+fn main() {
+ let up: GoUp = argh::from_env();
+}
+```
+
+Custom option types can be deserialized so long as they implement the
+`FromArgValue` trait (automatically implemented for all `FromStr` types).
+If more customized parsing is required, you can supply a custom
+`fn(&str) -> Result<T, String>` using the `from_str_fn` attribute:
+
+```rust
+use argh::FromArgs;
+
+#[derive(FromArgs)]
+/// Goofy thing.
+struct FiveStruct {
+ /// always five
+ #[argh(option, from_str_fn(always_five))]
+ five: usize,
+}
+
+fn always_five(_value: &str) -> Result<usize, String> {
+ Ok(5)
+}
+```
+
+Positional arguments can be declared using `#[argh(positional)]`.
+These arguments will be parsed in order of their declaration in
+the structure:
+
+```rust
+use argh::FromArgs;
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// A command with positional arguments.
+struct WithPositional {
+ #[argh(positional)]
+ first: String,
+}
+```
+
+The last positional argument may include a default, or be wrapped in
+`Option` or `Vec` to indicate an optional or repeating positional argument.
+
+Subcommands are also supported. To use a subcommand, declare a separate
+`FromArgs` type for each subcommand as well as an enum that cases
+over each command:
+
+```rust
+use argh::FromArgs;
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// Top-level command.
+struct TopLevel {
+ #[argh(subcommand)]
+ nested: MySubCommandEnum,
+}
+
+#[derive(FromArgs, PartialEq, Debug)]
+#[argh(subcommand)]
+enum MySubCommandEnum {
+ One(SubCommandOne),
+ Two(SubCommandTwo),
+}
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// First subcommand.
+#[argh(subcommand, name = "one")]
+struct SubCommandOne {
+ #[argh(option)]
+ /// how many x
+ x: usize,
+}
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// Second subcommand.
+#[argh(subcommand, name = "two")]
+struct SubCommandTwo {
+ #[argh(switch)]
+ /// whether to fooey
+ fooey: bool,
+}
+```
+
+NOTE: This is not an officially supported Google product.
diff --git a/cargo2android.json b/cargo2android.json
new file mode 100644
index 0000000..6e516e0
--- /dev/null
+++ b/cargo2android.json
@@ -0,0 +1,9 @@
+{
+ "apex-available": [
+ "//apex_available:platform",
+ "com.android.virt"
+ ],
+ "device": true,
+ "run": true,
+ "tests": true
+} \ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..c6e7a5c
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,80 @@
+// Copyright (c) 2020 Google LLC All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//! Shared functionality between argh_derive and the argh runtime.
+//!
+//! This library is intended only for internal use by these two crates.
+
+/// Information about a particular command used for output.
+pub struct CommandInfo<'a> {
+ /// The name of the command.
+ pub name: &'a str,
+ /// A short description of the command's functionality.
+ pub description: &'a str,
+}
+
+pub const INDENT: &str = " ";
+const DESCRIPTION_INDENT: usize = 20;
+const WRAP_WIDTH: usize = 80;
+
+/// Write command names and descriptions to an output string.
+pub fn write_description(out: &mut String, cmd: &CommandInfo<'_>) {
+ let mut current_line = INDENT.to_string();
+ current_line.push_str(cmd.name);
+
+ if cmd.description.is_empty() {
+ new_line(&mut current_line, out);
+ return;
+ }
+
+ if !indent_description(&mut current_line) {
+ // Start the description on a new line if the flag names already
+ // add up to more than DESCRIPTION_INDENT.
+ new_line(&mut current_line, out);
+ }
+
+ let mut words = cmd.description.split(' ').peekable();
+ while let Some(first_word) = words.next() {
+ indent_description(&mut current_line);
+ current_line.push_str(first_word);
+
+ 'inner: while let Some(&word) = words.peek() {
+ if (char_len(&current_line) + char_len(word) + 1) > WRAP_WIDTH {
+ new_line(&mut current_line, out);
+ break 'inner;
+ } else {
+ // advance the iterator
+ let _ = words.next();
+ current_line.push(' ');
+ current_line.push_str(word);
+ }
+ }
+ }
+ new_line(&mut current_line, out);
+}
+
+// Indent the current line in to DESCRIPTION_INDENT chars.
+// Returns a boolean indicating whether or not spacing was added.
+fn indent_description(line: &mut String) -> bool {
+ let cur_len = char_len(line);
+ if cur_len < DESCRIPTION_INDENT {
+ let num_spaces = DESCRIPTION_INDENT - cur_len;
+ line.extend(std::iter::repeat(' ').take(num_spaces));
+ true
+ } else {
+ false
+ }
+}
+
+fn char_len(s: &str) -> usize {
+ s.chars().count()
+}
+
+// Append a newline and the current line to the output,
+// clearing the current line.
+fn new_line(current_line: &mut String, out: &mut String) {
+ out.push('\n');
+ out.push_str(current_line);
+ current_line.truncate(0);
+}