![]() (defgeneric make-instance-from-json (class-symbol json-input) (json:decode-json-from-string json-input-string))))) (json::*object-key-handler* (wrap-for-key ))) (json::*end-of-object-handler* (end-wrap-for-class output-class-symbol)) (json::*beginning-of-object-handler* (start-wrap-for-class output-class-symbol)) (*name-of-current-class-being-decoded* nil) (let ((json:*json-symbols-package* (symbol-package output-class-symbol))) This could be called make-instance-from-json." (defun decode-json-to-clos (output-class-symbol json-input-string) (defun wrap-for-key (&optional (fn json::*object-key-handler*)) (setf *stack-of-object-ref* (cdr *stack-of-object-ref*)) stack pop (setf *last-json-key-read* current-json-key-for-slot) redo as if we had read this key again (array scenario) reset the same *last-json-key-read* as wrap-for-key does, in case we are in an array. (setf json:*json-symbols-package* (symbol-package (closer-mop:slot-definition-type the-method))))) (format t "json::*prototype*= ~a (the-parent-slot-name= ~a) class-name= ~a package-name= ~a~%" json::*prototype* the-method (closer-mop:slot-definition-type the-method) (package-name (symbol-package (closer-mop:slot-definition-type the-method)))) :lisp-package (find-symbol (package-name (symbol-package (closer-mop:slot-definition-type the-method)))))) :lisp-class (closer-mop:slot-definition-type the-method) (setf json::*prototype* (make-instance 'json::prototype (let ((the-method (get-slot-definition current-class-symbol current-json-key-for-slot))) (json:*json-symbols-package* (symbol-package root-class-symbol))) (current-json-key-for-slot (cdar *stack-of-object-ref*)) (current-class-symbol (caar *stack-of-object-ref*)) (let ((json::*prototype* top-level-prototype) root case dynamically re-bind *prototype* right around calling fn (let ((top-level-prototype (make-instance 'json::prototype :lisp-class root-class-symbol :lisp-package (find-symbol (package-name (symbol-package root-class-symbol)))))) "Utility code to unwrap JSON using cl-json::prototype and create instances of defined CLOS objects ()" (defun end-wrap-for-class (root-class-symbol &optional (fn json::*end-of-object-handler*)) (setf *stack-of-object-ref* (cons (cons class-symbol-of-reference-holder method-symbol-of-reference-holder) *stack-of-object-ref*))) stack push now that the three cases are resolved let's push the cons on the stack. (setf class-symbol-of-reference-holder root-class-symbol)))) else we are a first class object : use class-symbol. (get-slot-definition previous-class-symbol previous-json-key-for-slot))) if we are not in first class object : get the current class by using previous class and slot-definition-type. (previous-json-key-for-slot (cdar *stack-of-object-ref*))) (let ((previous-class-symbol (caar *stack-of-object-ref*)) (method-symbol-of-reference-holder *last-json-key-read*)) default case : we are on root object, don't do anything else. (let ((class-symbol-of-reference-holder nil) (defun start-wrap-for-class (root-class-symbol &optional (fn json::*beginning-of-object-handler*)) :test (lambda(a b) (string-equal a (symbol-name (closer-mop:slot-definition-name b)))))) "returns a slot-definition from the slot of class-symbol which is infered from using json-key / method symbol" (defun get-slot-definition (class-symbol json-key) (defvar *name-of-current-class-being-decoded*) (defvar *stack-of-object-ref*) holds elements as cons (class-name. and yes, I've just noticed while typing the code here that it's not compatible yet with json arrays :-/ dependencies I then have defgeneric make-instance-from-json ,so I can still overload that generic Json2CLOS engine depending on the root object to instantiate, without changing the call syntax.Īs I'm just beginning with lisp, what are your thoughts on that code (design/implementation) ? else we need to instantiate a class from the type of the slot-definition from the 2 data on the stack (the parent slot class having the specific slot definition name).if the stack top is nil we need to instantiate the root object.Json::*end-of-object-handler* to set the json::*prototype* of the class that should be instantiated. ![]() special case for the root object where last key read is nil.the type of the parent object we parse, which is either the type of the root object (for first level referenced object) or which is found on the top of the same stack (general case).the last key read (which represent the slot name in the parent object).Json::*beginning-of-object-handler* to push on stack a cons with : json::*object-key-handler* to always know the last key (parent slot name) we run through while parsing JSON.I use cl-json custom handle functionality Coming from this question I've finally come up with the following solution.
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |