use getset::{Getters, Setters, WithSetters};
use tap::Pipe;
use crate::os_cmd::{CommandRepr, RunnableCommand, presets::StrVec};
impl<'a> RunnableCommand<'a> for CargoDoc<'a> {}
#[derive(Debug, Clone, WithSetters, Setters, Getters)]
#[getset(set_with = "pub", set = "pub", get = "pub with_prefix")]
pub struct CargoDoc<'a> {
pkg: &'a str,
custom_cfg: &'a str,
nightly: bool,
all_features: bool,
open: bool,
enable_private_items: bool,
extra_args: Box<[&'a str]>,
}
#[macro_export]
macro_rules! ident_value_pair {
($value:ident) => {
(stringify!($value), $value)
};
}
fn concat_tinycfg<'a>(arg_tup: (&str, &'a str)) -> StrVec<'a, 2> {
let (field_name, value) = arg_tup;
let get_arg = || match field_name {
"pkg" => "--package",
_ => "--cfg",
};
match value {
"" => StrVec::new(),
v => [get_arg(), v].into(),
}
}
impl<'a> CargoDoc<'a> {
#[allow(clippy::unnecessary_lazy_evaluations)]
pub fn into_tinyvec(self) -> StrVec<'a, 11> {
let CargoDoc {
pkg,
custom_cfg,
nightly,
all_features,
open,
enable_private_items,
extra_args,
} = self;
"cargo"
.pipe(core::iter::once)
.chain(nightly.then(|| "+nightly"))
.chain(["rustdoc"])
.chain(ident_value_pair!(pkg).pipe(concat_tinycfg))
.chain(all_features.then(|| "--all-features"))
.chain(open.then(|| "--open"))
.chain(["--"])
.chain(ident_value_pair!(custom_cfg).pipe(concat_tinycfg))
.chain(enable_private_items.then(|| "--document-private-items"))
.chain(extra_args)
.collect::<StrVec<11>>()
}
}
impl<'a> From<CargoDoc<'a>> for CommandRepr<'a> {
fn from(value: CargoDoc<'a>) -> Self {
value
.into_tinyvec()
.into_boxed_slice()
.into()
}
}
impl Default for CargoDoc<'_> {
fn default() -> Self {
Self {
nightly: true,
pkg: "",
custom_cfg: "docsrs",
all_features: true,
open: true,
enable_private_items: true,
extra_args: Default::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{get_pkg_name, os_cmd::Runner};
#[test]
#[ignore]
fn test_cargo_doc_cmd() {
let cmd = CargoDoc::default().with_pkg(get_pkg_name!());
assert_eq!(cmd.pkg, "testutils");
assert_eq!(cmd.custom_cfg, "docsrs");
assert!(cmd.nightly);
assert!(cmd.open);
assert!(cmd.enable_private_items);
let cmd_repr: CommandRepr = cmd.into();
let _runner: Runner = cmd_repr.into();
}
#[ignore]
#[test]
fn show_cargo_doc_default() {
CargoDoc::default().pipe(|x| dbg!(x));
}
}