Skip to content

Commit

Permalink
Stop using multimethods on spec constructors.
Browse files Browse the repository at this point in the history
  • Loading branch information
niwinz committed Sep 19, 2016
1 parent c25a809 commit 7bf2c65
Showing 1 changed file with 27 additions and 30 deletions.
57 changes: 27 additions & 30 deletions src/octet/spec.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@
(:refer-clojure :exclude [type read float double long short byte bytes repeat])
(:require [octet.buffer :as buffer]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Abstraction definition
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- Protocols

(defprotocol ISpec
"Basic abstraction for something that can be work like a Spec."
Expand All @@ -50,9 +48,7 @@
"Abstraction for calculate size for dynamic specs."
(size* [_ data] "Calculate the size in bytes of the object having a data."))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Composed Spec Types
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- Composed Spec Types

(deftype AssociativeSpec [data dict types]
#?@(:clj
Expand Down Expand Up @@ -140,11 +136,20 @@
(alter-meta! #'->AssociativeSpec assoc :private true)
(alter-meta! #'->IndexedSpec assoc :private true)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Spec Constructors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; --- Spec Constructors

(defmulti spec
(defn- associative-spec
[& params]
(let [data (mapv vec (partition 2 params))
dict (into {} data)
types (map second data)]
(AssociativeSpec. data dict types)))

(defn- indexed-spec
[& types]
(IndexedSpec. types))

(defn spec
"Polymorphic constructor for Spec instances.
Spec is a some kind of composition of arbitrary
Expand All @@ -171,27 +176,19 @@
The same rules applies for writing data into a
buffer."
(fn [& params]
(let [numparams (count params)]
(cond
(every? #(satisfies? ISpec %) params)
:indexed

(and (even? numparams)
(keyword? (first params))
(satisfies? ISpec (second params)))
:associative))))

(defmethod spec :associative
[& params]
(let [data (mapv vec (partition 2 params))
dict (into {} data)
types (map second data)]
(AssociativeSpec. data dict types)))

(defmethod spec :indexed
[& types]
(IndexedSpec. types))
(let [numparams (count params)]
(cond
(every? #(satisfies? ISpec %) params)
(apply indexed-spec params)

(and (even? numparams)
(keyword? (first params))
(satisfies? ISpec (second params)))
(apply associative-spec params)

:else
(throw (ex-info "Invalid arguments" {})))))

(defn repeat
"Creare a composed typespec that repeats `n` times
Expand Down

0 comments on commit 7bf2c65

Please sign in to comment.