Skip to content

Instantly share code, notes, and snippets.

@kingcons
Created May 10, 2013 22:43
Show Gist options
  • Save kingcons/5557975 to your computer and use it in GitHub Desktop.
Save kingcons/5557975 to your computer and use it in GitHub Desktop.
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '(yason closer-mop alexandria)))
;; Turns out cl-json does this just as fast without all the fuss.
;; Just (cl-json:encode-json (romreader:load-rom "foo.nes") stream).
(defpackage #:json-export
(:use :cl)
(:import-from #:closer-mop #:class-slots
#:slot-definition-name)
(:export #:defexporter #:export! #:class-to-hash-table))
(in-package #:json-export)
(defgeneric export! (obj path)
(:documentation "Export OBJ to JSON in the given PATH.")
(:method (obj path)
(with-open-file (out path
:direction :output
:if-exists :supersede
:if-does-not-exist :create)
(yason:with-output (out)
(yason:encode obj out))
(format t "~&Export to ~A completed.~%" path))))
(defmacro defexporter (class exporter)
(alexandria:with-gensyms (new-obj)
`(defmethod export! :around ((obj ,class) path)
(let ((,new-obj (,exporter obj)))
(call-next-method ,new-obj path)))))
(defun class-to-hash-table (obj)
(let* ((slots (mapcar #'slot-definition-name (class-slots (class-of obj))))
(vals (mapcar (lambda (x) (slot-value obj x)) slots))
(result (make-hash-table :test #'equal)))
(loop for slot in slots for v in vals
do (setf (gethash slot result) v)
finally (return result))))
(defmethod yason:encode ((object symbol) &optional (stream *standard-output*))
(yason:encode (princ-to-string object) stream))
(defexporter romreader:rom class-to-hash-table)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment