zigcc/zig-msgpack
zig messagpack implementation / msgpack.org[zig]
A MessagePack implementation for the Zig programming language. This library provides a simple and efficient way to serialize and deserialize data using the MessagePack format.
An article introducing it: Zig Msgpack
Zig Version | Library Version | Status |
---|---|---|
0.13 and older | 0.0.6 | Legacy support |
0.14.0 | Current | ✅ Fully supported |
0.15.x | Current | ✅ Fully supported |
0.16.0-dev (nightly) | Current | ✅ Supported with compatibility layer |
Note: For Zig 0.13 and older versions, please use version
0.0.6
of this library. Note: Zig 0.16+ removesstd.io.FixedBufferStream
, but this library provides a compatibility layer to maintain the same API across all supported versions.
For Zig 0.14.0
, 0.15.x
, and 0.16.0-dev
, follow these steps:
Add as a dependency:
Add the library to your build.zig.zon
file. You can fetch a specific commit or branch.
zig fetch --save https://github.com/zigcc/zig-msgpack/archive/{COMMIT_OR_BRANCH}.tar.gz
Configure your build.zig
:
Add the zig-msgpack
module to your executable.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "my-app",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const msgpack_dep = b.dependency("zig_msgpack", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("msgpack", msgpack_dep.module("msgpack"));
b.installArtifact(exe);
}
const std = @import("std");
const msgpack = @import("msgpack");
pub fn main() !void {
const allocator = std.heap.page_allocator;
var buffer: [1024]u8 = undefined;
// Use the compatibility layer for cross-version support
const compat = msgpack.compat;
var write_buffer = compat.fixedBufferStream(&buffer);
var read_buffer = compat.fixedBufferStream(&buffer);
const BufferType = compat.BufferStream;
var packer = msgpack.Pack(
*BufferType, *BufferType,
BufferType.WriteError, BufferType.ReadError,
BufferType.write, BufferType.read,
).init(&write_buffer, &read_buffer);
// Create and encode data
var map = msgpack.Payload.mapPayload(allocator);
defer map.free(allocator);
try map.mapPut("name", try msgpack.Payload.strToPayload("Alice", allocator));
try map.mapPut("age", msgpack.Payload.uintToPayload(30));
try packer.write(map);
// Decode
read_buffer.pos = 0;
const decoded = try packer.read(allocator);
defer decoded.free(allocator);
const name = (try decoded.mapGet("name")).?.str.value();
const age = (try decoded.mapGet("age")).?.uint;
std.debug.print("Name: {s}, Age: {d}\n", .{ name, age });
}
// Basic types
const nil_val = msgpack.Payload.nilToPayload();
const bool_val = msgpack.Payload.boolToPayload(true);
const int_val = msgpack.Payload.intToPayload(-42);
const uint_val = msgpack.Payload.uintToPayload(42);
const float_val = msgpack.Payload.floatToPayload(3.14);
// String and binary
const str_val = try msgpack.Payload.strToPayload("hello", allocator);
const bin_val = try msgpack.Payload.binToPayload(&[_]u8{1, 2, 3}, allocator);
// Array
var arr = try msgpack.Payload.arrPayload(2, allocator);
try arr.setArrElement(0, msgpack.Payload.intToPayload(1));
try arr.setArrElement(1, msgpack.Payload.intToPayload(2));
// Extension type
const ext_val = try msgpack.Payload.extToPayload(5, &[_]u8{0xaa, 0xbb}, allocator);
// Create timestamps
const ts1 = msgpack.Payload.timestampFromSeconds(1234567890);
const ts2 = msgpack.Payload.timestampToPayload(1234567890, 123456789);
// Write and read timestamp
try packer.write(ts2);
read_buffer.pos = 0;
const decoded_ts = try packer.read(allocator);
defer decoded_ts.free(allocator);
std.debug.print("Timestamp: {}s + {}ns\n",
.{ decoded_ts.timestamp.seconds, decoded_ts.timestamp.nanoseconds });
std.debug.print("As float: {d}\n", .{ decoded_ts.timestamp.toFloat() });
// Type conversion with error handling
const int_payload = msgpack.Payload.intToPayload(-42);
const uint_result = int_payload.getUint() catch |err| switch (err) {
msgpack.MsGPackError.INVALID_TYPE => {
std.debug.print("Cannot convert negative to unsigned\n");
return;
},
else => return err,
};
msgpack.Pack
: The main struct for packing and unpacking MessagePack data. It is initialized with read and write contexts.msgpack.Payload
: A union that represents any MessagePack type. It provides methods for creating and interacting with different data types (e.g., mapPayload
, strToPayload
, mapGet
).Starting from Zig 0.16, the standard library underwent significant changes to the I/O subsystem. The std.io.FixedBufferStream
was removed as part of a broader redesign. This library includes a compatibility layer (src/compat.zig
) that:
BufferStream
implementation for Zig 0.16+ that mimics the behavior of the old FixedBufferStream
This means you can use the same API regardless of your Zig version, and the library will handle the differences internally.
To run the unit tests for this library, use the following command:
zig build test
# For more detailed test output
zig build test --summary all
To generate documentation for this library:
zig build docs
Contributions are welcome! Please feel free to open an issue or submit a pull request.
This project is licensed under the MIT License. See the LICENSE file for details.