argh_shared-0.1.9/.cargo_vcs_info.json0000644000000001510000000000100133070ustar { "git": { "sha1": "adc704cd29f710864b0fc1872bc86f857bebfdbf" }, "path_in_vcs": "argh_shared" }argh_shared-0.1.9/Cargo.toml0000644000000015110000000000100113060ustar # 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.9" authors = [ "Taylor Cramer ", "Benjamin Brittain ", "Erick Tryzelaar ", ] description = "Derive-based argument parsing optimized for code size" readme = "README.md" license = "BSD-3-Clause" repository = "https://github.com/google/argh" argh_shared-0.1.9/Cargo.toml.orig000064400000000000000000000005471046102023000147770ustar 00000000000000[package] name = "argh_shared" version = "0.1.9" authors = ["Taylor Cramer ", "Benjamin Brittain ", "Erick Tryzelaar "] edition = "2018" license = "BSD-3-Clause" description = "Derive-based argument parsing optimized for code size" repository = "https://github.com/google/argh" readme = "README.md" argh_shared-0.1.9/LICENSE000064400000000000000000000027101046102023000131070ustar 00000000000000Copyright 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. argh_shared-0.1.9/README.md000064400000000000000000000116311046102023000133630ustar 00000000000000# 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, } fn main() { let up: GoUp = argh::from_env(); } ``` `./some_bin --help` will then output the following: ``` Usage: cmdname [-j] --height [--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 = "")]` 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, /// 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` 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 { 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. ## How to debug the expanded derive macro for `argh` The `argh::FromArgs` derive macro can be debugged with the [cargo-expand](https://crates.io/crates/cargo-expand) crate. ### Expand the derive macro in `examples/simple_example.rs` See [argh/examples/simple_example.rs](./argh/examples/simple_example.rs) for the example struct we wish to expand. First, install `cargo-expand` by running `cargo install cargo-expand`. Note this requires the nightly build of Rust. Once installed, run `cargo expand` with in the `argh` package and you can see the expanded code. argh_shared-0.1.9/src/lib.rs000064400000000000000000000047571046102023000140220ustar 00000000000000// 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(¤t_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); }