mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
127 lines
2.8 KiB
Clojure
127 lines
2.8 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) UXBOX Labs SL
|
|
|
|
(ns app.util.transit
|
|
"A lightweight abstraction for transit serialization."
|
|
(:require
|
|
[cognitect.transit :as t]
|
|
[linked.core :as lk]
|
|
[linked.set :as lks]
|
|
[app.common.data :as d]
|
|
[app.common.geom.point :as gpt]
|
|
[app.common.geom.matrix :as gmt]
|
|
[app.util.time :as dt]))
|
|
|
|
(deftype Blob [content]
|
|
IDeref
|
|
(-deref [_] content))
|
|
|
|
(defn blob?
|
|
[v]
|
|
(instance? Blob v))
|
|
|
|
(def blob-write-handler
|
|
(t/write-handler
|
|
(constantly "jsonblob")
|
|
(fn [v] (js/JSON.stringify @v))))
|
|
|
|
(def blob-read-handler
|
|
(t/read-handler
|
|
(fn [value]
|
|
(->Blob (js/JSON.parse value)))))
|
|
|
|
;; --- Transit adapters
|
|
|
|
(def bigint-read-handler
|
|
(t/read-handler
|
|
(fn [value]
|
|
(js/parseInt value 10))))
|
|
|
|
(def point-write-handler
|
|
(t/write-handler
|
|
(constantly "point")
|
|
(fn [v] (into {} v))))
|
|
|
|
(def point-read-handler
|
|
(t/read-handler
|
|
(fn [value]
|
|
(gpt/map->Point value))))
|
|
|
|
(def matrix-write-handler
|
|
(t/write-handler
|
|
(constantly "matrix")
|
|
(fn [v] (into {} v))))
|
|
|
|
(def matrix-read-handler
|
|
(t/read-handler
|
|
(fn [value]
|
|
(gmt/map->Matrix value))))
|
|
|
|
(def ordered-set-write-handler
|
|
(t/write-handler
|
|
(constantly "ordered-set")
|
|
(fn [v] (vec v))))
|
|
|
|
(def ordered-set-read-handler
|
|
(t/read-handler #(into (lk/set) %)))
|
|
|
|
(def date-read-handler
|
|
(t/read-handler (fn [value] (-> value (js/parseInt 10) (dt/datetime)))))
|
|
|
|
(def duration-read-handler
|
|
(t/read-handler (fn [value] (dt/duration value))))
|
|
|
|
(def date-write-handler
|
|
(t/write-handler
|
|
(constantly "m")
|
|
(fn [v] (str (inst-ms v)))))
|
|
|
|
(def duration-write-handler
|
|
(t/write-handler
|
|
(constantly "duration")
|
|
(fn [v] (inst-ms v))))
|
|
|
|
;; --- Transit Handlers
|
|
|
|
(def ^:privare +read-handlers+
|
|
{"u" uuid
|
|
"n" bigint-read-handler
|
|
"ordered-set" ordered-set-read-handler
|
|
"jsonblob" blob-read-handler
|
|
"matrix" matrix-read-handler
|
|
"m" date-read-handler
|
|
"duration" duration-read-handler
|
|
"point" point-read-handler})
|
|
|
|
(def ^:privare +write-handlers+
|
|
{gmt/Matrix matrix-write-handler
|
|
Blob blob-write-handler
|
|
dt/DateTime date-write-handler
|
|
dt/Duration duration-write-handler
|
|
lks/LinkedSet ordered-set-write-handler
|
|
gpt/Point point-write-handler})
|
|
|
|
;; --- Public Api
|
|
|
|
(defn decode
|
|
[data]
|
|
(let [r (t/reader :json {:handlers +read-handlers+})]
|
|
(t/read r data)))
|
|
|
|
(defn encode
|
|
[data]
|
|
(try
|
|
(let [w (t/writer :json-verbose {:handlers +write-handlers+})]
|
|
(t/write w data))
|
|
(catch :default e
|
|
(throw e))))
|
|
|
|
(defn transit?
|
|
"Checks if a string can be decoded with transit"
|
|
[str]
|
|
(try
|
|
(-> str decode nil? not)
|
|
(catch js/SyntaxError e false)))
|