is it possible to extend a protocol defined in another library ? …. specifically TraceSpan
in io.pedestal.log
so that it implements <http://java.io|java.io>.Closeable
?
no, but you can make your own protocol to bridge the two
(defprotocol AsCloseable
(-as-closeable [_]))
(extend-type java.io.Closeable
AsCloseable
(-as-closeable [this] this))
actually, err
its not super straight forward
you can't actually implement a protocol on something based on it implementing another protocol
if you want to do that you probably would have to do a custom dispatch mechanism in some way
(defn as-closeable [item]
(cond
(satisfies? TraceSpan (type item))
(...)
(implements? Closeable item)
item
:else
...AAAA...))
the simplest and least extensible way would be this
i actually consider this a pretty big downside to protocols - they don't actually work like traits in rust or similar where you can implement a trait for anything that implements a trait
(def extending-protocols (atom [])
(defn register-impl-for-protocol! [protocol impl]
(swap! extending-protocols conj [protocol impl]))
(defn as-closeable [item]
(cond
(instance? Closeable item)
item
:else
(loop [impls @extending-protocols]
(if-not (empty? impls)
(let [[protocol impl] (first impls)
remaining-impls (rest impls)]
(if (satisfies? protocol item)
(impl item)
(recur remaining-impls)))
(throw (IllegalArgumentException. (str "No Impl found for " item)))))
the downside here is that with-open
and co won't actually work
I actually made a thing that I think came close to giving a general approach for this before