e20a0a8
Branches > main > e20a0a8 > files
Add uuid, list, table, optional, and context optional writers
Commit: e20a0a8a4b1e39458e1962906c1f8263d9188b51
Parent: eb8dec1
1 changed file:
src/net/bowmap/codecs/write.clj view file
@@ -1,10 +1,14 @@ (ns net.bowmap.codecs.write (:require+ [clojure.alpha.spec :as s] [clojure.data.json :as json]- [dev.grahp.error :refer [raise]])+ [dev.grahp.error :refer [raise]]+ [net.bowmap.codecs.types :as types]+ [net.bowmap.packets.registry :as reg]) (:import- [io.netty.buffer ByteBuf]- [java.nio.charset Charset]))+ [io.netty.buffer ByteBuf Unpooled]+ [java.nio.charset Charset]+ [java.util UUID])) (defn write-varint! [buf n] (loop [buf buf@@ -24,16 +28,41 @@ (defn write-json! [buf s] (write-string! buf (json/write-str s))) -(declare writer writers)+(defn write-list! [buf t xs]+ (doseq [x xs]+ (t buf x)))++(defn write-uuid! [buf uuid]+ (ByteBuf/.writeLong buf (UUID/.getMostSignificantBits uuid))+ (ByteBuf/.writeLong buf (UUID/.getLeastSignificantBits uuid)))++;; TODO this is where optionality and nil checking should be, and the packet stuff should use this.+(defn write-table! [buf t? m]+ (doseq [{:keys [field type]} t?]+ (type buf (get m field))))++(declare writers) ;; I think this should have :required/:optional/:prefixed-optional, ;; and have it that non-optional fields are implicity :required and thus nil checked (defn writer "Returns a form that will evaluate to a function that takes a buffer and writes the respective type to it."- ([t]- (or (writers t) (raise "No such type!" {:type t})))- ([t & args]- (apply (writer t) args)))+ [t]+ (if (vector? t)+ (let [[t & args] t]+ (apply (writer t) args))+ (or (writers t)+ (raise (str "No such type! " (name t)) {:type t}))))++(defn write-boolean! [buf x]+ (if x+ (ByteBuf/.writeByte buf 1)+ (ByteBuf/.writeByte buf 0)))++(defn write-context-optional! [buf codec x]+ (if x+ (codec buf x)+ buf)) (def writers {:byte `ByteBuf/.writeByte@@ -44,4 +73,20 @@ :long `ByteBuf/.writeLong :varint `write-varint! :string `write-string!- :json `write-json!})+ :json `write-json!+ :uuid `write-uuid!+ ;; TODO These are kinda named backwards...+ :context-optional (fn [t]+ `(fn ~'write-context-optional [buf# x#]+ (write-context-optional! buf# ~(writer t) x#)))+ :optional (fn [t]+ `(fn ~'write-optional [buf# x#]+ (write-boolean! buf# x#)+ (write-context-optional! buf# ~(writer t) x#)))+ :table (fn [t]+ ;; TODO needs to be moved yeah.+ (let [t (->> (s/conform ::reg/table t)+ (mapv #(update % :type writer)))]+ `(fn ~'write-table [buf# m#] (write-table! buf# ~t m#))))+ :list (fn [t]+ `(fn ~'write-list [buf# xs#] (write-list! buf# ~(writer t) xs#)))})