Skip to content

Commit d7d0b75

Browse files
committed
chore: update to Zig 0.15.1
1 parent 11af20f commit d7d0b75

11 files changed

Lines changed: 199 additions & 191 deletions

File tree

.github/workflows/cd.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,28 @@ on:
55
workflows: [CI]
66
types: [completed]
77

8-
workflow_dispatch:
8+
concurrency:
9+
group: cd
10+
cancel-in-progress: true
911

1012
jobs:
1113
emit:
12-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
14+
if: ${{ github.event.workflow_run.event == 'push' && github.event.workflow_run.conclusion == 'success' }}
1315

1416
runs-on: ubuntu-latest
1517

1618
steps:
1719
- name: Check out repository
18-
uses: actions/checkout@v4
20+
uses: actions/checkout@v5
1921

2022
- name: Set up Zig
21-
uses: mlugg/setup-zig@v1
22-
with:
23-
version: master
23+
uses: mlugg/setup-zig@v2
2424

25-
- name: Run doc step
25+
- name: Run `doc` step
2626
run: zig build doc
2727

2828
- name: Upload artifact for GitHub Pages
29-
uses: actions/upload-pages-artifact@v3
29+
uses: actions/upload-pages-artifact@v4
3030
with:
3131
path: zig-out/docs/
3232

.github/workflows/ci.yaml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,33 @@ on:
77
pull_request:
88
branches: [main]
99

10-
workflow_dispatch:
10+
concurrency:
11+
group: ci
12+
cancel-in-progress: true
1113

1214
jobs:
1315
test:
1416
runs-on: ubuntu-latest
1517

1618
steps:
1719
- name: Check out repository
18-
uses: actions/checkout@v4
20+
uses: actions/checkout@v5
1921

2022
- name: Set up Zig
21-
uses: mlugg/setup-zig@v1
22-
with:
23-
version: master
23+
uses: mlugg/setup-zig@v2
2424

25-
- name: Run test step
25+
- name: Run `test` step
2626
run: zig build test --summary all
2727

2828
fmt:
2929
runs-on: ubuntu-latest
3030

3131
steps:
3232
- name: Check out repository
33-
uses: actions/checkout@v4
33+
uses: actions/checkout@v5
3434

3535
- name: Set up Zig
36-
uses: mlugg/setup-zig@v1
37-
with:
38-
version: master
36+
uses: mlugg/setup-zig@v2
3937

40-
- name: Run fmt step
38+
- name: Run `fmt` step
4139
run: zig build fmt

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- Add `cookie` dependency to `build.zig.zon`.
88

99
```sh
10-
zig fetch --save git+https://github.com/tensorush/zig-cookie
10+
zig fetch --save git+https://github.com/tensorush/zig-cookie.git
1111
```
1212

1313
- Use `cookie` dependency in `build.zig`.

build.zig

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,45 @@
11
const std = @import("std");
22

