summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNic Ferier <nic@ferrier.me.uk>2012-09-07 21:03:00 +0100
committerNic Ferier <nic@ferrier.me.uk>2012-09-07 21:03:00 +0100
commit52dc626591146b65519188d0689ef9fbd2bd914a (patch)
treeabfa8f9cf665ce3b98fc3533783664bef7360151
initial commit
-rw-r--r--kv-tests.el37
-rw-r--r--kv.el120
2 files changed, 157 insertions, 0 deletions
diff --git a/kv-tests.el b/kv-tests.el
new file mode 100644
index 0000000..f4096fe
--- /dev/null
+++ b/kv-tests.el
@@ -0,0 +1,37 @@
+(require 'kv)
+(require 'ert)
+
+(ert-deftest kvhash->alist ()
+ "Test making alists from hashes."
+ (should
+ (equal
+ (sort
+ (kvhash->alist
+ (kvalist->hash '((name1 . value1)
+ (name2 . value2))))
+ (lambda (a b)
+ (string-lessp (symbol-name (car a))
+ (symbol-name (car b)))))
+ '((name1 . value1)
+ (name2 . value2)))))
+
+(ert-deftest kvdotassoc ()
+ (should
+ (equal
+ (dotassoc "a.b.c" '(("a" . (("b" . (("c" . 10)))))))
+ 10)))
+
+(ert-deftest kvdotassq ()
+ (should
+ (equal
+ (dotassq 'a.b.c '((a . ((b . ((c . 10)))))))
+ 10)))
+
+(ert-deftest kvalist->plist ()
+ "Make alists into plists."
+ (should
+ (equal
+ '(:a1 value1 :a2 value2)
+ (kvalist->plist '((a1 . value1)(a2 . value2))))))
+
+;;; kv-tests.el ends here
diff --git a/kv.el b/kv.el
new file mode 100644
index 0000000..381638f
--- /dev/null
+++ b/kv.el
@@ -0,0 +1,120 @@
+;;; kv.el --- key/value data structure functions
+
+;; Copyright (C) 2012 Nic Ferrier
+
+;; Author: Nic Ferrier <nferrier@ferrier.me.uk>
+;; Keywords: lisp
+;; Version: 0.0.1
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Some routines for working with key/value data structures like
+;; hash-tables and alists and plists.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defun kvalist->hash (alist &rest hash-table-args)
+ (let ((table (apply 'make-hash-table hash-table-args)))
+ (mapcar
+ (lambda (pair)
+ (puthash (car pair) (cdr pair) table))
+ alist)
+ table))
+
+(defun kvhash->alist (hash)
+ (let (store)
+ (maphash
+ (lambda (key value)
+ (setq
+ store
+ (append (list (cons key value)) store)))
+ hash)
+ store))
+
+(defun kvalist->plist (alist)
+ "Convert an alist to a plist."
+ ;; Why doesn't elisp provide this?
+ (loop for pair in alist
+ append (list
+ (intern
+ (concat
+ ":"
+ (cond
+ ((symbolp (car pair))
+ (symbol-name (car pair)))
+ ((stringp (car pair))
+ (car pair)))))
+ (cdr pair))))
+
+(defun kvalist->keys (alist)
+ "Get just the keys from the alist."
+ (mapcar (lambda (pair) (car pair)) alist))
+
+(defun kvalist->values (alist)
+ "Get just the values from the alist."
+ (mapcar (lambda (pair) (cdr pair)) alist))
+
+(defun kvdotassoc-fn (expr table func)
+ "Use the dotted EXPR to access deeply nested data in TABLE.
+
+EXPR is a dot separated expression, either a symbol or a string.
+For example:
+
+ \"a.b.c\"
+
+or:
+
+ 'a.b.c
+
+If the EXPR is a symbol then the keys of the alist are also
+expected to be symbols.
+
+TABLE is expected to be an alist currently.
+
+FUNC is some sort of `assoc' like function."
+ (let ((state table)
+ (parts
+ (if (symbolp expr)
+ (mapcar
+ 'intern
+ (split-string (symbol-name expr) "\\."))
+ ;; Else it's a string
+ (split-string expr "\\."))))
+ (catch 'break
+ (while (listp parts)
+ (let ((traverse (funcall func (car parts) state)))
+ (setq parts (cdr parts))
+ (if parts
+ (setq state (cdr traverse))
+ (throw 'break (cdr traverse))))))))
+
+(defun kvdotassoc (expr table)
+ "Dotted expression handling with `assoc'."
+ (kvdotassoc-fn expr table 'assoc))
+
+(defun kvdotassq (expr table)
+ "Dotted expression handling with `assq'."
+ (kvdotassoc-fn expr table 'assq))
+
+(defalias 'dotassoc 'kvdotassoc)
+(defalias 'dotassq 'kvdotassq)
+
+(provide 'kv)
+(provide 'dotassoc)
+
+;;; kv.el ends here