Add support for flagset composite types

This commit is contained in:
Joshua Suskalo 2022-07-07 16:08:41 -05:00
parent c0dee46fe9
commit e9a5b640ac
No known key found for this signature in database
GPG key ID: 9B6BA586EFF1B9F0
2 changed files with 22 additions and 1 deletions

View file

@ -1104,7 +1104,6 @@ These features are planned for future releases.
- Support for va_args type
- Header parsing tool for generating a data model?
- Generic type aliases
- Helpers for generating bitflags
- Unsigned integer types
- Record-based struct types
- Helper macro for out arguments

View file

@ -1279,6 +1279,28 @@
[obj [_enum variants & {:keys [_repr]}]]
((set/map-invert (enum-variants-map variants)) obj))
;;; Flagsets
(defmethod primitive-type ::flagset
[[_flagset _bits & {:keys [repr]}]]
(if repr
(primitive-type repr)
::int))
(defmethod serialize* ::flagset
[obj [_flagset bits & {:keys [repr]}] scope]
(let [bits-map (enum-variants-map bits)]
(reduce #(bit-set %1 (get bits-map %2)) (serialize* 0 (or repr ::int) scope) obj)))
(defmethod deserialize* ::flagset
[obj [_flagset bits & {:keys [repr]}]]
(let [bits-map (set/map-invert (enum-variants-map bits))]
(reduce #(if-not (zero? (bit-and 1 (bit-shift-right obj %2)))
(conj %1 (bits-map %2))
%1)
#{}
(range (* 8 (size-of (or repr ::int)))))))
(s/def ::type
(s/spec
(s/nonconforming