Skip to main content

cliw/
lib.rs

1#![warn(missing_docs)]
2#![allow(clippy::needless_doctest_main)]
3//! # Command line in web.
4//! **Clap in web.**
5//!
6//! Pronounced "Clue" as in "Get a cliw."
7//!
8//! Command line arguments for native and the web.
9//! \
10//! Also provide output for the web.
11//!
12//! The goal is to be flexible, write your command line code once and it should be able to run anywhere!
13//!
14//! # Command Line Arguments
15//! Provides a simple wrapper function [`args_os()`] that returns [`ArgsOs`] from [`std::env::args_os`]
16//! when running on native and [`UrlArgs`] when running on wasm.  This is feature gated with the
17//! "urlargs" feature.
18//!
19//! # Output
20//! Provides writers for output to the web when compiling to wasm and running in a browser.
21//! Also basic [`print(&str)`] and [`eprint(&str)`] functions that use the web or standard output
22//! depending on if compiled to native or wasm.  On native, output is to standard output.  On the
23//! web the output can be to the [console], a pop-up [`alert`], or standard output.
24//! Web output is feature gated with the "console", "alert", and "web-std-output" features.
25//!
26//! # Why use cliw?
27//!
28//! You probably don't want to use [`cliw`] directly.  This crate was designed so [`clap`] can be
29//! used in the web.  You normaly [`use cliw indirectly`] with a web enabled clap, [`we-clap`]
30//! which gives your web page clap powers. (opt parsing, help, suggestions, etc)
31//!
32//! The README with [`recommended usage`] and screenshots is at [`crates.io`], or the [`cliw repository`].
33//! Also check out the [`docs`] and [`examples`], specifically the [`we-clap_demo`] example.
34//!
35//! # Why not use cliw?
36//! * If you are writing only for the web, you may not be wanting to use command line arguments.
37//! * You might have another use of the url query string.
38//! * You might be compiling to wasm but the framework you use provides [`std::env::args_os`]
39//!   and/or standard output.
40//!
41//! # Example `cliw_demo`
42//! As mentioned above, you probably want to [`use cliw indirectly`], with [`we-clap`] but here
43//! is the obligitory [`cliw_demo`] example if you want to use just cliw.
44//! ## Cargo.toml
45//! ```toml
46//!  [package]
47//!  name = "cliw_demo"
48//!  version = "0.1.0"
49//!  edition = "2021"
50//!
51//!  [dependencies]
52//!  cliw = { version = "0.1.0", features = [
53//!      "alert",
54//!      "urlargs",
55//!  ]}
56//! ```
57//! ## main.rs
58//! ```
59//! fn main() {
60//!     // Get the args from CLI on native
61//!     // or the webpage URL on wasm in the browser
62//!     let args = cliw::args_os();
63//!     let args: Vec<_> = args.collect();
64//!     let msg = format!("{:?}", args);
65//!     // Output to standard on native
66//!     // or web popup alert on wasm in the browser
67//!     cliw::output::print(&msg);
68//! }
69//! ```
70//! ## Running on native.
71//! ```console
72//! $ cargo r -- arg1 arg2 ar3
73//!     Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
74//!      Running `/path/to/target/debug/cliw_demo arg1 arg2 ar3`
75//! ["/path/to/target/debug/cliw_demo", "arg1", "arg2", "ar3"]
76//! ```
77//! ## Running on the web with "alert" and "urlargs" features.
78//! ```console
79//! $ cargo r --target wasm32-unknown-unknown
80//!     Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.44s
81//!      Running `wasm-server-runner /path/to/target/wasm32-unknown-unknown/debug/cliw_demo.wasm`
82//!  INFO wasm_server_runner: uncompressed wasm output is 189.62kb in size
83//!  INFO wasm_server_runner: starting webserver at http://127.0.0.1:1334
84//! ```
85//!  Pointing your browser to
86//!  ```console
87//!  http://127.0.0.1:1334/?arg1&arg2&and&whatever
88//!  ```
89//!  you would get a popup alert with the following text.
90//!  ```console
91//!  ["http://127.0.0.1:1334/", "arg1", "arg2", "and", "whatever"]
92//!  ```
93//!
94//! # Features
95//!
96//! The functionality of the cliw crate is gated by features.
97//!
98//! * "alert"            :     Enable output to browser popup alert.
99//! * "console"          :     Enable output to browser console.
100//! * "web-std-output"   :     Enable standard output on the web.  You can use this if your web
101//!   framework provides standard output.  You always get standard output on native
102//! * "urlargs"          :     Enable getting args from [`UrlArgs`] on the web.  Do not use this if
103//!   your web framework provides [`std::env::args_os`].
104//!
105//!  For simplicity just set the "urlargs" and "console" or "alert" features in you Cargo.toml for
106//!  both native and wasm.  Under native you always get standard args and output.
107//!  ```toml
108//!  cliw = { version = "0.1.0", features = [
109//!      "alert",
110//!      "urlargs",
111//!  ]}
112//!  ```
113//!
114//! [`args_os()`]: args_os
115//! [`ArgsOs`]: std::env::ArgsOs
116//! [console]: https://developer.mozilla.org/en-US/docs/Web/API/console
117//! [`alert`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/alert
118//! [`print(&str)`]: output::print
119//! [`eprint(&str)`]: output::eprint
120//! [`cliw`]: crate
121//! [`cliw_demo`]: https://github.com/stonerfish/cliw_examples/cliw_demo
122//! [`docs`]: https://docs.rs/cliw
123//! [`examples`]: https://github.com/stonerfish/cliw_examples
124//! [`cliw repository`]: https://github.com/stonerfish/cliw/
125//! [`crates.io`]: https://crates.io/crates/cliw/
126//! [`clap`]: https://crates.io/crates/clap/
127//! [`recommended usage`]: https://crates.io/crates/cliw/#recommended-usage
128//! [`UrlArgs`]: url_args::UrlArgs
129//! [`use cliw indirectly`]: https://github.com/stonerfish/cliw_examples/we-clap_demos/we-clap_demo
130//! [`web enabled clap`]: https://github.com/stonerfish/clap/tree/we-clap
131//! [`we-clap`]: https://github.com/stonerfish/clap/tree/we-clap
132//! [`we-clap_demo`]: https://github.com/stonerfish/cliw_examples/we-clap_demos/we-clap_demo
133
134pub mod output;
135pub mod url_args;
136
137/// Return [`ArgsOs`] from [`env::args_os`] on native or [`UrlArgs`] on wasm
138///
139/// This function is feature gated.  To enable getting [`UrlArgs`] on wasm
140/// you must enable the "urlargs" feature.
141/// ## Example
142/// ```rust
143///     let args_iter = cliw::args_os();
144/// ```
145///
146/// [`ArgsOs`]: std::env::ArgsOs
147/// [`env::args_os`]: std::env::args_os
148/// [`UrlArgs`]: url_args::UrlArgs
149pub fn args_os() -> impl Iterator<Item = std::ffi::OsString> {
150    #[cfg(not(all(target_arch = "wasm32", feature = "urlargs")))]
151    {
152        std::env::args_os()
153    }
154
155    #[cfg(all(target_arch = "wasm32", feature = "urlargs"))]
156    {
157        crate::url_args::UrlArgs::new()
158    }
159}