mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-16 16:01:26 -07:00
encoding/cbor: add a custom tag to the example
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user