How to decode and encode MessagePack values¶
Decode a value¶
rustruct.formats.msgpack.decode() turns a buffer holding exactly one
MessagePack value into the matching Python object – None, bool, int,
float, bytes, str, list, or dict:
from rustruct.formats.msgpack import decode
assert decode(b"\xc0") is None
assert decode(b"\x2a") == 42
assert decode(b"\xa5hello") == "hello"
assert decode(b"\x92\x01\x02") == [1, 2]
assert decode(b"\x81\xa1a\x01") == {"a": 1}
Use decode_from(buf, offset)
instead when the buffer holds more than one
value back to back, or more data than just the value (a length-prefixed
frame, for example): it returns (value, new_offset) rather than raising on
trailing bytes, so the caller can keep decoding from where it left off:
from rustruct.formats.msgpack import decode_from
wire = b"\x01\xa3two\x93\x03\x03\x03" # 1, "two", [3, 3, 3]
first, offset = decode_from(wire, 0)
second, offset = decode_from(wire, offset)
third, offset = decode_from(wire, offset)
assert (first, second, third) == (1, "two", [3, 3, 3])
assert offset == len(wire)
decode() is
decode_from() plus a check
that nothing follows the one value it read.
Encode a value¶
rustruct.formats.msgpack.encode() takes a Python None/bool/int/
float/bytes/str/list/dict value (containers may nest any of these,
including further containers) and returns its MessagePack encoding, choosing
the most compact tag that fits – the same preference the reference
implementation uses, byte for byte, on the common cases:
from rustruct.formats.msgpack import encode
assert encode(None) == b"\xc0"
assert encode(42) == b"\x2a"
assert encode(-1) == b"\xff"
assert encode("hello") == b"\xa5hello"
assert encode([1, 2]) == b"\x92\x01\x02"
assert encode({"a": 1}) == b"\x81\xa1a\x01"
decode() reverses it:
from rustruct.formats.msgpack import decode
value = {"name": "sensor-1", "readings": [20.5, 21.0, 19.75], "active": True}
wire = encode(value)
assert decode(wire) == value
Dict keys keep their insertion order on the wire; MessagePack itself has no
ordering requirement, but encode()/
decode() agree with each other
and with dict’s own iteration order.