Skip to content

Commit 59d42d7

Browse files
committed
Implement properties for strings, some int checks
Also, adds top-level enums (and consts) and prepares for better range checks in int/number.
1 parent 4fb4264 commit 59d42d7

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

src/malli/json_schema/parse.cljc

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns malli.json-schema.parse
22
(:require [malli.core :as m]
3+
[malli.util :as mu]
34
[clojure.string :as str]))
45

56
;; Utility Functions
@@ -19,6 +20,11 @@
1920
(cond
2021
(-keys :type) (type->malli js-schema)
2122

23+
(-keys :enum) (into [:enum]
24+
(:enum js-schema))
25+
26+
(-keys :const) [:enum (:const js-schema)]
27+
2228
;; Aggregates
2329
(-keys :oneOf)
2430
(into
@@ -44,7 +50,8 @@
4450
(-keys :$ref) ($ref (:$ref js-schema))
4551

4652
:else
47-
(throw (ex-info "Not supported" {:js-schema js-schema})))))
53+
(throw (ex-info "Not supported" {:json-schema js-schema
54+
:reason ::schema-type})))))
4855

4956
(defn properties->malli [{:keys [required]} [k v]]
5057
(cond-> [k]
@@ -53,6 +60,7 @@
5360

5461
(defn object->malli [v]
5562
(let [required (into #{}
63+
;; TODO Should use the same fn as $ref
5664
(map keyword)
5765
(:required v))
5866
closed? (false? (:additionalProperties v))]
@@ -62,11 +70,33 @@
6270
(map (partial properties->malli {:required required}))
6371
(:properties v))))))
6472

65-
(defmethod type->malli "string" [p] string?)
66-
(defmethod type->malli "integer" [p] int?)
67-
(defmethod type->malli "number" [p]
68-
;; TODO support decimal/double
69-
number?)
73+
(defmethod type->malli "string" [{:keys [pattern minLength maxLength enum]}]
74+
;; `format` metadata is deliberately not considered.
75+
;; String enums are stricter, so they're also implemented here.
76+
(cond
77+
pattern [:re pattern]
78+
enum [:and
79+
:string
80+
(into [:enum] enum)]
81+
[:string (cond-> {}
82+
minLength (assoc :min minLength)
83+
maxLength (assoc :max maxLength))]))
84+
85+
(defmethod type->malli "integer" [{:keys [minimum maximum exclusiveMinimum exclusiveMaximum multipleOf]
86+
:or {minimum Integer/MIN_VALUE
87+
maximum Integer/MAX_VALUE}}]
88+
;; On draft 4, exclusive{Minimum,Maximum} is a boolean.
89+
;; TODO Decide on whether draft 4 will be supported
90+
;; TODO Implement exclusive{Minimum,Maximum} support
91+
;; TODO Implement multipleOf support
92+
;; TODO Wrap, when it makes sense, the values below with range checkers, i.e. [:< maximum]
93+
;; TODO extract ranges logic and reuse with number
94+
(cond
95+
(pos? minimum) pos-int?
96+
(neg? maximum) neg-int?
97+
:else int?))
98+
99+
(defmethod type->malli "number" [p] number?)
70100
(defmethod type->malli "boolean" [p] boolean?)
71101
(defmethod type->malli "null" [p] nil?)
72102
(defmethod type->malli "object" [p] (object->malli p))
@@ -76,7 +106,8 @@
76106
(map schema->malli)
77107
items)
78108
(map? items) [:vector (schema->malli items)]
79-
:else (throw (ex-info "Can't produce malli schema" {:p p})))))
109+
:else (throw (ex-info "Not Supported" {:json-schema p
110+
:reason ::array-items})))))
80111

81112
(defn json-schema-document->malli [obj]
82113
[:schema {:registry (into {}

0 commit comments

Comments
 (0)