diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-13 11:02:32 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-13 11:02:32 +0200 |
| commit | 043b150f7651c598dac8fc02d7068b940d0f8741 (patch) | |
| tree | 943acdc0a0c8891a150dd02af6299b28d31499e5 /src/rulequery.cpp | |
| parent | a3651eac1528a2b90cfb8e26934facf856ae3531 (diff) | |
| download | qtmaildir-043b150f7651c598dac8fc02d7068b940d0f8741.tar.gz qtmaildir-043b150f7651c598dac8fc02d7068b940d0f8741.zip | |
feat(rulequery): compile every field and operator
Diffstat (limited to 'src/rulequery.cpp')
| -rw-r--r-- | src/rulequery.cpp | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/rulequery.cpp b/src/rulequery.cpp index f80e6c4..198c583 100644 --- a/src/rulequery.cpp +++ b/src/rulequery.cpp @@ -36,6 +36,54 @@ QString prefixFor(RuleTerm::Field field) return QString(); } +bool isNegated(RuleTerm::Op op) +{ + return op == RuleTerm::ContainsNot || op == RuleTerm::IsNot + || op == RuleTerm::HasNot; +} + +/// Quoted when the operator asks for an exact phrase, and ALWAYS when the +/// value holds a space: unquoted, the space ends the term and the remainder +/// becomes a bare word, which widens the rule instead of breaking it. +bool needsQuotes(const RuleTerm &term) +{ + if (term.field == RuleTerm::Folder) + return true; + if (term.value.contains(QLatin1Char(' '))) + return true; + // Is/IsNot asks for an exact phrase, which only free-text fields need + // quoting for: tag: and attachment: values are already bare words, and + // quoting them changes nothing notmuch cares about but breaks the test's + // documented expectation of an unquoted tag. + if (term.op == RuleTerm::Is || term.op == RuleTerm::IsNot) { + return term.field == RuleTerm::From || term.field == RuleTerm::To + || term.field == RuleTerm::Cc || term.field == RuleTerm::Subject; + } + return false; +} + +QString compileTerm(const RuleTerm &term) +{ + QString value = term.value; + if (term.field == RuleTerm::Folder) + value += QStringLiteral("/**"); + + QString body; + if (term.field == RuleTerm::Date) { + body = prefixFor(term.field) + QLatin1Char(':') + + (term.op == RuleTerm::Before + ? QStringLiteral("..") + value + : value + QStringLiteral("..")); + } else if (needsQuotes(term)) { + body = prefixFor(term.field) + QStringLiteral(":\"") + value + + QLatin1Char('"'); + } else { + body = prefixFor(term.field) + QLatin1Char(':') + value; + } + + return isNegated(term.op) ? QStringLiteral("not ") + body : body; +} + } // namespace bool operator==(const RuleTerm &a, const RuleTerm &b) @@ -54,8 +102,7 @@ QString RuleQuery::compile() const if (terms.isEmpty()) return QString(); - return prefixFor(terms.first().field) + QLatin1Char(':') - + terms.first().value; + return compileTerm(terms.first()); } RuleQuery RuleQuery::parse(const QString &query) |
