Closed mischac closed 3 years ago
@mischac This is desired behavior. As in Clojure spec, Lancaster takes the view that a schema should not exclude extra information from being included in the map/record. You can define the keys and types of the things you care about and check that they match those definitions. However, leaving the map/record open to containing extra things that you don't care about greatly improves reuse and compatibility. It enables the common pattern of creating a map of information and passing it along to various functions that manipulate it. Step 2 of a process may add a key that is used by Step 7. However Steps 3-6 don't need that key nor do they care about it. However, if they excluded it, Step 7 would have to get the key some other way. Rich Hickey has discussed this principle a few times and Lancaster follows his approach. Lancaster's conversion to Plumatic schema enables open maps/records by adding {Any Any}
.
Here's some a REPL session exploring this:
user> (require '[deercreeklabs.lancaster :as l])
nil
user> (l/def-record-schema person-schema
[:name l/string-schema]
[:age l/int-schema])
#'user/person-schema
user> (l/edn person-schema)
{:name :user/person,
:type :record,
:fields
[{:name :name, :type [:null :string], :default nil}
{:name :age, :type [:null :int], :default nil}]}
user> (l/plumatic-schema person-schema)
{Any Any,
{:k :name}
(conditional
nil?
(eq nil)
deercreeklabs.lancaster.utils/valid-bytes-or-string?
(pred deercreeklabs.lancaster.utils/valid-bytes-or-string?)),
{:k :age} (conditional nil? (eq nil) int? Int)}
user> (def plu (l/plumatic-schema person-schema))
#'user/plu
user> (require '[schema.core :as s])
nil
user> (s/check plu {:name "Alice" :age 37})
nil
user> (s/check plu {:name "Alice" :age "not an int"})
{:age (not (some-matching-condition? "not an int"))}
user> (s/check plu {:name "Alice" :age 37 :fav-color :red})
nil
I get an
Any Any
for each avro record when converting to aplumatic
schema via alancaster
schema.Example:
It might relate to this line, not sure.