Giter Site home page Giter Site logo

json-mop's People

Contributors

gnuxie avatar gschjetne avatar kilianmh avatar xtab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-mop's Issues

Add required slot to json-serializable-slot class

It is quite useful to specify required slots.

Therefore we can add an required slot to the json-serializable-slot class.
Then in the initialize-slots-from-json function it will be checked for each required slot.

I'm however not sure if there should be a warning or an error when a required slot is not present? @gschjetne

No applicable method error when redefining classes

Once a class has been redefined, encode throws a no applicable method error when you attempt to encode an instance.

I've made two extra test cases for this for tests/encode-decode.lisp:

(test reload-encode ()
  (load (asdf:system-relative-pathname :json-mop-tests "tests.lisp"))
  (let ((child (make-instance 'child))
        (parent-only (make-instance 'parent)))
    (is (string= (with-output-to-string (s) (encode child s))
                 (with-output-to-string (s) (encode parent-only s))))))

(test reload-decode ()
  (load (asdf:system-relative-pathname :json-mop-tests "tests.lisp"))
  (let* ((child (make-instance 'child :foo "hello" :bar "quux"))
         (child-rt (obj-rt child)))
    (is (string= (foo child) (foo child-rt)))
    (is (string= (bar child) (bar child-rt)))))
 Failure Details:
 --------------------------------
 RELOAD-DECODE []: 
      Unexpected Error: #<SB-PCL::NO-APPLICABLE-METHOD-ERROR {10064BF7A3}>
There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION YASON:ENCODE (15)>
when called with arguments
  (#<CHILD {10064BF5D3}> #<SB-IMPL::STRING-OUTPUT-STREAM {CA0E523}>).
See also:
  The ANSI Standard, Section 7.6.6.
 --------------------------------
 --------------------------------
 RELOAD-ENCODE []: 
      Unexpected Error: #<SB-PCL::NO-APPLICABLE-METHOD-ERROR {1005F5BDA3}>
There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION YASON:ENCODE (15)>
when called with arguments
  (#<CHILD {1005EC97A3}> #<SB-IMPL::STRING-OUTPUT-STREAM {CA0E583}>).
See also:
  The ANSI Standard, Section 7.6.6.
 --------------------------------

Consuming a map/hash-table of objects

JSON maps (hash-tables) with strings as keys and objects as values can not be consumed so far.
A function for that would be useful. I was not sure how to name it best tough...

(defmethod json-object-to-clos ((input hash-table) class &rest initargs)
  (let ((hash-table
          (make-hash-table :test #'equal :size (hash-table-size input))))
    (loop for key being the hash-keys of input
          for value being the hash-values of input
          do (setf (gethash key hash-table)
                   (apply #'json-to-clos value class initargs)))
    hash-table))

The method also needs to be specialized on stream, pathname, etc. as done with json-to-clos.

Encoding these hash-table of objects will be more difficult and might be implemented like homogeneous-sequence-intermediate-class.

Here is an example using book class from the readme:

(json-object-to-clos
 (yason:parse "{
  \"first-book\": {
    \"title\": \"The Gilded Age: A Tale of Today\",
    \"year_published\": 1873
  },
  \"second-book\": {
    \"title\": \"The Gilded Age: A Tale of Today\",
    \"year_published\": 1873
  }
}")
 'book)

Add support for JSON Schema

https://json-schema.org/

This is useful for many things, like automatically generating a CLOS hierarchy from a schema to consume, or generating a schema for other applications to use when consuming JSON produced by this library.

  • Build a CLOS representation of JSON schema
  • Create a macro that defines classes given a JSON schema
  • Create a function that produces a JSON schema given a class

Redefining a JSON-SERIALIZABLE-CLASS removes JSON-SERIALIZABLE from supertypes of its instances

JSON-MOP> (defclass test-class () () (:metaclass json-serializable-class))
#<JSON-SERIALIZABLE-CLASS JSON-MOP::TEST-CLASS>

JSON-MOP> (typep (make-instance 'test-class) 'json-serializable)
T ;; just as expected

JSON-MOP> (defclass test-class () () (:metaclass json-serializable-class))
#<JSON-SERIALIZABLE-CLASS JSON-MOP::TEST-CLASS>

JSON-MOP> (typep (make-instance 'test-class) 'json-serializable)
NIL ;; wat

This is because appending the json-serializable class in

(defmethod initialize-instance :around ((class json-serializable-class)
&rest rest &key direct-superclasses)
(apply #'call-next-method
class
:direct-superclasses
(append direct-superclasses (list (find-class 'json-serializable)))
rest))

only happens in initialize-instance and not reinitialize-instance.

json-mop and inheritance

Hi. I'm kind of a CL newbie, but I'm trying to use json-mop and having an issue with inheritance.

Suppose I have two classes:

(defclass parent ()
  ((foo :accessor foo :initarg :foo 
          :initform "Foo"
          :json-key "foo"))
  (:metaclass json-serializable-class))

(defclass child (parent)
    ((bar :accessor bar :initarg :bar
      :json-key "bar"))
    (:metaclass json-serializable-class))

(encode (make-instance 'parent)) prints exactly what I expect: {"foo":"Foo"}

I would expect (encode (make-instance 'child)) to print exactly the same thing. However, it prints
{}.

But:

 (describe (make-instance 'child))
#<CHILD {1004ABEC93}>
  [standard-object]

Slots with :INSTANCE allocation:
  FOO  = "Foo"
  BAR  = #<unbound slot>

Maybe I'm misunderstanding a basic CLOS thing? Shouldn't encoding an instance of child include the values it gets from parent's initforms?

Use jzon instead of yason

This seems to be the gold standard for JSON processing in Common Lisp these days.

It also has the advantage of having a stream oriented parser, which saves the inefficiency of consing a whole hash table for every CLOS object. With jzon we can create the objects and populate the slots directly.

Example for consuming a list of objects

I can succesfully consume a class person from the according json format, but how do I invoke json-to-clos if my json endpoint returns a list of person. Being fairly new to Common Lisp I do not grokk yet how to provide the according class information.

using :json-type :any when the type is hash-table throws exception "There is no class named :ANY"

Hello, new to CL and this library. I am running into a strange error. Using :json-type :any seems to work for all types except when the object is a hash-table. Has anyone else had this issue or am I missing something?

There is no class named :ANY.
   [Condition of type SB-PCL:CLASS-NOT-FOUND-ERROR]

Restarts:
 0: [*ABORT] Return to SLIME's top level.
 1: [ABORT] abort thread (#<THREAD "worker" RUNNING {10024BCBD3}>)

Backtrace:
  0: (SB-PCL::FIND-CLASS-FROM-CELL :ANY NIL T)
      Locals:
        CELL = NIL
        ERRORP = T
        SYMBOL = :ANY
  1: ((:METHOD MAKE-INSTANCE (SYMBOL)) :ANY) [fast-method]
      Locals:
        CLASS = :ANY
        SB-DEBUG::MORE = NIL
  2: ((:METHOD JSON-TO-CLOS (HASH-TABLE T)) #<HASH-TABLE :TEST EQUAL :COUNT 2 {10025E8173}> :ANY) [fast-method]
      Locals:
        CLASS = :ANY
        JSON-MOP::INPUT = #<HASH-TABLE :TEST EQUAL :COUNT 2 {10025E8173}>
        SB-DEBUG::MORE = NIL
  3: ((:METHOD JSON-TO-CLOS (HASH-TABLE T)) #<HASH-TABLE :TEST EQUAL :COUNT 17 {10025E4BF3}> OBJECT) [fast-method]
      Locals:
        CLASS = OBJECT
        JSON-MOP::INPUT = #<HASH-TABLE :TEST EQUAL :COUNT 17 {10025E4BF3}>
        JSON-MOP::KEY-COUNT = 11
        JSON-MOP::LISP-OBJECT = #<OBJECT {10025E9D73}>
        SB-DEBUG::MORE = NIL

Thank you for any help, great library over all and very useful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.