use crate::builder::IntoResettable;
use crate::util::Id;
#[derive(Default, Clone, Debug, PartialEq, Eq)]
pub struct ArgGroup {
pub(crate) id: Id,
pub(crate) args: Vec<Id>,
pub(crate) required: bool,
pub(crate) requires: Vec<Id>,
pub(crate) conflicts: Vec<Id>,
pub(crate) multiple: bool,
}
impl ArgGroup {
pub fn new(id: impl Into<Id>) -> Self {
ArgGroup::default().id(id)
}
#[must_use]
pub fn id(mut self, id: impl Into<Id>) -> Self {
self.id = id.into();
self
}
#[must_use]
pub fn arg(mut self, arg_id: impl IntoResettable<Id>) -> Self {
if let Some(arg_id) = arg_id.into_resettable().into_option() {
self.args.push(arg_id);
} else {
self.args.clear();
}
self
}
#[must_use]
pub fn args(mut self, ns: impl IntoIterator<Item = impl Into<Id>>) -> Self {
for n in ns {
self = self.arg(n);
}
self
}
#[inline]
#[must_use]
pub fn multiple(mut self, yes: bool) -> Self {
self.multiple = yes;
self
}
#[inline]
#[must_use]
pub fn required(mut self, yes: bool) -> Self {
self.required = yes;
self
}
#[must_use]
pub fn requires(mut self, id: impl IntoResettable<Id>) -> Self {
if let Some(id) = id.into_resettable().into_option() {
self.requires.push(id);
} else {
self.requires.clear();
}
self
}
#[must_use]
pub fn requires_all(mut self, ns: impl IntoIterator<Item = impl Into<Id>>) -> Self {
for n in ns {
self = self.requires(n);
}
self
}
#[must_use]
pub fn conflicts_with(mut self, id: impl IntoResettable<Id>) -> Self {
if let Some(id) = id.into_resettable().into_option() {
self.conflicts.push(id);
} else {
self.conflicts.clear();
}
self
}
#[must_use]
pub fn conflicts_with_all(mut self, ns: impl IntoIterator<Item = impl Into<Id>>) -> Self {
for n in ns {
self = self.conflicts_with(n);
}
self
}
}
impl ArgGroup {
#[inline]
pub fn get_id(&self) -> &Id {
&self.id
}
}
impl From<&'_ ArgGroup> for ArgGroup {
fn from(g: &ArgGroup) -> Self {
g.clone()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn groups() {
let g = ArgGroup::new("test")
.arg("a1")
.arg("a4")
.args(["a2", "a3"])
.required(true)
.conflicts_with("c1")
.conflicts_with_all(["c2", "c3"])
.conflicts_with("c4")
.requires("r1")
.requires_all(["r2", "r3"])
.requires("r4");
let args: Vec<Id> = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()];
let reqs: Vec<Id> = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()];
let confs: Vec<Id> = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()];
assert_eq!(g.args, args);
assert_eq!(g.requires, reqs);
assert_eq!(g.conflicts, confs);
}
#[test]
fn test_from() {
let g = ArgGroup::new("test")
.arg("a1")
.arg("a4")
.args(["a2", "a3"])
.required(true)
.conflicts_with("c1")
.conflicts_with_all(["c2", "c3"])
.conflicts_with("c4")
.requires("r1")
.requires_all(["r2", "r3"])
.requires("r4");
let args: Vec<Id> = vec!["a1".into(), "a4".into(), "a2".into(), "a3".into()];
let reqs: Vec<Id> = vec!["r1".into(), "r2".into(), "r3".into(), "r4".into()];
let confs: Vec<Id> = vec!["c1".into(), "c2".into(), "c3".into(), "c4".into()];
let g2 = ArgGroup::from(&g);
assert_eq!(g2.args, args);
assert_eq!(g2.requires, reqs);
assert_eq!(g2.conflicts, confs);
}
#[test]
fn arg_group_send_sync() {
fn foo<T: Send + Sync>(_: T) {}
foo(ArgGroup::new("test"))
}
}