Add section about unions
This commit is contained in:
parent
381ca1e636
commit
364af931c5
1 changed files with 40 additions and 1 deletions
41
README.md
41
README.md
|
|
@ -411,7 +411,46 @@ Deserialization is a little more complex. First the tag is retrieved from the
|
||||||
beginning of the segment, and then the type of the value is decided based on
|
beginning of the segment, and then the type of the value is decided based on
|
||||||
that before it is deserialized.
|
that before it is deserialized.
|
||||||
|
|
||||||
### TODO Unions
|
### Unions
|
||||||
|
In the last section the custom serialization and deserialization of a tagged
|
||||||
|
union used a union from coffi in order to define the native layout, but not for
|
||||||
|
actual serialization or deserialization. This is intentional. A union in coffi
|
||||||
|
is rather limited. It can be serialized, but not deserialized without external
|
||||||
|
information.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
[::ffi/union
|
||||||
|
#{::ffi/float ::ffi/double}
|
||||||
|
:dispatch #(cond
|
||||||
|
(float? %) ::ffi/float
|
||||||
|
(double? %) ::ffi/double)]
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a minimal union in coffi. If the `:dispatch` keyword argument is not
|
||||||
|
passed, then the union cannot be serialized, as coffi would not know which type
|
||||||
|
to serialize the values as. In the example with a tagged union, a dispatch
|
||||||
|
function was not provided because the type was only used for the native layout.
|
||||||
|
|
||||||
|
In addition to a dispatch function, when serializing a union an extract function
|
||||||
|
may also be provided. In the case of the value in the tagged union from before,
|
||||||
|
it could be represented for serialization purposes like so:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
[::ffi/union
|
||||||
|
#{::ffi/int ::ffi/c-string}
|
||||||
|
:dispatch #(case (first %)
|
||||||
|
:ok ::ffi/int
|
||||||
|
:err ::ffi/c-string)
|
||||||
|
:extract second]
|
||||||
|
```
|
||||||
|
|
||||||
|
This union however would not include the tag when serialized.
|
||||||
|
|
||||||
|
If a union is deserialized, then all that coffi does is to allocate a new
|
||||||
|
segment of the appropriate size with an implicit scope so that it may later be
|
||||||
|
garbage collected, and copies the data from the source segment into it. It's up
|
||||||
|
to the user to call `deserialize-from` on that segment with the appropriate
|
||||||
|
type.
|
||||||
|
|
||||||
### TODO Data Model
|
### TODO Data Model
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue