Skip to content

Commit 6d80a59

Browse files
committed
Add support for alist, plist and an explicit error for unsupported dotted pair notation.
1 parent f42ff98 commit 6d80a59

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

parseedn.el

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ TAG-READERS is an optional association list. For more information, see
141141
(insert " ")
142142
(parseedn-print-seq next))))
143143

144-
(defun parseedn-print-kvs (map &optional ks)
145-
"Insert hash table MAP as an EDN map into the current buffer."
144+
(defun parseedn-print-hash-or-alist (map &optional ks)
145+
"Insert hash table MAP or elisp a-list as an EDN map into the current buffer."
146146
(let ((keys (or ks (a-keys map))))
147147
(parseedn-print (car keys))
148148
(insert " ")
@@ -152,6 +152,34 @@ TAG-READERS is an optional association list. For more information, see
152152
(insert ", ")
153153
(parseedn-print-kvs map next)))))
154154

155+
(defun parseedn-print-plist (plist)
156+
"Insert an elisp property list as an EDN map into the current buffer."
157+
(parseedn-print (car plist))
158+
(insert " ")
159+
(parseedn-print (cadr plist))
160+
(let ((next (cddr plist)))
161+
(when (not (seq-empty-p next))
162+
(insert ", ")
163+
(parseedn-print-plist next))))
164+
165+
(defun parseedn-alist-p (list)
166+
"Non-null if and only if LIST is an alist with simple keys."
167+
(while (consp list)
168+
(setq list (if (and (consp (car list))
169+
(atom (caar list)))
170+
(cdr list)
171+
'not-alist)))
172+
(null list))
173+
174+
(defun parseedn-plist-p (list)
175+
"Non-null if and only if LIST is a plist with keyword keys."
176+
(while (consp list)
177+
(setq list (if (and (keywordp (car list))
178+
(consp (cdr list)))
179+
(cddr list)
180+
'not-plist)))
181+
(null list))
182+
155183
(defun parseedn-print (datum)
156184
"Insert DATUM as EDN into the current buffer.
157185
DATUM can be any Emacs Lisp value."
@@ -175,19 +203,30 @@ DATUM can be any Emacs Lisp value."
175203
((eq t datum)
176204
(insert "true"))
177205

178-
((symbolp datum)
206+
((or (keywordp datum) (symbolp datum))
179207
(insert (symbol-name datum)))
180208

181209
((vectorp datum) (insert "[") (parseedn-print-seq datum) (insert "]"))
182210

211+
((or (hash-table-p datum) (parseedn-alist-p datum))
212+
(insert "{")
213+
(parseedn-print-hash-or-alist datum)
214+
(insert "}"))
215+
216+
((parseedn-plist-p datum)
217+
(insert "{")
218+
(parseedn-print-plist datum)
219+
(insert "}"))
220+
183221
((consp datum)
184222
(cond
223+
((not (listp (cdr datum))) ; dotted pair
224+
(error "Don't know how to print: %s" datum))
185225
((eq 'edn-set (car datum))
186226
(insert "#{") (parseedn-print-seq (cadr datum)) (insert "}"))
187227
(t (insert "(") (parseedn-print-seq datum) (insert ")"))))
188228

189-
((hash-table-p datum)
190-
(insert "{") (parseedn-print-kvs datum) (insert "}"))))
229+
(t (error "Don't know how to print: %s" datum))))
191230

192231
(defun parseedn-print-str (datum)
193232
"Return a string containing DATUM as EDN.

test/parseedn-test.el

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
(should (equal (parseedn-print-str 1.2) "1.2"))
3939
(should (equal (parseedn-print-str [1 2 3]) "[1 2 3]"))
4040
(should (equal (parseedn-print-str t) "true"))
41+
(should (equal (parseedn-print-str '((a . 1) (b . 2))) "{a 1, b 2}"))
42+
(should (equal (parseedn-print-str '((a . 1) (b . ((c . 3))))) "{:a 1, :b {:c 3}}"))
43+
(should (equal (parseedn-print-str '(:a 1 :b 2)) "{:a 1, :b 2}"))
44+
(should (equal (parseedn-print-str '(:a 1 :b (:c 3))) "{:a 1, :b {:c 3}}"))
4145
(should (listp (member (parseedn-print-str
4246
(let ((ht (make-hash-table)))
4347
(puthash :a 1 ht)

0 commit comments

Comments
 (0)