Skip to content

Creating custom handlers

Alex Miller edited this page May 5, 2014 · 5 revisions

Provided handlers

Fressian provides handlers for the following tags and their Java representation:

  • short, integer, long - java.lang.[Short,Integer,Long]
  • double, float - java.lang.[Double,Float]
  • boolean - java.lang.Boolean
  • byte[], int[], long[], float[], boolean[], double[], Object[]
  • string - java.lang.String
  • null
  • any - TaggedObject
  • list - java.util.List
  • map - java.util.HashMap
  • set - java.util.HashSet
  • uuid - java.util.uuid
  • regex - java.util.regex.Pattern
  • uri - java.net.URI
  • bigint - java.math.BigInteger
  • bigdec - java.math.BigDecimal
  • inst - java.util.Date

data.fressian adds an additional set of handlers that cover many common Clojure types:

  • char - java.lang.Character
  • ratio - clojure.lang.Ratio
  • record - Clojure records
  • symbol - clojure.lang.Symbol
  • key - clojure.lang.Keyword
  • bigint - clojure.lang.BigInt

Adding your own

To add your own tag or override existing tags, you must implement ReadHandler and WriteHandler and merge those mappings into the data.fressian mappings (which are used by default).

Example

Let's add support for the java.awt.Point class. First define the read handler and write handler for Point:

(ns mytest
  (:require [clojure.data.fressian :as fressian])
  (:import [java.awt Point]
           [java.io ByteArrayOutputStream ByteArrayInputStream]
           [org.fressian.handlers WriteHandler ReadHandler]))

(def point-tag "point")

(def point-writer
  (reify WriteHandler
    (write [_ writer point]
      (.writeTag writer point-tag 2)
      (.writeInt writer (.x point))
      (.writeInt writer (.y point)))))

(def point-reader
  (reify ReadHandler
    (read [_ reader tag component-count]
      (Point. (.readInt reader) (.readInt reader)))))

(def my-write-handlers
  (-> (merge {java.awt.Point {point-tag point-writer}}
             fressian/clojure-write-handlers)
      fressian/associative-lookup
      fressian/inheritance-lookup))

(def my-read-handlers
  (-> (merge {point-tag point-reader} fressian/clojure-read-handlers)
      fressian/associative-lookup))

;; Demo

(defn demo []
  (let [baos (ByteArrayOutputStream.)
        writer (fressian/create-writer baos :handlers my-write-handlers)
        point (Point. 1 2)]
    (fressian/write-object writer point)
    (let [bais (ByteArrayInputStream. (.toByteArray baos))
          reader (fressian/create-reader bais :handlers my-read-handlers)
          out (fressian/read-object reader)]
      (assert (= point out)))))
Clone this wiki locally