Converting between Java types in Clojure can get messy. This library helps you define simple conversion steps and generate automatic type converter functions.
For example defining a conversion from type A
to B
and then from type B
to C
automatically
gives you =>B
and =>C
functions. The =>C
function accepts both A
and B
types!
First, import the definitions interface.
(require '[convertible.def :refer [defconv defsource deftarget]])
Second, define some type conversion logics. For example, define ways to convert from String
to LocalDate
and also from LocalDate
to LocalDateTime
.
(defconv String LocalDate (LocalDate/parse +input+)
(defconv LocalDate LocalDateTime (.atStartOfDay +input+))
These lines generated two functions: (=>LocalDate)
and (=>LocalDateTime)
.
(=>LocalDate "2018-01-01")
;; it returns #object[java.time.LocalDate ... "2018-01-01"]
(=>LocalDateTime (=>LocalDate "2018-01-01"))
;; it returns #object[java.time.LocalDateTime ... "2018-01-01T00:00"]
The fun part is that this library chains conversions automatically.
(=>LocalDateTime "2018-01-01")
;; it calls =>LocalDate and then =>LocalDateTime to return #object[java.time.LocalDateTime ... "2018-01-01T00:00"]
The library found the shortest path from String
through LocalDate
to LocalDateTime
.
Also, the path is memoized so next time type conversion will be faster between these two types.
See namespaces coll
, color
, core
, io
, str
namespaces for a list of available type conversions. Import convertible.all
namespace to access all implemented type conversions.
You can use three methods to generate converter code.
Use deftarget
to define conversion target classes. The public unary constructors
of target classes are used for conversion. For example, calling (defsource File)
will generate converters to URI
and String
types because the File
class has constructors for these cases.
Use defsource
to defined conversion sources. The toXXX()
methods will be used
for data conversion. For example, calling (deftarget File)
will generate converters to URI
and URL
types
because the File
class has a toURI()
and a toURL()
method.
Use defconv
to define more complex conversion logics. For example, writing the following:
(defconv String Time
(try (Time/valueOf +input+)
(catch IllegalArgumentException _ nil)))
Will generate a converter from String
to Time
with a custom parsing logics.
Please note, if the conversion fails the implementation should return nil
so the library will
try to find an other conversion path.
The above codes successfully generated the (=>URI)
, (=>URL)
, (=>File)
, (=>Time)
methods.
You need to import them from the location of the conversion to call them.
The automatically generated converter functions are named (=>XXX)
where XXX
is the name of the
target class.
toString
conversions pleaseYou should not define converters that convert to String
types. This is because
many different types can be constructed directly from strings and automatically
composing them with string conversions would enable irrational and unexpected
type conversions.
Use the convertible.coercer/matcher
function with schema.coerce/coercer
to automatically coerce to a given schema.
For example lets say we want to coerce to CommentRequest
schema:
(def parse-comment-request
(coerce/coercer CommentRequest convertible.coercer/matcher))
Calling parse-comment-request
will do the coercion or throw a RuntimeException
.
These are not implemented (yet).
Copyright © 2018 Janos Erdos
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close