https://github.com/doglooksgood/borsh-clj
A pure Clojure/Script implementation for Borsh
https://github.com/doglooksgood/borsh-clj
Last synced: about 1 year ago
JSON representation
A pure Clojure/Script implementation for Borsh
- Host: GitHub
- URL: https://github.com/doglooksgood/borsh-clj
- Owner: DogLooksGood
- License: mit
- Created: 2023-05-24T15:08:41.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2023-12-26T05:06:40.000Z (over 2 years ago)
- Last Synced: 2023-12-26T06:20:55.388Z (over 2 years ago)
- Language: Clojure
- Size: 76.2 KB
- Stars: 6
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# borsh-clj [](https://github.com/DogLooksGood/borsh-clj/actions/workflows/test.yml) [](https://clojars.org/io.github.doglooksgood/borsh-clj)
A pure Clojure/Script implementation for [Borsh](https://borsh.io/), the binary serializer for security-critical projects.
## Examples
```clojure
(require '[borsh.macros :as m]
'[borsh.core :as borsh])
;; Define schemas
(m/defstruct Point
[^:u32 x
^:u32 y])
(m/defstruct Rect
[^{:struct Point} p1
^{:struct Point} p2])
(def r (->Rect
(->Point 0 0)
(->Point 42 42)))
;; Serialize an object
(def bs (borsh/serialize r))
;; Deserialize a byte array
(def r1 (borsh/deserialize ->Rect bs))
```
## Type Mappings
| Borsh | Clojure | Meta |
|--------------------------|----------------------|-------------------------------|
| boolean | Boolean | `^:bool` |
| `u8` integer | Long or Number | `^:u8` |
| `u16` integer | Long or Number | `^:u16` |
| `u32` integer | Long or Number | `^:u32` |
| `u64` integer | Long or BigInt | `^:u64` |
| `usize` integer | Long or Number | `^:usize` |
| UTF-8 String | String | `^:string` |
| Option | `nil` or type | `^{:option type}` |
| Vec | Vector | `^{:vec item-type}` |
| Map | HashMap | `^{:map [key-type val-type]}` |
| Struct | Record | `^{:struct record}` |
| Simple enum | Keyword | `^{:enum [kws]}` |
| Enum of structs | Record | `^{:enum variants}` |
| Dynamic-sized byte array | Byte[] or Uint8Array | `^:bytes` |
| Extended type | | `^{:ext ext}` |
## Enums
Simple enums can be defined with a vector of keywords
```clojure
(require '[borsh.macros :as m])
(m/defstruct HasStatus
[^{:enum [:status/a :status/b]} status])
;; Another approach
(def status-enums [:status/a :status/b])
(m/defstruct HasStatus
[^{:enum status-enums} status])
```
Complicated enums can be defined with `borsh.macro/defvariants`.
```clojure
(require '[borsh.macros :as m])
(m/defstruct Point [^:u64 x ^:u64 y])
(m/defstruct Line [^{:struct Point} p1 ^{:struct Point} p2])
(m/defvariants shapes [Point Line])
(m/defstruct HasVariants
[^{:enum shapes} shape])
```
## Extended Types
To extend a custom type, use `IExtendWriter` and `IExtendReader`.
```clojure
(require '[borsh.ext :as ext]
'[borsh.types :as t]
'[borsh.macros :as m])
(defrecord DateExt [])
(extend-type DateExt
ext/IExtendWriter
(write [this buf value] ;; the type of value is java.util.Date
(t/write-u64 buf (.getTime value)))
ext/IExtendReader
(read [this buf] ;; return java.util.Date
(java.util.Date. (t/read-u64 buf))))
(def date-ext (->DateExt))
(m/defstruct X [^{:ext date-ext} date])
```