Skip to content

Commit bfedfd1

Browse files
authored
feat: adopt with Zig 0.15 (#114)
Close #112
1 parent b827821 commit bfedfd1

File tree

19 files changed

+137
-137
lines changed

19 files changed

+137
-137
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
fail-fast: false
2828
matrix:
2929
os: [ubuntu-latest, macos-latest]
30-
zig-version: [0.14.1]
30+
zig-version: [0.15.1]
3131
steps:
3232
- uses: actions/checkout@v4
3333
- uses: mlugg/setup-zig@v2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
[Zig cookbook](https://github.com/zigcc/zig-cookbook) is a collection of simple Zig programs that demonstrate good practices to accomplish common programming tasks.
1111

12-
> - Main branch tracks Zig 0.14.0 and master, and are tested on Linux and macOS via GitHub actions.
12+
> - Main branch tracks Zig 0.15.x, and is tested on Linux and macOS via GitHub actions.
1313
> - Earlier Zig support could be found in [other branches](https://github.com/zigcc/zig-cookbook/branches).
1414
1515
# How to use

assets/src/01-01.zig

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,17 @@ const fs = std.fs;
33
const print = std.debug.print;
44

55
pub fn main() !void {
6-
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
7-
defer _ = gpa.deinit();
8-
const allocator = gpa.allocator();
9-
106
const file = try fs.cwd().openFile("tests/zig-zen.txt", .{});
117
defer file.close();
128

13-
// Wrap the file reader in a buffered reader.
14-
// Since it's usually faster to read a bunch of bytes at once.
15-
var buf_reader = std.io.bufferedReader(file.reader());
16-
const reader = buf_reader.reader();
17-
18-
var line = std.ArrayList(u8).init(allocator);
19-
defer line.deinit();
20-
21-
const writer = line.writer();
9+
var file_buffer: [4096]u8 = undefined;
10+
var reader = file.reader(&file_buffer);
2211
var line_no: usize = 0;
23-
while (reader.streamUntilDelimiter(writer, '\n', null)) {
24-
// Clear the line so we can reuse it.
25-
defer line.clearRetainingCapacity();
12+
while (reader.interface.takeDelimiterExclusive('\n')) |line| {
2613
line_no += 1;
27-
28-
print("{d}--{s}\n", .{ line_no, line.items });
14+
print("{d}--{s}\n", .{ line_no, line });
2915
} else |err| switch (err) {
30-
error.EndOfStream => { // end of file
31-
if (line.items.len > 0) {
32-
line_no += 1;
33-
print("{d}--{s}\n", .{ line_no, line.items });
34-
}
35-
},
16+
error.EndOfStream => {}, // Normal termination
3617
else => return err, // Propagate error
3718
}
3819

assets/src/01-02.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ pub fn main() !void {
2121
// Before mmap, we need to ensure file isn't empty
2222
try file.setEndPos(content_to_write.len);
2323

24-
const md = try file.metadata();
25-
try std.testing.expectEqual(md.size(), content_to_write.len);
24+
const md = try file.stat();
25+
try std.testing.expectEqual(md.size, content_to_write.len);
2626

2727
const ptr = try std.posix.mmap(
2828
null,

assets/src/02-01.zig

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ fn sha256_digest(
99
file: fs.File,
1010
) ![Sha256.digest_length]u8 {
1111
var sha256 = Sha256.init(.{});
12-
const rdr = file.reader();
13-
14-
var buf: [BUF_SIZE]u8 = undefined;
15-
var n = try rdr.read(&buf);
12+
var file_buf: [BUF_SIZE]u8 = undefined;
13+
var reader = file.reader(&file_buf);
14+
var read_buf: [BUF_SIZE]u8 = undefined;
15+
var n = try reader.interface.readSliceShort(&read_buf);
1616
while (n != 0) {
17-
sha256.update(buf[0..n]);
18-
n = try rdr.read(&buf);
17+
sha256.update(read_buf[0..n]);
18+
n = try reader.interface.readSliceShort(&read_buf);
1919
}
2020

2121
return sha256.finalResult();
@@ -32,8 +32,8 @@ pub fn main() !void {
3232
const digest = try sha256_digest(file);
3333
const hex_digest = try std.fmt.allocPrint(
3434
allocator,
35-
"{s}",
36-
.{std.fmt.fmtSliceHexLower(&digest)},
35+
"{x}",
36+
.{&digest},
3737
);
3838
defer allocator.free(hex_digest);
3939

assets/src/03-01.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const print = std.debug.print;
66

77
fn expensive_function() void {
88
// sleep 500ms
9-
time.sleep(time.ns_per_ms * 500);
9+
std.Thread.sleep(time.ns_per_ms * 500);
1010
}
1111

1212
pub fn main() !void {

assets/src/04-01.zig

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Start a TCP server at an unused port.
1+
//! Start an echo TCP server at an unused port.
22
//!
33
//! Test with
44
//! echo "hello zig" | nc localhost <port>
@@ -8,10 +8,6 @@ const net = std.net;
88
const print = std.debug.print;
99

1010
pub fn main() !void {
11-
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
12-
defer _ = gpa.deinit();
13-
const allocator = gpa.allocator();
14-
1511
const loopback = try net.Ip4Address.parse("127.0.0.1", 0);
1612
const localhost = net.Address{ .in = loopback };
1713
var server = try localhost.listen(.{
@@ -22,13 +18,31 @@ pub fn main() !void {
2218
const addr = server.listen_address;
2319
print("Listening on {}, access this port to end the program\n", .{addr.getPort()});
2420

25-
var client = try server.accept();
26-
defer client.stream.close();
27-
28-
print("Connection received! {} is sending data.\n", .{client.address});
29-
30-
const message = try client.stream.reader().readAllAlloc(allocator, 1024);
31-
defer allocator.free(message);
21+
const client = try server.accept();
22+
// In real world, you'd want to handle multiple clients, probably in separate threads.
23+
try handleClient(client);
24+
}
3225

33-
print("{} says {s}\n", .{ client.address, message });
26+
fn handleClient(client: net.Server.Connection) !void {
27+
print("Accepted connection from {f}\n", .{client.address});
28+
defer client.stream.close();
29+
var stream_buf: [1024]u8 = undefined;
30+
var reader = client.stream.reader(&stream_buf);
31+
// Here we echo back what we read directly, so the writer buffer is empty
32+
var writer = client.stream.writer(&.{});
33+
34+
while (true) {
35+
print("Waiting for data from {f}...\n", .{client.address});
36+
const msg = reader.interface().takeDelimiterInclusive('\n') catch |err| {
37+
if (err == error.EndOfStream) {
38+
print("{f} closed the connection\n", .{client.address});
39+
return;
40+
} else {
41+
return err;
42+
}
43+
};
44+
print("{f} says {s}", .{ client.address, msg });
45+
try writer.interface.writeAll(msg);
46+
// No need to flush, as writer buffer is empty
47+
}
3448
}

assets/src/04-02.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ pub fn main() !void {
1616
// Connect to peer
1717
const stream = try net.tcpConnectToAddress(peer);
1818
defer stream.close();
19-
print("Connecting to {}\n", .{peer});
19+
print("Connecting to {f}\n", .{peer});
2020

2121
// Sending data to peer
2222
const data = "hello zig";
23-
var writer = stream.writer();
24-
const size = try writer.write(data);
25-
print("Sending '{s}' to peer, total written: {d} bytes\n", .{ data, size });
26-
// Or just using `writer.writeAll`
27-
// try writer.writeAll("hello zig");
23+
var buffer: [1024]u8 = undefined;
24+
var writer = stream.writer(buffer[0..]);
25+
try writer.interface.writeAll(data);
26+
try writer.interface.flush();
27+
print("Sending '{s}' to peer, total written: {d} bytes\n", .{ data, data.len });
2828
}

assets/src/04-03.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub fn main() !void {
3030

3131
var buf: [1024]u8 = undefined;
3232

33-
print("Listen on {any}...\n", .{addr});
33+
print("Listen on {f}\n", .{addr});
3434

3535
// we did not set the NONBLOCK flag (socket type flag),
3636
// so the program will wait until data is received

assets/src/05-01.zig

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,22 @@ pub fn main() !void {
1313
const uri = try std.Uri.parse("http://httpbin.org/headers");
1414
const buf = try allocator.alloc(u8, 1024 * 8);
1515
defer allocator.free(buf);
16-
var req = try client.open(.GET, uri, .{
17-
.server_header_buffer = buf,
16+
var req = try client.request(.GET, uri, .{
17+
.extra_headers = &.{.{ .name = "Custom-header", .value = "Custom Value" }},
1818
});
1919
defer req.deinit();
2020

21-
try req.send();
22-
try req.finish();
23-
try req.wait();
21+
try req.sendBodiless();
2422

25-
var iter = req.response.iterateHeaders();
23+
var redirect_buffer: [1024]u8 = undefined;
24+
var response = try req.receiveHead(&redirect_buffer);
25+
var iter = response.head.iterateHeaders();
2626
while (iter.next()) |header| {
2727
std.debug.print("Name:{s}, Value:{s}\n", .{ header.name, header.value });
2828
}
2929

30-
try std.testing.expectEqual(req.response.status, .ok);
31-
32-
var rdr = req.reader();
33-
const body = try rdr.readAllAlloc(allocator, 1024 * 1024 * 4);
30+
try std.testing.expectEqual(response.head.status, .ok);
31+
const body = try response.reader(&.{}).allocRemaining(allocator, .unlimited);
3432
defer allocator.free(body);
3533

3634
print("Body:\n{s}\n", .{body});

0 commit comments

Comments
 (0)