git.fiddlerwoaroof.com
Browse code

feat: json-file, load json as lisp data

Edward authored on 09/03/2021 18:45:29
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+;;; -*- Mode:Lisp; Syntax:ANSI-Common-Lisp; Package: ASDF-USER -*-
2
+(in-package :asdf-user)
3
+
4
+(defsystem :fwoar-asdf-extensions
5
+  :description ""
6
+  :author "Ed L <edward@elangley.org>"
7
+  :license "MIT"
8
+  :depends-on (#:alexandria
9
+               #:uiop
10
+               #:serapeum
11
+               #:yason)
12
+  :serial t
13
+  :components ((:file "json-file")
14
+               ))
0 15
new file mode 100644
... ...
@@ -0,0 +1,42 @@
1
+(defpackage :fwoar.json-file
2
+  (:use :cl )
3
+  (:export json))
4
+(in-package :fwoar.json-file)
5
+
6
+(defclass json (asdf:cl-source-file)
7
+  ((package :initarg :package :reader json-package :initform (error "must have a package"))
8
+   (transform :initarg :transform :reader json-transform :initform ''identity)))
9
+(defclass generate-lisp-op (asdf:downward-operation)
10
+  ())
11
+(defmethod asdf:component-depends-on ((o asdf:compile-op) (component json))
12
+  (format t "~&...~%")
13
+  `((generate-lisp-op ,component) ,@(call-next-method)))
14
+
15
+(defvar *ht-pprint-dispatch* (copy-pprint-dispatch *print-pprint-dispatch*))
16
+(defvar *empty-package* (make-package (symbol-name (gensym)) :use ()))
17
+(defmethod asdf:perform ((op generate-lisp-op) (c json))
18
+  (let* ((lisp-file (car (asdf:input-files 'asdf:load-source-op
19
+                                           c)))
20
+         (json-file (merge-pathnames (make-pathname :type "json")
21
+                                     lisp-file))
22
+         (*package* *empty-package*)
23
+         (*print-pretty* t)
24
+         (*print-case* :upcase))
25
+    (alexandria:with-output-to-file (s lisp-file :if-exists :supersede :if-does-not-exist :create)
26
+      (pprint `(defpackage ,(json-package c) (:use) (:export :+data+))
27
+              s)
28
+      (fresh-line s)
29
+      (princ (serapeum:string-replace "#:~A"
30
+                                      (with-output-to-string (str)
31
+                                        (let ((*print-readably* t))
32
+                                          (pprint
33
+                                           `(defvar #:~a
34
+                                              (funcall ,(json-transform c)
35
+                                                       (yason:parse
36
+                                                        ,(alexandria:read-file-into-string json-file))))
37
+                                           str)))
38
+                                      (format nil "~a:~a"
39
+                                              (json-package c)
40
+                                              :+data+))
41
+             s))
42
+    (values)))