Add enum serdes
This commit is contained in:
parent
d7e0ced38b
commit
2646e6fc9e
2 changed files with 44 additions and 1 deletions
|
|
@ -1104,7 +1104,7 @@ These features are planned for future releases.
|
||||||
- Support for va_args type
|
- Support for va_args type
|
||||||
- Header parsing tool for generating a data model?
|
- Header parsing tool for generating a data model?
|
||||||
- Generic type aliases
|
- Generic type aliases
|
||||||
- Helpers for generating enums & bitflags
|
- Helpers for generating bitflags
|
||||||
- Unsigned integer types
|
- Unsigned integer types
|
||||||
- Record-based struct types
|
- Record-based struct types
|
||||||
- Helper macro for out arguments
|
- Helper macro for out arguments
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
use [[with-acquired]] on the [[segment-scope]] in order to ensure it won't be
|
use [[with-acquired]] on the [[segment-scope]] in order to ensure it won't be
|
||||||
released during its manipulation."
|
released during its manipulation."
|
||||||
(:require
|
(:require
|
||||||
|
[clojure.set :as set]
|
||||||
[clojure.spec.alpha :as s])
|
[clojure.spec.alpha :as s])
|
||||||
(:import
|
(:import
|
||||||
(java.nio ByteOrder)
|
(java.nio ByteOrder)
|
||||||
|
|
@ -1235,6 +1236,48 @@
|
||||||
(slice-segments (slice segment 0 (* count (size-of type)))
|
(slice-segments (slice segment 0 (* count (size-of type)))
|
||||||
(size-of type))))
|
(size-of type))))
|
||||||
|
|
||||||
|
;;; Enum types
|
||||||
|
|
||||||
|
(defmethod primitive-type ::enum
|
||||||
|
[[_enum _variants & {:keys [repr]}]]
|
||||||
|
(if repr
|
||||||
|
(primitive-type repr)
|
||||||
|
::int))
|
||||||
|
|
||||||
|
(defn- enum-variants-map
|
||||||
|
"Constructs a map from enum variant objects to their native representations.
|
||||||
|
|
||||||
|
Enums are mappings from Clojure objects to numbers, with potential default
|
||||||
|
values for each element based on order.
|
||||||
|
|
||||||
|
If `variants` is a map, then every variant has a value provided already (a
|
||||||
|
guarantee of maps in Clojure's syntax) and we are done.
|
||||||
|
|
||||||
|
If `variants` is a vector then we assume C-style implicit enum values,
|
||||||
|
counting from 0. If an element of `variants` itself is a vector, it must be a
|
||||||
|
vector tuple of the variant object to the native representation, with further
|
||||||
|
counting continuing from that value."
|
||||||
|
[variants]
|
||||||
|
(if (map? variants)
|
||||||
|
variants
|
||||||
|
(reduce
|
||||||
|
(fn [[m next-id] variant]
|
||||||
|
(if (vector? variant)
|
||||||
|
[(conj m variant) (inc (second variant))]
|
||||||
|
[(assoc m variant next-id) (inc next-id)]))
|
||||||
|
[{} 0]
|
||||||
|
variants)))
|
||||||
|
|
||||||
|
(defmethod serialize* ::enum
|
||||||
|
[obj [_enum variants & {:keys [repr]}] scope]
|
||||||
|
(serialize* ((enum-variants-map variants) obj)
|
||||||
|
(or repr ::int)
|
||||||
|
scope))
|
||||||
|
|
||||||
|
(defmethod deserialize* ::enum
|
||||||
|
[obj [_enum variants & {:keys [_repr]}]]
|
||||||
|
((set/map-invert (enum-variants-map variants)) obj))
|
||||||
|
|
||||||
(s/def ::type
|
(s/def ::type
|
||||||
(s/spec
|
(s/spec
|
||||||
(s/nonconforming
|
(s/nonconforming
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue