Improve default serdes for primitive-adjacent types

This commit is contained in:
Joshua Suskalo 2021-09-16 16:35:08 -05:00
parent 3dcbe3ff2a
commit 0e2fc6f458

View file

@ -265,7 +265,7 @@
[obj type segment scope] [obj type segment scope]
(if-some [prim-layout (primitive-type type)] (if-some [prim-layout (primitive-type type)]
(serialize-into (serialize* obj type scope) prim-layout segment scope) (serialize-into (serialize* obj type scope) prim-layout segment scope)
(throw (ex-info "Attempted to serialize an object to a type that has not been overriden." (throw (ex-info "Attempted to serialize an object to a type that has not been overriden"
{:type type {:type type
:object obj})))) :object obj}))))
@ -318,15 +318,28 @@
(let [segment (alloc-instance type scope)] (let [segment (alloc-instance type scope)]
(serialize-into obj type segment scope))))) (serialize-into obj type segment scope)))))
(declare deserialize) (declare deserialize deserialize*)
(defmulti deserialize-from (defmulti deserialize-from
"Deserializes the given segment into a Clojure data structure." "Deserializes the given segment into a Clojure data structure.
For types that serialize to primitives, a default implementation will
deserialize the primitive before calling [[deserialize*]]."
(fn (fn
#_{:clj-kondo/ignore [:unused-binding]} #_{:clj-kondo/ignore [:unused-binding]}
[segment type] [segment type]
(type-dispatch type))) (type-dispatch type)))
(defmethod deserialize-from :default
[segment type]
(if-some [prim (primitive-type type)]
(-> segment
(deserialize-from prim)
(deserialize* type))
(throw (ex-info "Attempted to deserialize a non-primitive type that has not been overriden"
{:type type
:segment segment}))))
(defmethod deserialize-from ::byte (defmethod deserialize-from ::byte
[segment _type] [segment _type]
(MemoryAccess/getByte segment)) (MemoryAccess/getByte segment))
@ -377,8 +390,12 @@
(type-dispatch type))) (type-dispatch type)))
(defmethod deserialize* :default (defmethod deserialize* :default
[obj _type] [obj type]
obj) (if (primitive-type type)
obj
(throw (ex-info "Attempted to deserialize a non-primitive type with primitive methods"
{:type type
:segment obj}))))
(defmethod deserialize* ::pointer (defmethod deserialize* ::pointer
[addr type] [addr type]
@ -410,12 +427,6 @@
[obj _type scope] [obj _type scope]
(address-of (CLinker/toCString (str obj) ^ResourceScope scope))) (address-of (CLinker/toCString (str obj) ^ResourceScope scope)))
(defmethod deserialize-from ::c-string
[segment type]
(-> segment
(deserialize-from ::pointer)
(deserialize* type)))
(defmethod deserialize* ::c-string (defmethod deserialize* ::c-string
[addr _type] [addr _type]
(CLinker/toJavaString ^MemoryAddress addr)) (CLinker/toJavaString ^MemoryAddress addr))