{"id":15616772,"url":"https://github.com/thepacketgeek/clap-stdin","last_synced_at":"2025-04-09T09:04:50.571Z","repository":{"id":156551682,"uuid":"626538367","full_name":"thepacketgeek/clap-stdin","owner":"thepacketgeek","description":null,"archived":false,"fork":false,"pushed_at":"2025-01-20T23:01:18.000Z","size":37,"stargazers_count":21,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T07:42:01.728Z","etag":null,"topics":["clap","cli"],"latest_commit_sha":null,"homepage":"https://docs.rs/clap-stdin/latest","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thepacketgeek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-11T17:05:44.000Z","updated_at":"2025-03-11T18:18:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"4f03ca6e-9111-4063-b344-41a8445fcbd1","html_url":"https://github.com/thepacketgeek/clap-stdin","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepacketgeek%2Fclap-stdin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepacketgeek%2Fclap-stdin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepacketgeek%2Fclap-stdin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepacketgeek%2Fclap-stdin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thepacketgeek","download_url":"https://codeload.github.com/thepacketgeek/clap-stdin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248008631,"owners_count":21032556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clap","cli"],"created_at":"2024-10-03T07:21:58.578Z","updated_at":"2025-04-09T09:04:50.555Z","avatar_url":"https://github.com/thepacketgeek.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# clap-stdin [![Build](https://img.shields.io/github/actions/workflow/status/thepacketgeek/clap-stdin/ci-build.yml?branch=main)](https://github.com/thepacketgeek/clap-stdin/actions/workflows/ci-build.yml)\n\nThis library offers two wrapper types for [`clap`](https://docs.rs/clap) `Arg`s that help\nfor cases where values may be passed in via `stdin`. When an `Arg` value is to be read\nfrom `stdin`, the user will pass the commonly used `stdin` alias: `-`\n\n- `MaybeStdin`: Used when a value can be passed in via args OR `stdin`\n- `FileOrStdin`: Used when a value can be read in from a file OR `stdin`\n\n## `MaybeStdin`\n\nExample usage with `clap`'s `derive` feature for a positional argument:\n```rust,no_run\nuse clap::Parser;\n\nuse clap_stdin::MaybeStdin;\n\n#[derive(Debug, Parser)]\nstruct Args {\n    value: MaybeStdin\u003cString\u003e,\n}\n\nlet args = Args::parse();\nprintln!(\"value={}\", args.value);\n```\n\nCalling this CLI:\n```sh\n# using stdin for positional arg value\n$ echo \"testing\" | cargo run -- -\nvalue=testing\n```\n\n## Compatible Types\n[`MaybeStdin`] can wrap any type that matches the trait bounds for `Arg`: `FromStr` and `Clone`\n```rust\nuse std::path::PathBuf;\nuse clap::Parser;\nuse clap_stdin::MaybeStdin;\n\n#[derive(Debug, Parser)]\nstruct Args {\n    path: MaybeStdin\u003cPathBuf\u003e,\n}\n```\n\n```sh\n$ pwd | ./example -\n```\n\n## `FileOrStdin`\n\nExample usage with `clap`'s `derive` feature for a positional argument:\n```rust,no_run\nuse clap::Parser;\n\nuse clap_stdin::FileOrStdin;\n\n#[derive(Debug, Parser)]\nstruct Args {\n    input: FileOrStdin,\n}\n\n# fn main() -\u003e anyhow::Result\u003c()\u003e {\nlet args = Args::parse();\nprintln!(\"input={}\", args.input.contents()?);\n# Ok(())\n# }\n```\n\nCalling this CLI:\n```sh\n# using stdin for positional arg value\n$ echo \"testing\" | cargo run -- -\ninput=testing\n\n# using filename for positional arg value\n$ echo \"testing\" \u003e input.txt\n$ cargo run -- input.txt\ninput=testing\n```\n\n## Compatible Types\n[`FileOrStdin`] can wrap any type that matches the trait bounds for `Arg`: `FromStr` and `Clone`\n```rust\nuse clap::Parser;\nuse clap_stdin::FileOrStdin;\n\n#[derive(Debug, Parser)]\nstruct Args {\n    path: FileOrStdin\u003cu32\u003e,\n}\n```\n\n```sh\n# Value from stdin\n$ wc ~/myfile.txt -l | ./example -\n\n# Value from file\n$ cat myfile.txt\n42\n$ .example myfile.txt\n```\n\n## Reading from Stdin without special characters\nWhen using [`MaybeStdin`] or [`FileOrStdin`], you can allow your users to omit the \"-\" character to read from `stdin` by providing a `default_value` to clap.\n\n**NOTE:** This only works with positional args, since clap requires optional args (E.g. using #[arg(long, short)]) to have a value to parse.\n\n```rust,no_run\nuse clap::Parser;\n\nuse clap_stdin::FileOrStdin;\n\n#[derive(Debug, Parser)]\nstruct Args {\n    #[arg(default_value = \"-\")]\n    input: FileOrStdin,\n}\n\n# fn main() -\u003e anyhow::Result\u003c()\u003e {\nlet args = Args::parse();\nprintln!(\"input={}\", args.input.contents()?);\n# Ok(())\n# }\n```\n\nCalling this CLI:\n```sh\n# using stdin for positional arg value\n$ echo \"testing\" | cargo run\ninput=testing\n\n# using filename for positional arg value\n$ echo \"testing\" \u003e input.txt\n$ cargo run -- input.txt\ninput=testing\n```\n\n## Async Support\n`FileOrStdin` can also be used with [`tokio::io::AsyncRead`](https://docs.rs/tokio/latest/tokio/io/trait.AsyncRead.html) using the `tokio` feature. See [`FileOrStdin::contents_async`] and [`FileOrStdin::into_async_reader`] for examples.\n\n# Using `MaybeStdin` or `FileOrStdin` multiple times\nBoth [`MaybeStdin`] and [`FileOrStdin`] will check at runtime if `stdin` is being read from multiple times. You can use this\nas a feature if you have mutually exclusive args that should both be able to read from stdin, but know\nthat the user will receive an error if 2+ `MaybeStdin` args receive the \"-\" value.\n\nFor example, this compiles:\n```rust\nuse clap_stdin::{FileOrStdin, MaybeStdin};\n\n#[derive(Debug, clap::Parser)]\nstruct Args {\n    first: FileOrStdin,\n    second: MaybeStdin\u003cu32\u003e,\n}\n```\n\nand it will work fine if the stdin alias `-` is only passed for one of the arguments:\n```sh\n$ echo \"2\" | ./example FIRST -\n```\n\nBut if `stdin` is attempted to be used for both arguments, there will be no value for the `second` arg\n```sh\n$ echo \"2\" | ./example - -\nerror: invalid value '-' for '\u003cSECOND\u003e': stdin argument used more than once\n```\n\n# License\n\n`clap-stdin` is both MIT and Apache License, Version 2.0 licensed, as found\nin the LICENSE-MIT and LICENSE-APACHE files.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepacketgeek%2Fclap-stdin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthepacketgeek%2Fclap-stdin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepacketgeek%2Fclap-stdin/lists"}