e20a0a8

Branches > namespace-reorganization > e20a0a8 > files / src / net / bowmap / packet_handling.clj

Add uuid, list, table, optional, and context optional writers

Grahp, 2026-02-27

Commit: e20a0a8a4b1e39458e1962906c1f8263d9188b51
Parent: eb8dec1

1 changed file:

src/net/bowmap/codecs/write.clj modified (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#)))})