I noticed that "spamtest" uses :ge, :gt, etc. operators that
implicitly apply to a number value returned by the internal test.
We've seen those operators before -- in the ":count" and ":value"
match types that are part of Wolfgang Segmuller's "relational" extension.
But there, the syntax is slightly different; one writes
header :value "ge" "X-Priority" "3" # "relational" extension
rather than
header :ge "X-Priority" "3" # ungrammatical
If "spamtest" were changed to simply produced a string and then just
apply a generic match type to it -- similar to the existing address,
header, and envelope operators --
Suggested Syntax: spamtest MATCH-TYPE <key-list: string-list>
one could reuse the "relational" :value and :comparator behavior.
(The "i;ascii-numeric" operator maps all non-number strings to the
same out-of-band value that sorts higher than any number. It also
ignores trailing garbage after a number.)
That would allow a scheme where the spamtest module publishes
a list of keyword criteria that made a message spam, along with
the initial numeric value,
8 money; unsubscribe-clause; this-is-not-spam; invalid-from;
and users could match against the value (using ":value" and
"i;ascii-numeric") or against any of the keyword descriptions
(using :contains).
A message that for whatever reason hasn't been scanned would have
a NULL spamtest value that does not :match or :contain anything.
FWIW, I agree with this assessment. Spamtest should be cast in terms of
the relational extension if at all possible.
Side question: Is it time to last call the relational extension?
Ned