Skip to content

Commit

Permalink
feat: support flag-like option
Browse files Browse the repository at this point in the history
  • Loading branch information
sigoden committed Nov 10, 2023
1 parent 95c6259 commit f570fcb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 25 deletions.
43 changes: 18 additions & 25 deletions src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,32 +92,37 @@ impl FlagOptionParam {
}

pub(crate) fn unlimited_args(&self) -> bool {
self.terminated() || !self.notation_modifer().is_none()
self.terminated()
|| self
.notation_modifer()
.map(|v| "*+".contains(v))
.unwrap_or_default()
}

pub(crate) fn validate_args_len(&self, num: usize) -> bool {
let len = self.arg_value_names.len();
if self.unlimited_args() {
let min = if len > 1 && self.notation_modifer() == NotationModifier::Asterisk {
let min = if len > 1 && self.notation_modifer() == Some('*') {
len - 1
} else {
len
};
num >= min
} else if self.allow_empty() {
num == 1 || num == 0
} else {
num == len
}
}

pub(crate) fn notation_modifer(&self) -> NotationModifier {
if let Some(notation) = self.arg_value_names.last() {
if notation.ends_with('*') {
return NotationModifier::Asterisk;
} else if notation.ends_with('+') {
return NotationModifier::Plus;
}
}
NotationModifier::None
pub(crate) fn allow_empty(&self) -> bool {
!self.multiple() && self.notation_modifer() == Some('?')
}

pub(crate) fn notation_modifer(&self) -> Option<char> {
self.arg_value_names
.last()
.and_then(|name| ['*', '+', '?'].into_iter().find(|v| name.ends_with(*v)))
}

pub(crate) fn required(&self) -> bool {
Expand Down Expand Up @@ -272,6 +277,8 @@ impl FlagOptionParam {
var_name,
values[0].iter().map(|v| v.to_string()).collect(),
))
} else if self.allow_empty() && values[0].is_empty() {
Some(ArgcValue::Single(var_name, "1".to_string()))
} else {
Some(ArgcValue::Single(var_name, must_get_first(values[0])))
}
Expand Down Expand Up @@ -590,20 +597,6 @@ impl ParamData {
}
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
#[serde(tag = "type", content = "value")]
pub(crate) enum NotationModifier {
None,
Plus,
Asterisk,
}

impl NotationModifier {
pub(crate) fn is_none(&self) -> bool {
self == &NotationModifier::None
}
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
#[serde(tag = "type", content = "value")]
pub(crate) enum Modifier {
Expand Down
23 changes: 23 additions & 0 deletions tests/snapshots/integration__spec__zero_or_one.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: tests/spec.rs
expression: data
---
************ RUN ************
prog --oa

OUTPUT
argc_oa=1
argc__args=( prog --oa )
argc__cmd_arg_index=0
argc__positionals=( )

************ RUN ************
prog --oa v1

OUTPUT
argc_oa=v1
argc__args=( prog --oa v1 )
argc__cmd_arg_index=0
argc__positionals=( )


8 changes: 8 additions & 0 deletions tests/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,11 @@ fn plus_sign() {
]
);
}

#[test]
fn zero_or_one() {
let script = r###"
# @option --oa <VALUE?>
"###;
snapshot_multi!(script, [vec!["prog", "--oa"], vec!["prog", "--oa", "v1"]]);
}

0 comments on commit f570fcb

Please sign in to comment.