Liking cljdoc? Tell your friends :D

Adding supported key/path types (updated in version 1.3)

defpathtype

If you want to support additional types in paths you can use the defpathtype macro. It takes the following parameters:

  • hex-code - a number used for type identification in the database
    • 0x0 is used internally and off limits
    • built-in codes which should not be overwritten are: 0x10 , 0x20, 0x21, 0x24, 0x25, 0x30, 0x31, 0x32, 0x68, 0x69, 0x70, 0xa0. Attempts to overwrite them (or generally change encodings) should print a warning.
  • types - the types to be encoded (generally there should only be one)
  • encoder - a function which takes elements of the types specified in types and returns a string representation
  • decoder - a function which takes the string reprensentations generated by the encoder and reconstructs a value of the appropriate type

You can see which types and hex-codes are already assigned by calling the path-encoding-assignments function

check-encoding

Additionally, you should use the check-encoding function to test that your encoding and decodings match. It returns a map with four keys:

  • :equal - indicates if the decoded value is equal to the initial value
  • :initial - the supplied value before encoding
  • :decoded - the value after it has been decoded
  • :encoded - the encoded (string) representation of the value

Example

;; setup namespace
(require '(clojure [string :as str]))
(use 'codax.core)

;; create a record type
(defrecord Point [x y])

;; find an unused hex-code
(path-encoding-assignments) ;{:hex-codes ("0x20" "0xa0" "0x21" "0x24" "0x25" "0x68" "0x69" "0x10" "0x30" "0x70" "0x31" "0x32"),
                            ; :types (nil java.time.Instant java.lang.Double clojure.lang.Symbol java.lang.String ...}

;; define a path type using 0x50 as the identifier code.
;; 0x50 is chosen arbitrarily, because it is unassigned.
(defpathtype [0x50 Point]

  (fn point-encoder [pt]
    (str (:x pt) "x" (:y pt))) ;; e.g. path-type-demo.Point{:x 10 :y 20} becomes "10x20"

  (fn point-decoder [encoded-pt]
    (let [[x y] (str/split encoded-pt #"x")] ;; split the str representation on "x"
      (Point. (read-string x) (read-string y))))) ;; read the x and y values and use them to reconstruct the point

;; test the encoder/decoder pair
(check-path-encoding (Point. 10 20)) ;{:equal true,
                                     ; :initial #path_type_demo.Point{:x 10, :y 20},
                                     ; :decoded #path_type_demo.Point{:x 10, :y 20},
                                     ; :encoded "10x20"}


;; now the type can be used in any path
;; e.g. (assoc-at! some-database [:points (Point. 10 20)] true)

Notes

  • Creating custom path types is advanced functionality which is not required for the vast majority of applications.
  • A database using custom pathtypes will (probably) be unreadable in any program which does not define the exact same pathtype
  • If you believe that a custom pathtype you have defined has generally applicable utility, please submit a PR or open an issue!

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close