   (not (valid? schema expr)))
 
 
-(defmethod valid? :default
+(defmethod valid?-type :default
   [schema expr]
   (throw (Exception. (str "Unknown schema type: " (serialize schema)))))
 
-(defmethod valid? "integer"
+(defmethod valid?-type "integer"
   [schema expr]
   (integer? expr))
 
-(defmethod valid? "number"
+(defmethod valid?-type "number"
   [schema expr]
   (or (float? expr) (integer? expr)))
 

(ns ru.nsu.ccfit.12222.seon.schema
  (:use [ru.nsu.ccfit.12222.seon.core]))

(defmulti valid?
          "Validate SEON expression against schema."
          (fn [schema expr]
            (:type schema)))

(defn invalid?
  "Shortcut for (not (valid schema expr))."

  [schema expr]
  (nil? expr))

(defmethod valid?-type "null"
           [schema expr]
  (valid?-nil schema expr))

(defmethod valid?-type "nil"
           [schema expr]
  (valid?-nil schema expr))

(defmethod valid?-type "string"
           [schema expr]
  (string? expr))

(defmethod valid?-type "boolean"
           [schema expr]
  (or (true? expr) (false? expr)))

(defmethod valid?-type "object"
  [schema expr]
  (and
    (map? expr)
    (if (:properties schema)
      (every? true? (map (fn [[property schema]]
                           (if (or (:required schema) (property expr))
                             (valid?-type schema (property expr))
                             true)
                           ) (:properties schema)))
      true)))

(defmethod valid?-type "array"
           [schema expr]
  (and
    (seq? expr)
    (if (:items schema)
      (every? true? (map (partial valid?-type (:items schema)) expr))
      true)))