Skip to content

Commit

Permalink
Add "not matching regex" conditional
Browse files Browse the repository at this point in the history
  • Loading branch information
laniakea64 committed Dec 3, 2024
1 parent 79be6c1 commit bc176f2
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/conditional_operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub(crate) enum ConditionalOperator {
Inequality,
/// `=~`
RegexMatch,
/// `!~`
RegexNotMatch,
}

impl Display for ConditionalOperator {
Expand All @@ -17,6 +19,7 @@ impl Display for ConditionalOperator {
Self::Equality => write!(f, "=="),
Self::Inequality => write!(f, "!="),
Self::RegexMatch => write!(f, "=~"),
Self::RegexNotMatch => write!(f, "!~"),
}
}
}
3 changes: 3 additions & 0 deletions src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ impl<'src, 'run> Evaluator<'src, 'run> {
ConditionalOperator::RegexMatch => Regex::new(&rhs_value)
.map_err(|source| Error::RegexCompile { source })?
.is_match(&lhs_value),
ConditionalOperator::RegexNotMatch => !Regex::new(&rhs_value)
.map_err(|source| Error::RegexCompile { source })?
.is_match(&lhs_value),
};
Ok(condition)
}
Expand Down
3 changes: 2 additions & 1 deletion src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ impl<'src> Lexer<'src> {
match start {
' ' | '\t' => self.lex_whitespace(),
'!' if self.rest().starts_with("!include") => Err(self.error(Include)),
'!' => self.lex_digraph('!', '=', BangEquals),
'!' => self.lex_choices('!', &[('=', BangEquals), ('~', BangTilde)], Unspecified),
'#' => self.lex_comment(),
'$' => self.lex_single(Dollar),
'&' => self.lex_digraph('&', '&', AmpersandAmpersand),
Expand Down Expand Up @@ -949,6 +949,7 @@ mod tests {
Asterisk => "*",
At => "@",
BangEquals => "!=",
BangTilde => "!~",
BarBar => "||",
BraceL => "{",
BraceR => "}",
Expand Down
2 changes: 2 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,8 @@ impl<'run, 'src> Parser<'run, 'src> {
ConditionalOperator::Inequality
} else if self.accepted(EqualsTilde)? {
ConditionalOperator::RegexMatch
} else if self.accepted(BangTilde)? {
ConditionalOperator::RegexNotMatch
} else {
self.expect(EqualsEquals)?;
ConditionalOperator::Equality
Expand Down
2 changes: 2 additions & 0 deletions src/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ pub enum ConditionalOperator {
Equality,
Inequality,
RegexMatch,
RegexNotMatch,
}

impl ConditionalOperator {
Expand All @@ -368,6 +369,7 @@ impl ConditionalOperator {
full::ConditionalOperator::Equality => Self::Equality,
full::ConditionalOperator::Inequality => Self::Inequality,
full::ConditionalOperator::RegexMatch => Self::RegexMatch,
full::ConditionalOperator::RegexNotMatch => Self::RegexNotMatch,
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/token_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub(crate) enum TokenKind {
At,
Backtick,
BangEquals,
BangTilde,
BarBar,
BraceL,
BraceR,
Expand Down Expand Up @@ -51,6 +52,7 @@ impl Display for TokenKind {
At => "'@'",
Backtick => "backtick",
BangEquals => "'!='",
BangTilde => "'!~'",
BarBar => "'||'",
BraceL => "'{'",
BraceR => "'}'",
Expand Down
2 changes: 1 addition & 1 deletion tests/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ test! {
",
stdout: "",
stderr: "
error: Expected '&&', '!=', '||', '==', '=~', '+', or '/', but found identifier
error: Expected '&&', '!=', '!~', '||', '==', '=~', '+', or '/', but found identifier
——▶ justfile:1:12
1 │ a := if '' a '' { '' } else { b }
Expand Down
20 changes: 20 additions & 0 deletions tests/regexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,23 @@ fn bad_regex_fails_at_runtime() {
.status(EXIT_FAILURE)
.run();
}

#[test]
fn not_matching_regex() {
Test::new()
.justfile(
"
foo := if 'Foo' !~ '^ab+c' {
'no'
} else {
'yes'
}
default:
echo {{ foo }}
",
)
.stderr("echo no\n")
.stdout("no\n")
.run();
}

0 comments on commit bc176f2

Please sign in to comment.