summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNic Ferier <nic@ferrier.me.uk>2012-12-28 19:28:26 +0000
committerNic Ferier <nic@ferrier.me.uk>2012-12-28 19:28:26 +0000
commit446800fd8e1339b3245d1c9b6e3cd070c24b29c9 (patch)
tree62fe1cca0a3b2ade5596ae61b49a5d3fabdbd973
parentf8c11b10b140efbc02c6eaf2a174df870adc790b (diff)
add matching to kvquery->func, add query language documentation.
-rw-r--r--kv-tests.el7
-rw-r--r--kv.el41
2 files changed, 40 insertions, 8 deletions
diff --git a/kv-tests.el b/kv-tests.el
index 8721f51..c910d2a 100644
--- a/kv-tests.el
+++ b/kv-tests.el
@@ -84,7 +84,12 @@
(should
(equal
'("testkey" . "testvalue")
- (kvassoq= 'testkey "testvalue" '(("testkey" . "testvalue"))))))
+ (kvassoq= 'testkey "testvalue" '(("testkey" . "testvalue")))))
+ ;; The nil case, the key isn't present
+ (should
+ (equal
+ nil
+ (kvassoq= 'blah "testvalue" '(("testkey" . "testvalue"))))))
(ert-deftest kvalist2-filter ()
(should
diff --git a/kv.el b/kv.el
index d6fa327..58532b8 100644
--- a/kv.el
+++ b/kv.el
@@ -96,11 +96,34 @@ Returns the value looked up by KEY that passes, so normally:
(let ((v (kvassoqc key alist)))
(and v (equal (cdr v) value) v)))
-(defun* kvquery->func (query &key (equal-func 'kvassoc))
+(defun kvmatch (key regex alist)
+ "Test the value with KEY in ALIST matches REGEX."
+ (let ((v (kvassoqc key alist)))
+ (and v (string-match regex (cdr v)) v)))
+
+(defun* kvquery->func (query &key
+ (equal-func 'kvassoc=)
+ (match-func 'kvmatch))
"Turn a simple QUERY expression into a filter function.
EQUAL-FUNC is the function that implements the equality
-predicate."
+predicate.
+
+MATCH-FUNC is the function that implements the match predicate.
+
+The query language is:
+
+ | a b - true if a or b is true
+ & a b - true only if a and b is true
+ = a b - true if a equals b as per the EQUAL-FUNC
+ ~ a b - true if a matches b as per the MATCH-FUNC
+
+So, for example:
+
+ (|(= a b)(= c d))
+
+Means: if `a' equals `b', or if `c' equals `d' then the
+expression is true."
(flet ((query-parse (query)
(let ((part (car query))
(rest (cdr query)))
@@ -113,6 +136,9 @@ predicate."
(cons 'and
(loop for i in rest
collect (query-parse i))))
+ ((eq part '~)
+ (destructuring-bind (field value) rest
+ (list match-func field value (quote record))))
((eq part '=)
(destructuring-bind (field value) rest
(list equal-func field value (quote record))))))))
@@ -190,11 +216,12 @@ Only pairs where the car is a `member' of KEYS will be returned."
"Filter the plist to just those matching KEYS.
`kvalist->filter-keys' is actually used to do this work."
- (let ((symkeys (loop for k in keys
- collect (let ((strkey (symbol-name k)))
- (if (equal (substring strkey 0 1) ":")
- (intern (substring strkey 1))
- k)))))
+ (let ((symkeys
+ (loop for k in keys
+ collect (let ((strkey (symbol-name k)))
+ (if (equal (substring strkey 0 1) ":")
+ (intern (substring strkey 1))
+ k)))))
(kvalist->plist
(apply
'kvalist->filter-keys