Skip to content

Commit d6ee196

Browse files
authored
add serde zon example (#95)
Close #87
1 parent f1c2252 commit d6ee196

File tree

5 files changed

+102
-19
lines changed

5 files changed

+102
-19
lines changed

book-src/10-02-zon.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Serialize and deserialize Zon
2+
3+
ZON ("Zig Object Notation") is a textual file format. Outside of `nan` and `inf` literals, ZON's grammar is a subset of Zig's.
4+
5+
Supported Zig primitives:
6+
* boolean literals
7+
* number literals (including `nan` and `inf`)
8+
* character literals
9+
* enum literals
10+
* `null` literals
11+
* string literals
12+
* multiline string literals
13+
14+
Supported Zig container types:
15+
* anonymous struct literals
16+
* anonymous tuple literals
17+
18+
```zig
19+
{{#include ../src/10-02.zig }}
20+
```
File renamed without changes.

book-src/SUMMARY.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@
5353

5454
- [Encoding]()
5555

56-
- [Deserialize JSON](./10-01-json.md)
57-
- [Encode and decode base64](./10-02-base64.md)
56+
- [(De)serialize JSON](./10-01-json.md)
57+
- [(De)serialize Zon](./10-02-zon.md)
58+
- [Encode and decode base64](./10-03-base64.md)
5859

5960
- [Mathematics]()
6061

src/10-02.zig

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,62 @@
11
const std = @import("std");
2-
const print = std.debug.print;
3-
const Encoder = std.base64.standard.Encoder;
4-
const Decoder = std.base64.standard.Decoder;
2+
const zon = std.zon;
3+
const Allocator = std.mem.Allocator;
4+
5+
const Student = struct {
6+
name: []const u8,
7+
age: u16,
8+
favourites: []const []const u8,
9+
10+
fn deinit(self: *Student, allocator: Allocator) void {
11+
allocator.free(self.name);
12+
for (self.favourites) |item| {
13+
allocator.free(item);
14+
}
15+
allocator.free(self.favourites);
16+
}
17+
};
518

619
pub fn main() !void {
720
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
8-
defer _ = gpa.deinit();
21+
defer if (gpa.deinit() != .ok) @panic("leak");
922
const allocator = gpa.allocator();
1023

11-
const src = "hello zig";
24+
const source = Student{
25+
.name = "John",
26+
.age = 20,
27+
.favourites = &.{ "swimming", "running" },
28+
};
29+
30+
var dst = std.ArrayList(u8).init(allocator);
31+
defer dst.deinit();
32+
try zon.stringify.serialize(source, .{}, dst.writer());
1233

13-
// Encode
14-
const encoded_length = Encoder.calcSize(src.len);
15-
const encoded_buffer = try allocator.alloc(u8, encoded_length);
16-
defer allocator.free(encoded_buffer);
34+
const expected =
35+
\\.{
36+
\\ .name = "John",
37+
\\ .age = 20,
38+
\\ .favourites = .{ "swimming", "running" },
39+
\\}
40+
;
41+
try std.testing.expectEqualStrings(expected, dst.items);
1742

18-
_ = Encoder.encode(encoded_buffer, src);
19-
try std.testing.expectEqualStrings("aGVsbG8gemln", encoded_buffer);
43+
// Make it 0-sentinel
44+
try dst.append(0);
45+
const input = dst.items[0 .. dst.items.len - 1 :0];
2046

21-
// Decode
22-
const decoded_length = try Decoder.calcSizeForSlice(encoded_buffer);
23-
const decoded_buffer = try allocator.alloc(u8, decoded_length);
24-
defer allocator.free(decoded_buffer);
47+
var status: zon.parse.Status = .{};
48+
defer status.deinit(allocator);
49+
var parsed = zon.parse.fromSlice(
50+
Student,
51+
allocator,
52+
input,
53+
&status,
54+
.{ .free_on_error = true },
55+
) catch |err| {
56+
std.debug.print("Parse status: {any}\n", .{status});
57+
return err;
58+
};
59+
defer parsed.deinit(allocator);
2560

26-
try Decoder.decode(decoded_buffer, encoded_buffer);
27-
try std.testing.expectEqualStrings(src, decoded_buffer);
61+
try std.testing.expectEqualDeep(source, parsed);
2862
}

src/10-03.zig

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const std = @import("std");
2+
const print = std.debug.print;
3+
const Encoder = std.base64.standard.Encoder;
4+
const Decoder = std.base64.standard.Decoder;
5+
6+
pub fn main() !void {
7+
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
8+
defer _ = gpa.deinit();
9+
const allocator = gpa.allocator();
10+
11+
const src = "hello zig";
12+
13+
// Encode
14+
const encoded_length = Encoder.calcSize(src.len);
15+
const encoded_buffer = try allocator.alloc(u8, encoded_length);
16+
defer allocator.free(encoded_buffer);
17+
18+
_ = Encoder.encode(encoded_buffer, src);
19+
try std.testing.expectEqualStrings("aGVsbG8gemln", encoded_buffer);
20+
21+
// Decode
22+
const decoded_length = try Decoder.calcSizeForSlice(encoded_buffer);
23+
const decoded_buffer = try allocator.alloc(u8, decoded_length);
24+
defer allocator.free(decoded_buffer);
25+
26+
try Decoder.decode(decoded_buffer, encoded_buffer);
27+
try std.testing.expectEqualStrings(src, decoded_buffer);
28+
}

0 commit comments

Comments
 (0)