3-
pub fn build(b: *std.Build) void {
3+
const manifest = @import("build.zig.zon");
4+
5+
pub fn build(b: *std.Build) !void {
46
const install_step = b.getInstallStep();
57
const target = b.standardTargetOptions(.{});
68
const optimize = b.standardOptimizeOption(.{});
79
const root_source_file = b.path("src/root.zig");
8-
const version = std.SemanticVersion{ .major = 0, .minor = 2, .patch = 2 };
10+
const version: std.SemanticVersion = try .parse(manifest.version);
911

10-
// Module
11-
const mod = b.addModule("cookie", .{
12+
// Public root module
13+
const root_mod = b.addModule("cookie", .{
1214
.target = target,
1315
.optimize = optimize,
1416
.root_source_file = root_source_file,
17+
.strip = b.option(bool, "strip", "Strip the binary"),
1518
});
1619

1720
// Library
18-
const lib_step = b.step("lib", "Install library");
19-
2021
const lib = b.addLibrary(.{
2122
.name = "cookie",
2223
.version = version,
23-
.root_module = mod,
24+
.root_module = root_mod,
2425
});
25-
26-
const lib_install = b.addInstallArtifact(lib, .{});
27-
lib_step.dependOn(&lib_install.step);
28-
install_step.dependOn(lib_step);
26+
b.installArtifact(lib);
2927

3028
// Documentation
3129
const docs_step = b.step("doc", "Emit documentation");
30+
3231
const docs_install = b.addInstallDirectory(.{
3332
.install_dir = .prefix,
3433
.install_subdir = "docs",
3534
.source_dir = lib.getEmittedDocs(),
3635
});
3736
docs_step.dependOn(&docs_install.step);
38-
install_step.dependOn(docs_step);
3937

4038
// Test suite
4139
const tests_step = b.step("test", "Run test suite");
4240

4341
const tests = b.addTest(.{
44-
.version = version,
45-
.root_module = b.createModule(.{
46-
.target = target,
47-
.root_source_file = root_source_file,
48-
}),
42+
.root_module = root_mod,
4943
});
5044

5145
const tests_run = b.addRunArtifact(tests);
@@ -65,4 +59,14 @@ pub fn build(b: *std.Build) void {
6559
});
6660
fmt_step.dependOn(&fmt.step);
6761
install_step.dependOn(fmt_step);
62+
63+
// Compilation check for ZLS Build-On-Save
64+
// See: https://zigtools.org/zls/guides/build-on-save/
65+
const check_step = b.step("check", "Check compilation");
66+
const check_exe = b.addExecutable(.{
67+
.name = "cookie",
68+
.version = version,
69+
.root_module = root_mod,
70+
});
71+
check_step.dependOn(&check_exe.step);
6872
}

build.zig.zon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
.{
22
.name = .cookie,
33
.fingerprint = 0x8ae0ba6611e7a9c1,
4-
.version = "0.2.2",
5-
.minimum_zig_version = "0.14.0",
4+
.version = "0.3.0",
5+
.minimum_zig_version = "0.15.1",
66
.paths = .{
77
"src/",
88
"build.zig",

src/Cookie.zig

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
//! HTTP cookie printing and parsing.
22

33
const std = @import("std");
4+
45
const Datetime = @import("Datetime.zig");
56

67
const Cookie = @This();
78

9+
expires: ?Expiration = null,
10+
same_site: ?SameSite = null,
11+
domain: ?[]const u8 = null,
12+
max_age: ?u64 = null,
13+
partitioned: ?bool = null,
14+
http_only: ?bool = null,
15+
path: ?[]const u8 = null,
16+
secure: ?bool = null,
17+
value: []const u8 = "",
18+
name: []const u8,
19+
820
pub const Error = error{
921
MissingPair,
1022
EmptyName,
@@ -22,55 +34,44 @@ pub const SameSite = enum {
2234
Lax,
2335
};
2436

25-
expires: ?Expiration = null,
26-
same_site: ?SameSite = null,
27-
domain: ?[]const u8 = null,
28-
max_age: ?u64 = null,
29-
partitioned: ?bool = null,
30-
http_only: ?bool = null,
31-
path: ?[]const u8 = null,
32-
secure: ?bool = null,
33-
value: []const u8 = "",
34-
name: []const u8,
35-
3637
/// Set expires field from HTTP datetime value.
3738
pub fn setExpires(self: *Cookie, value: []const u8) Datetime.Error!void {
38-
self.expires = .{ .datetime = try Datetime.parse(value) };
39+
self.expires = .{ .datetime = try .parse(value) };
3940
}
4041

4142
/// Turn into permanent cookie.
4243
pub fn makePermanent(self: *Cookie) void {
4344
self.max_age = 20 * 365 * std.time.s_per_day;
44-
self.expires = .{ .datetime = Datetime.fromTimestamp(std.time.timestamp() + self.max_age) };
45+
self.expires = .{ .datetime = .fromTimestamp(std.time.timestamp() + self.max_age) };
4546
}
4647

4748
/// Turn into removal cookie.
4849
pub fn makeRemoval(self: *Cookie) void {
4950
self.value = "";
5051
self.max_age = 0;
51-
self.expires = .{ .datetime = Datetime.fromTimestamp(std.time.timestamp() + 365 * std.time.s_per_day) };
52+
self.expires = .{ .datetime = .fromTimestamp(std.time.timestamp() + 365 * std.time.s_per_day) };
5253
}
5354

5455
/// Parse cookie from string, specifying whether name and value need escaping.
5556
pub fn parse(cookie_str: []const u8) Error!Cookie {
5657
var attr_iter = std.mem.tokenizeScalar(u8, cookie_str, ';');
57-
const name_value = attr_iter.next() orelse return error.MissingPair;
58-
const name_value_idx = std.mem.indexOfScalar(u8, name_value, '=') orelse return error.MissingPair;
59-
var name = std.mem.trim(u8, name_value[0..name_value_idx], std.ascii.whitespace[0..]);
60-
var value = std.mem.trim(u8, name_value[name_value_idx + 1 ..], std.ascii.whitespace[0..]);
58+
const name_value = attr_iter.next() orelse return Error.MissingPair;
59+
const name_value_idx = std.mem.indexOfScalar(u8, name_value, '=') orelse return Error.MissingPair;
60+
var name = std.mem.trim(u8, name_value[0..name_value_idx], &std.ascii.whitespace);
61+
var value = std.mem.trim(u8, name_value[name_value_idx + 1 ..], &std.ascii.whitespace);
6162

6263
if (name.len == 0) {
63-
return error.EmptyName;
64+
return Error.EmptyName;
6465
}
6566

66-
var cookie = Cookie{ .name = name, .value = value };
67+
var cookie: Cookie = .{ .name = name, .value = value };
6768

6869
outer: while (attr_iter.next()) |attr| {
6970
if (std.mem.indexOfScalar(u8, attr, '=')) |idx| {
70-
name = std.mem.trim(u8, attr[0..idx], std.ascii.whitespace[0..]);
71-
value = std.mem.trim(u8, attr[idx + 1 ..], std.ascii.whitespace[0..]);
71+
name = std.mem.trim(u8, attr[0..idx], &std.ascii.whitespace);
72+
value = std.mem.trim(u8, attr[idx + 1 ..], &std.ascii.whitespace);
7273
} else {
73-
name = std.mem.trim(u8, attr, std.ascii.whitespace[0..]);
74+
name = std.mem.trim(u8, attr, &std.ascii.whitespace);
7475
value = "";
7576
}
7677

@@ -104,23 +105,23 @@ pub fn parse(cookie_str: []const u8) Error!Cookie {
104105
} else if (std.ascii.eqlIgnoreCase(name, "partitioned")) {
105106
cookie.partitioned = true;
106107
} else if (std.ascii.eqlIgnoreCase(name, "expires")) {
107-
cookie.expires = .{ .datetime = try Datetime.parse(value) };
108+
cookie.expires = .{ .datetime = try .parse(value) };
108109
}
109110
}
110111

111112
return cookie;
112113
}
113114

114115
/// Print cookie to writer.
115-
pub fn format(self: Cookie, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
116+
pub fn format(self: Cookie, writer: *std.io.Writer) std.io.Writer.Error!void {
116117
try writer.print("{s}={s}", .{ self.name, self.value });
117118

118119
if (self.http_only) |_| {
119120
try writer.writeAll("; HttpOnly");
120121
}
121122

122123
if (self.same_site) |same_site| {
123-
try writer.print("; SameSite={s}", .{@tagName(same_site)});
124+
try writer.print("; SameSite={t}", .{same_site});
124125
}
125126

126127
if (self.partitioned) |_| {
@@ -148,48 +149,48 @@ pub fn format(self: Cookie, comptime _: []const u8, _: std.fmt.FormatOptions, wr
148149

149150
if (self.expires) |expires| {
150151
if (std.meta.activeTag(expires) == .datetime) {
151-
try writer.print("; Expires={s}", .{expires.datetime});
152+
try writer.print("; Expires={f}", .{expires.datetime});
152153
}
153154
}
154155
}
155156

156157
test format {
157-
try std.testing.expectFmt("foo=bar", "{}", .{Cookie{ .name = "foo", .value = "bar" }});
158-
try std.testing.expectFmt("foo=bar; HttpOnly", "{}", .{Cookie{ .name = "foo", .value = "bar", .http_only = true }});
159-
try std.testing.expectFmt("foo=bar; Max-Age=10", "{}", .{Cookie{ .name = "foo", .value = "bar", .max_age = 10 }});
160-
try std.testing.expectFmt("foo=bar; Secure", "{}", .{Cookie{ .name = "foo", .value = "bar", .secure = true }});
161-
try std.testing.expectFmt("foo=bar; Path=/", "{}", .{Cookie{ .name = "foo", .value = "bar", .path = "/" }});
162-
try std.testing.expectFmt("foo=bar; Domain=ziglang.org", "{}", .{Cookie{ .name = "foo", .value = "bar", .domain = "ziglang.org" }});
163-
try std.testing.expectFmt("foo=bar; SameSite=Strict", "{}", .{Cookie{ .name = "foo", .value = "bar", .same_site = .Strict }});
164-
try std.testing.expectFmt("foo=bar; SameSite=Lax", "{}", .{Cookie{ .name = "foo", .value = "bar", .same_site = .Lax }});
165-
166-
var cookie = Cookie{ .name = "foo", .value = "bar", .same_site = .None };
167-
try std.testing.expectFmt("foo=bar; SameSite=None; Secure", "{}", .{cookie});
158+
try std.testing.expectFmt("foo=bar", "{f}", .{Cookie{ .name = "foo", .value = "bar" }});
159+
try std.testing.expectFmt("foo=bar; HttpOnly", "{f}", .{Cookie{ .name = "foo", .value = "bar", .http_only = true }});
160+
try std.testing.expectFmt("foo=bar; Max-Age=10", "{f}", .{Cookie{ .name = "foo", .value = "bar", .max_age = 10 }});
161+
try std.testing.expectFmt("foo=bar; Secure", "{f}", .{Cookie{ .name = "foo", .value = "bar", .secure = true }});
162+
try std.testing.expectFmt("foo=bar; Path=/", "{f}", .{Cookie{ .name = "foo", .value = "bar", .path = "/" }});
163+
try std.testing.expectFmt("foo=bar; Domain=ziglang.org", "{f}", .{Cookie{ .name = "foo", .value = "bar", .domain = "ziglang.org" }});
164+
try std.testing.expectFmt("foo=bar; SameSite=Strict", "{f}", .{Cookie{ .name = "foo", .value = "bar", .same_site = .Strict }});
165+
try std.testing.expectFmt("foo=bar; SameSite=Lax", "{f}", .{Cookie{ .name = "foo", .value = "bar", .same_site = .Lax }});
166+
167+
var cookie: Cookie = .{ .name = "foo", .value = "bar", .same_site = .None };
168+
try std.testing.expectFmt("foo=bar; SameSite=None; Secure", "{f}", .{cookie});
168169

169170
cookie.partitioned = true;
170-
try std.testing.expectFmt("foo=bar; SameSite=None; Partitioned; Secure", "{}", .{cookie});
171+
try std.testing.expectFmt("foo=bar; SameSite=None; Partitioned; Secure", "{f}", .{cookie});
171172

172173
cookie.same_site = null;
173-
try std.testing.expectFmt("foo=bar; Partitioned; Secure", "{}", .{cookie});
174+
try std.testing.expectFmt("foo=bar; Partitioned; Secure", "{f}", .{cookie});
174175

175176
cookie.secure = false;
176-
try std.testing.expectFmt("foo=bar; Partitioned; Secure", "{}", .{cookie});
177+
try std.testing.expectFmt("foo=bar; Partitioned; Secure", "{f}", .{cookie});
177178

178179
cookie.secure = null;
179-
try std.testing.expectFmt("foo=bar; Partitioned; Secure", "{}", .{cookie});
180+
try std.testing.expectFmt("foo=bar; Partitioned; Secure", "{f}", .{cookie});
180181

181182
cookie.partitioned = null;
182-
try std.testing.expectFmt("foo=bar", "{}", .{cookie});
183+
try std.testing.expectFmt("foo=bar", "{f}", .{cookie});
183184

184-
cookie = Cookie{ .name = "foo", .value = "bar", .same_site = .None, .secure = false };
185-
try std.testing.expectFmt("foo=bar; SameSite=None", "{}", .{cookie});
185+
cookie = .{ .name = "foo", .value = "bar", .same_site = .None, .secure = false };
186+
try std.testing.expectFmt("foo=bar; SameSite=None", "{f}", .{cookie});
186187

187188
cookie.secure = true;
188-
try std.testing.expectFmt("foo=bar; SameSite=None; Secure", "{}", .{cookie});
189+
try std.testing.expectFmt("foo=bar; SameSite=None; Secure", "{f}", .{cookie});
189190

190-
cookie = Cookie{ .name = "foo", .value = "bar" };
191+
cookie = .{ .name = "foo", .value = "bar" };
191192
try cookie.setExpires("Mon, 08 Feb 2016 07:28:00 GMT");
192-
try std.testing.expectFmt("foo=bar; Expires=Mon, 08 Feb 2016 07:28:00 GMT", "{}", .{cookie});
193+
try std.testing.expectFmt("foo=bar; Expires=Mon, 08 Feb 2016 07:28:00 GMT", "{f}", .{cookie});
193194
}
194195

195196
test parse {
@@ -215,9 +216,9 @@ test parse {
215216
try std.testing.expectEqualStrings(cookie.value, "bar");
216217
try std.testing.expectEqual(cookie.expires.?.datetime, try Datetime.parse("Mon, 08 Feb 2016 07:28:00 GMT"));
217218

218-
try std.testing.expectError(error.MissingPair, parse("bar"));
219-
try std.testing.expectError(error.EmptyName, parse("=bar"));
220-
try std.testing.expectError(error.EmptyName, parse(" =bar"));
219+
try std.testing.expectError(Error.MissingPair, parse("bar"));
220+
try std.testing.expectError(Error.EmptyName, parse("=bar"));
221+
try std.testing.expectError(Error.EmptyName, parse(" =bar"));
221222

222223
cookie = try parse("foo=bar=baz");
223224
try std.testing.expectEqualStrings(cookie.name, "foo");

0 commit comments

Comments
 (0)