extend-protocol

added
1.2

ns
clojure.core

type
macro

(extend-protocol p & specs)

Useful when you want to provide several implementations of the same
protocol all at once. Takes a single protocol and the implementation
of that protocol for one or more types. Expands into calls to
extend-type:

(extend-protocol Protocol
AType
(foo [x] ...)
(bar [x y] ...)
BType
(foo [x] ...)
(bar [x y] ...)
AClass
(foo [x] ...)
(bar [x y] ...)
nil
(foo [x] ...)
(bar [x y] ...))

expands into:

(do
(clojure.core/extend-type AType Protocol 
(foo [x] ...) 
(bar [x y] ...))
(clojure.core/extend-type BType Protocol 
(foo [x] ...) 
(bar [x y] ...))
(clojure.core/extend-type AClass Protocol 
(foo [x] ...) 
(bar [x y] ...))
(clojure.core/extend-type nil Protocol 
(foo [x] ...) 
(bar [x y] ...)))

                (defprotocol XmlNode
  (as-xml [this]))

(defrecord User [^Integer id ^String name ^java.util.Date dob])

;; Protocols can be extended to existing types and user defined types
(extend-protocol XmlNode
  Integer
    (as-xml [this] (str this))
  String
    (as-xml [this] (identity this))
  java.util.Date
    (as-xml [this] (-> (java.text.SimpleDateFormat. "yyyy-MM-dd HH:mm:ss")
                       (.format this)))
  User
    (as-xml [this] (str "<user>"
                        "<id>" (as-xml (:id this)) "</id>"
                        "<name>" (as-xml (:name this)) "</name>"
                        "<dob>" (as-xml (:dob this)) "</dob>"
                        "</user>")))