Last active
September 5, 2025 13:25
-
-
Save peterhellberg/65346cabe20318a61fc4e6cb817fe342 to your computer and use it in GitHub Desktop.
Tiny example in Go of using CBOR tags to distinguish between two different types of messages using github.com/fxamacker/cbor/v2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "fmt" | |
| "log" | |
| "github.com/fxamacker/cbor/v2" | |
| ) | |
| const ( | |
| tagChatMessage = 10001 | |
| tagChatPresence = 10002 | |
| ) | |
| type ChatEvent interface { | |
| ChatEventType() string | |
| } | |
| type chatMessage struct { | |
| User string `cbor:"user"` | |
| Message string `cbor:"message"` | |
| } | |
| func (c chatMessage) ChatEventType() string { | |
| return "chatMessage" | |
| } | |
| type chatPresence struct { | |
| User string `cbor:"user"` | |
| Status string `cbor:"status"` | |
| } | |
| func (c chatPresence) ChatEventType() string { | |
| return "chatPresence" | |
| } | |
| func marshal(tagNum uint64, v any) ([]byte, error) { | |
| payloadBytes, err := cbor.Marshal(v) | |
| if err != nil { | |
| return nil, err | |
| } | |
| return cbor.Marshal(cbor.RawTag{ | |
| Number: tagNum, | |
| Content: payloadBytes, | |
| }) | |
| } | |
| func unmarshal(data []byte) (ChatEvent, error) { | |
| var tag cbor.RawTag | |
| if err := cbor.Unmarshal(data, &tag); err != nil { | |
| return nil, fmt.Errorf("failed to unmarshal tag: %w", err) | |
| } | |
| switch tag.Number { | |
| case tagChatMessage: | |
| var msg chatMessage | |
| return msg, cbor.Unmarshal(tag.Content, &msg) | |
| case tagChatPresence: | |
| var pres chatPresence | |
| return pres, cbor.Unmarshal(tag.Content, &pres) | |
| default: | |
| return nil, fmt.Errorf("unknown tag: %d", tag.Number) | |
| } | |
| } | |
| func main() { | |
| var ( | |
| msg = chatMessage{User: "alice", Message: "hello!"} | |
| pres = chatPresence{User: "bob", Status: "away"} | |
| ) | |
| msgBytes, err := marshal(tagChatMessage, msg) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| presBytes, err := marshal(tagChatPresence, pres) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| for _, data := range [][]byte{ | |
| msgBytes, | |
| presBytes, | |
| } { | |
| event, err := unmarshal(data) | |
| if err != nil { | |
| log.Fatal(err) | |
| } else { | |
| fmt.Printf("Decoded data: %#v\n", event) | |
| } | |
| switch e := event.(type) { | |
| case chatMessage: | |
| fmt.Println("Message from:", e.User) | |
| case chatPresence: | |
| fmt.Println("Presence update:", e.User, e.Status) | |
| } | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TinyCBOR version in C (compiled using
zig cc)Download and unpack tinycbor v0.6.1 into
tinycbor-0.6.1/curl -s -L https://github.com/intel/tinycbor/archive/refs/tags/v0.6.1.tar.gz | tar xvzc-cbor-tagged-messages.cMakefileResult