#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#[doc = include_str!("../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;
mod argument;
mod fromfile;
#[cfg(feature = "response")]
mod response;
pub use argument::*;
pub use fromfile::*;
#[cfg(feature = "response")]
pub use response::*;
pub const PREFIX: char = '@';
pub fn expand_args<F>(parser: F, prefix: char) -> Result<Vec<std::ffi::OsString>, std::io::Error>
where
F: Fn(&str, char) -> Vec<Argument>,
{
expand_args_from(std::env::args_os(), parser, prefix)
}
pub fn expand_args_from<F>(
args: impl Iterator<Item = std::ffi::OsString>,
parser: F,
prefix: char,
) -> Result<Vec<std::ffi::OsString>, std::io::Error>
where
F: Fn(&str, char) -> Vec<Argument>,
{
use std::collections::VecDeque;
let mut expanded_args = Vec::with_capacity(args.size_hint().0);
let mut todo: VecDeque<_> = args.map(|a| Argument::parse(a, prefix)).collect();
while let Some(next) = todo.pop_front() {
match next {
Argument::PassThrough(arg) => expanded_args.push(arg),
Argument::Path(path) => {
let content = fs_err::read_to_string(path)?;
let new_args = parser(&content, prefix);
todo.reserve(new_args.len());
for (i, arg) in new_args.into_iter().enumerate() {
todo.insert(i, arg);
}
}
}
}
Ok(expanded_args)
}