Skip to content

Commit 3377126

Browse files
committed
docs(readme): update and expand documentation, add Chinese translation
- update README.md with timestamp extension support and improved usage examples - add detailed sections for data types, timestamp usage, and error handling - fix formatting and clarify API overview and related projects - add README_CN.md providing a comprehensive Chinese translation of the documentation
1 parent 00a2aa7 commit 3377126

File tree

2 files changed

+250
-30
lines changed

2 files changed

+250
-30
lines changed

README.md

Lines changed: 75 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ An article introducing it: [Zig Msgpack](https://blog.nvimer.org/2025/05/03/zig-
88

99
## Features
1010

11-
- **Full MessagePack Support:** Implements all MessagePack types (except for the timestamp extension).
11+
- **Full MessagePack Support:** Implements all MessagePack types including the timestamp extension.
12+
- **Timestamp Support:** Complete implementation of MessagePack timestamp extension type (-1) with support for all three formats (32-bit, 64-bit, and 96-bit).
1213
- **Efficient:** Designed for high performance with minimal memory overhead.
1314
- **Type-Safe:** Leverages Zig's type system to ensure safety during serialization and deserialization.
1415
- **Simple API:** Offers a straightforward and easy-to-use API for encoding and decoding.
@@ -56,56 +57,100 @@ For Zig `0.14.0` and `nightly`, follow these steps:
5657

5758
## Usage
5859

59-
Here is a simple example of how to encode and decode a `Payload`:
60+
### Basic Usage
6061

6162
```zig
6263
const std = @import("std");
6364
const msgpack = @import("msgpack");
64-
const allocator = std.testing.allocator;
6565
6666
pub fn main() !void {
67+
const allocator = std.heap.page_allocator;
6768
var buffer: [1024]u8 = undefined;
6869
var stream = std.io.fixedBufferStream(&buffer);
6970
7071
var packer = msgpack.Pack(
71-
*std.io.FixedBufferStream([]u8),
72-
*std.io.FixedBufferStream([]u8),
73-
std.io.FixedBufferStream([]u8).WriteError,
74-
std.io.FixedBufferStream([]u8).ReadError,
75-
std.io.FixedBufferStream([]u8).write,
76-
std.io.FixedBufferStream([]u8).read,
72+
*std.io.FixedBufferStream([]u8), *std.io.FixedBufferStream([]u8),
73+
std.io.FixedBufferStream([]u8).WriteError, std.io.FixedBufferStream([]u8).ReadError,
74+
std.io.FixedBufferStream([]u8).write, std.io.FixedBufferStream([]u8).read,
7775
).init(&stream, &stream);
7876
79-
// Create a map payload
77+
// Create and encode data
8078
var map = msgpack.Payload.mapPayload(allocator);
8179
defer map.free(allocator);
82-
83-
try map.mapPut("message", try msgpack.Payload.strToPayload("Hello, MessagePack!", allocator));
84-
try map.mapPut("version", msgpack.Payload.uintToPayload(1));
85-
86-
// Encode
80+
try map.mapPut("name", try msgpack.Payload.strToPayload("Alice", allocator));
81+
try map.mapPut("age", msgpack.Payload.uintToPayload(30));
8782
try packer.write(map);
8883
89-
// Reset stream for reading
84+
// Decode
9085
stream.pos = 0;
86+
const decoded = try packer.read(allocator);
87+
defer decoded.free(allocator);
88+
89+
const name = (try decoded.mapGet("name")).?.str.value();
90+
const age = (try decoded.mapGet("age")).?.uint;
91+
std.debug.print("Name: {s}, Age: {d}\n", .{ name, age });
92+
}
93+
```
9194
92-
// Decode
93-
const decoded_payload = try packer.read(allocator);
94-
defer decoded_payload.free(allocator);
95+
### Data Types
9596
96-
// Use the decoded data
97-
const message = (try decoded_payload.mapGet("message")).?.str.value();
98-
const version = (try decoded_payload.mapGet("version")).?.uint;
97+
```zig
98+
// Basic types
99+
const nil_val = msgpack.Payload.nilToPayload();
100+
const bool_val = msgpack.Payload.boolToPayload(true);
101+
const int_val = msgpack.Payload.intToPayload(-42);
102+
const uint_val = msgpack.Payload.uintToPayload(42);
103+
const float_val = msgpack.Payload.floatToPayload(3.14);
104+
105+
// String and binary
106+
const str_val = try msgpack.Payload.strToPayload("hello", allocator);
107+
const bin_val = try msgpack.Payload.binToPayload(&[_]u8{1, 2, 3}, allocator);
108+
109+
// Array
110+
var arr = try msgpack.Payload.arrPayload(2, allocator);
111+
try arr.setArrElement(0, msgpack.Payload.intToPayload(1));
112+
try arr.setArrElement(1, msgpack.Payload.intToPayload(2));
113+
114+
// Extension type
115+
const ext_val = try msgpack.Payload.extToPayload(5, &[_]u8{0xaa, 0xbb}, allocator);
116+
```
99117
100-
std.debug.print("Message: {s}, Version: {d}
101-
", .{ message, version });
102-
}
118+
### Timestamp Usage
119+
120+
```zig
121+
// Create timestamps
122+
const ts1 = msgpack.Payload.timestampFromSeconds(1234567890);
123+
const ts2 = msgpack.Payload.timestampToPayload(1234567890, 123456789);
124+
125+
// Write and read timestamp
126+
try packer.write(ts2);
127+
stream.pos = 0;
128+
const decoded_ts = try packer.read(allocator);
129+
defer decoded_ts.free(allocator);
130+
131+
std.debug.print("Timestamp: {}s + {}ns\n",
132+
.{ decoded_ts.timestamp.seconds, decoded_ts.timestamp.nanoseconds });
133+
std.debug.print("As float: {d}\n", .{ decoded_ts.timestamp.toFloat() });
134+
```
135+
136+
### Error Handling
137+
138+
```zig
139+
// Type conversion with error handling
140+
const int_payload = msgpack.Payload.intToPayload(-42);
141+
const uint_result = int_payload.getUint() catch |err| switch (err) {
142+
msgpack.MsGPackError.INVALID_TYPE => {
143+
std.debug.print("Cannot convert negative to unsigned\n");
144+
return;
145+
},
146+
else => return err,
147+
};
103148
```
104149
105150
## API Overview
106151
107-
- **`msgpack.Pack`**: The main struct for packing and unpacking MessagePack data. It is initialized with read and write contexts.
108-
- **`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`).
152+
- **`msgpack.Pack`**: The main struct for packing and unpacking MessagePack data. It is initialized with read and write contexts.
153+
- **`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`).
109154
110155
## Testing
111156
@@ -121,9 +166,9 @@ Contributions are welcome! Please feel free to open an issue or submit a pull re
121166
122167
## Related Projects
123168
124-
- [getty-msgpack](https://git.mzte.de/LordMZTE/getty-msgpack)
125-
- [znvim](https://github.com/jinzhongjia/znvim)
169+
- [getty-msgpack](https://git.mzte.de/LordMZTE/getty-msgpack)
170+
- [znvim](https://github.com/jinzhongjia/znvim)
126171
127172
## License
128173
129-
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
174+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

README_CN.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# zig-msgpack
2+
3+
[![CI](https://github.com/zigcc/zig-msgpack/actions/workflows/ci.yml/badge.svg)](https://github.com/zigcc/zig-msgpack/actions/workflows/ci.yml)
4+
5+
Zig 编程语言的 MessagePack 实现。此库提供了一种简单高效的方式来使用 MessagePack 格式序列化和反序列化数据。
6+
7+
相关介绍文章: [Zig Msgpack](https://blog.nvimer.org/2025/05/03/zig-msgpack/)
8+
9+
## 特性
10+
11+
- **完整的 MessagePack 支持**: 实现了所有 MessagePack 类型,包括时间戳扩展类型。
12+
- **时间戳支持**: 完整实现 MessagePack 时间戳扩展类型 (-1),支持所有三种格式(32位、64位和96位)。
13+
- **高效**: 设计追求高性能,内存开销最小。
14+
- **类型安全**: 利用 Zig 的类型系统确保序列化和反序列化期间的安全性。
15+
- **简单的 API**: 提供直观易用的编码和解码 API。
16+
17+
## 安装
18+
19+
> 对于 Zig 0.13 及更早版本,请使用本库的 `0.0.6` 版本。
20+
21+
对于 Zig `0.14.0``nightly` 版本,请按以下步骤操作:
22+
23+
1. **添加为依赖项**:
24+
将库添加到您的 `build.zig.zon` 文件中。您可以获取特定的提交或分支。
25+
26+
```sh
27+
zig fetch --save https://github.com/zigcc/zig-msgpack/archive/{COMMIT_OR_BRANCH}.tar.gz
28+
```
29+
30+
2. **配置您的 `build.zig`**:
31+
`zig-msgpack` 模块添加到您的可执行文件中。
32+
33+
```zig
34+
const std = @import("std");
35+
36+
pub fn build(b: *std.Build) void {
37+
const target = b.standardTargetOptions(.{});
38+
const optimize = b.standardOptimizeOption(.{});
39+
40+
const exe = b.addExecutable(.{
41+
.name = "my-app",
42+
.root_source_file = .{ .path = "src/main.zig" },
43+
.target = target,
44+
.optimize = optimize,
45+
});
46+
47+
const msgpack_dep = b.dependency("zig_msgpack", .{
48+
.target = target,
49+
.optimize = optimize,
50+
});
51+
52+
exe.root_module.addImport("msgpack", msgpack_dep.module("msgpack"));
53+
54+
b.installArtifact(exe);
55+
}
56+
```
57+
58+
## 使用方法
59+
60+
### 基础用法
61+
62+
```zig
63+
const std = @import("std");
64+
const msgpack = @import("msgpack");
65+
66+
pub fn main() !void {
67+
const allocator = std.heap.page_allocator;
68+
var buffer: [1024]u8 = undefined;
69+
var stream = std.io.fixedBufferStream(&buffer);
70+
71+
var packer = msgpack.Pack(
72+
*std.io.FixedBufferStream([]u8), *std.io.FixedBufferStream([]u8),
73+
std.io.FixedBufferStream([]u8).WriteError, std.io.FixedBufferStream([]u8).ReadError,
74+
std.io.FixedBufferStream([]u8).write, std.io.FixedBufferStream([]u8).read,
75+
).init(&stream, &stream);
76+
77+
// 创建和编码数据
78+
var map = msgpack.Payload.mapPayload(allocator);
79+
defer map.free(allocator);
80+
try map.mapPut("姓名", try msgpack.Payload.strToPayload("小明", allocator));
81+
try map.mapPut("年龄", msgpack.Payload.uintToPayload(25));
82+
try packer.write(map);
83+
84+
// 解码
85+
stream.pos = 0;
86+
const decoded = try packer.read(allocator);
87+
defer decoded.free(allocator);
88+
89+
const name = (try decoded.mapGet("姓名")).?.str.value();
90+
const age = (try decoded.mapGet("年龄")).?.uint;
91+
std.debug.print("姓名: {s}, 年龄: {d}\n", .{ name, age });
92+
}
93+
```
94+
95+
### 数据类型
96+
97+
```zig
98+
// 基础类型
99+
const nil_val = msgpack.Payload.nilToPayload();
100+
const bool_val = msgpack.Payload.boolToPayload(true);
101+
const int_val = msgpack.Payload.intToPayload(-42);
102+
const uint_val = msgpack.Payload.uintToPayload(42);
103+
const float_val = msgpack.Payload.floatToPayload(3.14);
104+
105+
// 字符串和二进制数据
106+
const str_val = try msgpack.Payload.strToPayload("你好", allocator);
107+
const bin_val = try msgpack.Payload.binToPayload(&[_]u8{1, 2, 3}, allocator);
108+
109+
// 数组
110+
var arr = try msgpack.Payload.arrPayload(2, allocator);
111+
try arr.setArrElement(0, msgpack.Payload.intToPayload(1));
112+
try arr.setArrElement(1, msgpack.Payload.intToPayload(2));
113+
114+
// 扩展类型
115+
const ext_val = try msgpack.Payload.extToPayload(5, &[_]u8{0xaa, 0xbb}, allocator);
116+
```
117+
118+
### 时间戳用法
119+
120+
```zig
121+
// 创建时间戳
122+
const ts1 = msgpack.Payload.timestampFromSeconds(1234567890);
123+
const ts2 = msgpack.Payload.timestampToPayload(1234567890, 123456789);
124+
125+
// 写入和读取时间戳
126+
try packer.write(ts2);
127+
stream.pos = 0;
128+
const decoded_ts = try packer.read(allocator);
129+
defer decoded_ts.free(allocator);
130+
131+
std.debug.print("时间戳: {}秒 + {}纳秒\n",
132+
.{ decoded_ts.timestamp.seconds, decoded_ts.timestamp.nanoseconds });
133+
std.debug.print("浮点数形式: {d}\n", .{ decoded_ts.timestamp.toFloat() });
134+
```
135+
136+
### 错误处理
137+
138+
```zig
139+
// 类型转换与错误处理
140+
const int_payload = msgpack.Payload.intToPayload(-42);
141+
const uint_result = int_payload.getUint() catch |err| switch (err) {
142+
msgpack.MsGPackError.INVALID_TYPE => {
143+
std.debug.print("无法将负数转换为无符号整数\n");
144+
return;
145+
},
146+
else => return err,
147+
};
148+
```
149+
150+
## API 概览
151+
152+
- **`msgpack.Pack`**: 用于打包和解包 MessagePack 数据的主要结构体。使用读写上下文进行初始化。
153+
- **`msgpack.Payload`**: 表示任何 MessagePack 类型的联合体。提供创建和与不同数据类型交互的方法(例如,`mapPayload``strToPayload``mapGet`)。
154+
155+
## 测试
156+
157+
要运行此库的单元测试,请使用以下命令:
158+
159+
```sh
160+
zig build test
161+
```
162+
163+
## 贡献
164+
165+
欢迎贡献!请随时提出问题或提交拉取请求。
166+
167+
## 相关项目
168+
169+
- [getty-msgpack](https://git.mzte.de/LordMZTE/getty-msgpack)
170+
- [znvim](https://github.com/jinzhongjia/znvim)
171+
172+
## 许可证
173+
174+
此项目在 MIT 许可证下许可。详情请参阅 [LICENSE](LICENSE) 文件。
175+

0 commit comments

Comments
 (0)