fisxoj / sanity-clause

A data serialization/contract library for common lisp
GNU Lesser General Public License v3.0
51 stars 2 forks source link

Schemas should hydrate late, allowing circular references #25

Closed fisxoj closed 4 years ago

fisxoj commented 4 years ago

I have a schema class

(defclass object-schema (schema-common)
          ((type :data-key "type" :reader %type-of :field-type :constant
            :constant "object" :required t)
           (format :data-key "format" :reader format-of :field-type :string)
           (properties :data-key "properties" :reader properties-of :field-type
            :map :key-field :string :value-field
            (:one-schema-of :schema-choices
             (object-schema array-schema reference))))
          (:metaclass sanity-clause.schema:validated-metaclass))

That references itself in the properties slot. When compiling this code, I get

There is no class named OPENAPI.SPEC.V3::OBJECT-SCHEMA.
   [Condition of type SB-PCL:CLASS-NOT-FOUND-ERROR]

because it's trying to look up the object-schema class while in the middle of defining it.

It would be more useful if this behavior were allowed because there are plenty of places where defining recursive structures would be desirable.

The fix might just be removing

(defmethod initialize-instance :after ((field one-schema-of-field) &key)
  (flet ((ensure-class (symbol-or-class)
           (if (c2mop:classp symbol-or-class)
               symbol-or-class
               (find-class symbol-or-class))))

    (setf (schema-choices-of field) (mapcar #'ensure-class (schema-choices-of field))))
  field)

from field.lisp.