Created
September 26, 2016 16:35
-
-
Save ponzao/6476b7df853402ac744222ab18efe1fa to your computer and use it in GitHub Desktop.
Clojure Spec coercion nonsense
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns vice | |
(:require [clojure.spec :as s] | |
[clj-time.core :as t] | |
[clj-time.format :as tf]) | |
(:import [org.joda.time DateMidnight DateTime] | |
[java.util UUID] | |
[clojure.lang Keyword] | |
[java.math BigInteger] | |
[java.net URL URI] | |
[java.util.regex Pattern])) | |
(def invalid :clojure.spec/invalid) | |
(defmulti coerce-uuid class) | |
(defmethod coerce-uuid java.util.UUID [u] u) | |
(defmethod coerce-uuid java.lang.String [s] | |
(UUID/fromString s)) | |
(defmethod coerce-uuid :default [& args] | |
invalid) | |
(def ->uuid | |
(s/conformer coerce-uuid)) | |
(defmulti coerce-boolean class) | |
(defmethod coerce-boolean java.lang.Boolean [b] b) | |
(defmethod coerce-boolean java.lang.String [s] | |
(case s | |
"true" true | |
"false" false | |
invalid)) | |
(defmethod coerce-boolean :default [& args] | |
invalid) | |
(defmulti coerce-bigint class) | |
(defmethod coerce-bigint java.math.BigInteger [n] n) | |
(defmethod coerce-bigint java.lang.String [s] | |
(try | |
(bigint s) | |
(catch NumberFormatException e | |
invalid))) | |
(defmethod coerce-bigint :default [& args] | |
invalid) | |
(def ->uuid | |
(s/conformer coerce-uuid)) | |
(def ->boolean | |
(s/conformer coerce-boolean)) | |
(def ->bigint | |
(s/conformer coerce-bigint)) | |
(def data | |
(let [id (str (UUID/randomUUID))] | |
{:vice/post.id id | |
:vice/post.title "How to Spec" | |
:vice/post.published? "true" | |
:vice/post.price "10000" | |
:vice/post.content (URI/create (str "http://www.google.com/")) | |
:vice/post.authors [{:vice/author.id (str (UUID/randomUUID)) | |
:vice/author.name "Vesa Marttila"}]})) | |
(s/def :vice/author.id ->uuid) | |
(s/def :vice/author.name string?) | |
(s/def :vice/author | |
(s/keys :req [:vice/author.id | |
:vice/author.name])) | |
(s/def :vice/post.id ->uuid) | |
(s/def :vice/post.title string?) | |
(s/def :vice/post.published? ->boolean) | |
(s/def :vice/post.price ->bigint) | |
(defn content-resolver | |
[entity] | |
(if (uri? entity) | |
(.substring (slurp entity) 0 50) | |
entity)) | |
(def ->resolve | |
(s/conformer content-resolver)) | |
(def ->upper-case | |
(s/conformer | |
(fn [s] | |
(.toUpperCase s)))) | |
(s/def :vice/post.content | |
(s/and ->resolve | |
->upper-case)) | |
(s/def :vice/post.authors (s/coll-of :vice/author)) | |
(s/def :vice/post | |
(s/keys :req [:vice/post.id | |
:vice/post.title | |
:vice/post.published? | |
:vice/post.price | |
:vice/post.content | |
:vice/post.authors])) | |
(clojure.pprint/pprint | |
(s/conform :vice/post data)) | |
; => | |
; #:vice{:post.id #uuid "364f316b-5452-407f-b0cf-ef377f5bacb4", | |
; :post.title "How to Spec", | |
; :post.published? true, | |
; :post.price 10000N, | |
; :post.content "<!DOCTYPE HTML><HTML ITEMSCOPE=\"\" ITEMTYPE=\"HTTP:/", | |
; :post.authors | |
; [#:vice{:author.id #uuid "6a4daf4a-749b-44e1-860a-a63cb9d69837", | |
; :author.name "Vesa Marttila"}]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment