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}