Skip to content

Instantly share code, notes, and snippets.

@eraserhd
Created September 27, 2019 13:57
Show Gist options
  • Save eraserhd/263b2ecc859714baa9d82d8aa78ddeef to your computer and use it in GitHub Desktop.
Save eraserhd/263b2ecc859714baa9d82d8aa78ddeef to your computer and use it in GitHub Desktop.
Another win for meander
(defn- schema->type
[schema]
(let [types (concat
(m/search schema
{"format" "date-time"} :db.type/instant
{"format" "uri"} :db.type/uri
{"type" "array"} '(Array nil)
{"type" "boolean"} :db.type/boolean
{"type" "integer"} :db.type/long
{"type" "string"} :db.type/string
{"items" (m/pred some? ?item)} (list 'Array (schema->type ?item))
{"$ref" (m/pred some? ?ref)} (if (= ?ref "#uuid")
:db.type/uuid
(subs ?ref 1)))
(map schema->type (get schema "allOf")))]
(reduce narrower-type nil types)))
(defn- schema->type
[schema]
(let [types (concat
(case (get schema "type")
nil []
"boolean" [:db.type/boolean]
"string" [:db.type/string]
"integer" [:db.type/long]
"array" ['(Array nil)])
(case (get schema "format")
"date-time" [:db.type/instant]
[])
(when-let [items (get schema "items")]
[(list 'Array (schema->type items))])
(let [$ref (get schema "$ref")]
(cond
(nil? $ref) []
(= $ref "#uuid") [:db.type/uuid]
:else [(subs $ref 1)]))
(map schema->type (get schema "allOf")))]
(reduce narrower-type nil types)))
@noprompt
Copy link

@eraserhd Here's an example of the macro expansion in the first case but with a small tweak on that "$ref" key using epsilon version 0.0.221.

(meander.match.epsilon/search schema
  {"format" "date-time"}           :db.type/instant
  {"format" "uri"}                 :db.type/uri
  {"type"   "array"}               '(Array nil)
  {"type"   "boolean"}             :db.type/boolean
  {"type"   "integer"}             :db.type/long
  {"type"   "string"}              :db.type/string
  {"items"  (m/some ?item)}        (list 'Array (schema->type ?item))
  {"$ref"   "#uuid"}               :db.type/uuid
  {"$ref"   (m/some ?ref)}         (subs ?ref 1))
;; =>
(let [TARGET__13488 schema]
  (if (map? TARGET__13488)
    (let [VAL__13502 (.valAt TARGET__13488 "$ref")
          VAL__13501 (.valAt TARGET__13488 "type")
          VAL__13500 (.valAt TARGET__13488 "format")]
      (concat
       (case VAL__13500
         ("date-time") (list :db.type/instant)
         ("uri") (list :db.type/uri)
         nil)
       (case VAL__13501
         ("array") (list '(Array nil))
         ("boolean") (list :db.type/boolean)
         ("integer") (list :db.type/long)
         ("string") (list :db.type/string)
         nil)
       (let [val__13495 (.valAt TARGET__13488 "items")]
         (letfn [(save__13496 [] nil)
                 (f__13503 []
                   (let [?item val__13495]
                     (list (list 'Array (schema->type ?item)))))]
           (case val__13495 (nil) (save__13496) (f__13503))))
       (case VAL__13502
         ("#uuid")
         (list :db.type/uuid) nil)
       (letfn [(save__13499 [] nil)
               (f__13504 []
                 (let [?ref VAL__13502]
                   (list (subs ?ref 1))))]
         (case VAL__13502
           (nil)
           (save__13499)
           (f__13504)))))
    nil))

I'm fairly sure this macro expansion is superior to previous versions.

@noprompt
Copy link

noprompt commented Sep 27, 2019

Note, I didn't put an example of the version which uses m/cata because its effectively the same but just a bit more noisy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment