encoding/cbor: add a custom tag to the example

This commit is contained in:
Laytan Laats
2024-07-08 01:01:11 +02:00
parent db3b4ceb4a
commit 6ab559437a
+33 -5
View File
@@ -77,8 +77,11 @@ You can look at the default tags provided for pointers on how these implementati
Example:
package main
import "base:intrinsics"
import "core:encoding/cbor"
import "core:fmt"
import "core:reflect"
import "core:time"
Possibilities :: union {
@@ -93,9 +96,32 @@ Example:
ignore_this: ^Data `cbor:"-"`, // Ignored by implementation.
renamed: f32 `cbor:"renamed :)"`, // Renamed when encoded.
my_union: Possibilities, // Union support.
my_raw: [8]u32 `cbor_tag:"raw"`, // Custom tag that just writes the value as bytes.
}
main :: proc() {
// Example custom tag implementation that instead of breaking down all parts,
// just writes the value as a big byte blob. This is an advanced feature but very powerful.
RAW_TAG_NR :: 200
cbor.tag_register_number({
marshal = proc(_: ^cbor.Tag_Implementation, e: cbor.Encoder, v: any) -> cbor.Marshal_Error {
cbor._encode_u8(e.writer, RAW_TAG_NR, .Tag) or_return
return cbor.err_conv(cbor._encode_bytes(e, reflect.as_bytes(v)))
},
unmarshal = proc(_: ^cbor.Tag_Implementation, d: cbor.Decoder, _: cbor.Tag_Number, v: any) -> (cbor.Unmarshal_Error) {
hdr := cbor._decode_header(d.reader) or_return
maj, add := cbor._header_split(hdr)
if maj != .Bytes {
return .Bad_Tag_Value
}
bytes := cbor.err_conv(cbor._decode_bytes(d, add, maj)) or_return
intrinsics.mem_copy_non_overlapping(v.data, raw_data(bytes), len(bytes))
return nil
},
}, RAW_TAG_NR, "raw")
now := time.Time{_nsec = 1701117968 * 1e9}
data := Data{
@@ -105,21 +131,22 @@ Example:
ignore_this = &Data{},
renamed = 123123.125,
my_union = 3,
my_raw = {1=1, 2=2, 3=3},
}
// Marshal the struct into binary CBOR.
binary, err := cbor.marshal(data, cbor.ENCODE_FULLY_DETERMINISTIC)
assert(err == nil)
fmt.assertf(err == nil, "marshal error: %v", err)
defer delete(binary)
// Decode the binary data into a `cbor.Value`.
decoded, derr := cbor.decode(string(binary))
assert(derr == nil)
fmt.assertf(derr == nil, "decode error: %v", derr)
defer cbor.destroy(decoded)
// Turn the CBOR into a human readable representation defined as the diagnostic format in [[RFC 8949 Section 8;https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation]].
diagnosis, eerr := cbor.to_diagnostic_format(decoded)
assert(eerr == nil)
fmt.assertf(eerr == nil, "to diagnostic error: %v", eerr)
defer delete(diagnosis)
fmt.println(diagnosis)
@@ -127,6 +154,7 @@ Example:
Output:
{
"my_raw": 200(h'00001000200030000000000000000000'),
"my_union": 1010([
"int",
3