From 52dc626591146b65519188d0689ef9fbd2bd914a Mon Sep 17 00:00:00 2001 From: Nic Ferier Date: Fri, 7 Sep 2012 21:03:00 +0100 Subject: initial commit --- kv-tests.el | 37 +++++++++++++++++++ kv.el | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 kv-tests.el create mode 100644 kv.el 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 +;; 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 . + +;;; 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 -- cgit v1.2.3