| ... | @@ -6,7 +6,7 @@ const testing = std.testing; | ... | @@ -6,7 +6,7 @@ const testing = std.testing; |
| 6 | const ascii = std.ascii; | 6 | const ascii = std.ascii; |
| 7 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| 8 | | 8 | |
| 9 | pub const HeaderList = std.ArrayListUnmanaged(HeaderEntry); | 9 | pub const HeaderList = std.ArrayListUnmanaged(Field); |
| 10 | pub const HeaderIndexList = std.ArrayListUnmanaged(usize); | 10 | pub const HeaderIndexList = std.ArrayListUnmanaged(usize); |
| 11 | pub const HeaderIndex = std.HashMapUnmanaged([]const u8, HeaderIndexList, CaseInsensitiveStringContext, std.hash_map.default_max_load_percentage); | 11 | pub const HeaderIndex = std.HashMapUnmanaged([]const u8, HeaderIndexList, CaseInsensitiveStringContext, std.hash_map.default_max_load_percentage); |
| 12 | | 12 | |
| ... | @@ -32,11 +32,11 @@ pub const CaseInsensitiveStringContext = struct { | ... | @@ -32,11 +32,11 @@ pub const CaseInsensitiveStringContext = struct { |
| 32 | } | 32 | } |
| 33 | }; | 33 | }; |
| 34 | | 34 | |
| 35 | pub const HeaderEntry = struct { | 35 | pub const Field = struct { |
| 36 | name: []const u8, | 36 | name: []const u8, |
| 37 | value: []const u8, | 37 | value: []const u8, |
| 38 | | 38 | |
| 39 | pub fn modify(entry: *HeaderEntry, allocator: Allocator, new_value: []const u8) !void { | 39 | pub fn modify(entry: *Field, allocator: Allocator, new_value: []const u8) !void { |
| 40 | if (entry.value.len <= new_value.len) { | 40 | if (entry.value.len <= new_value.len) { |
| 41 | std.mem.copy(u8, @constCast(entry.value), new_value); | 41 | std.mem.copy(u8, @constCast(entry.value), new_value); |
| 42 | } else { | 42 | } else { |
| ... | @@ -46,7 +46,7 @@ pub const HeaderEntry = struct { | ... | @@ -46,7 +46,7 @@ pub const HeaderEntry = struct { |
| 46 | } | 46 | } |
| 47 | } | 47 | } |
| 48 | | 48 | |
| 49 | fn lessThan(ctx: void, a: HeaderEntry, b: HeaderEntry) bool { | 49 | fn lessThan(ctx: void, a: Field, b: Field) bool { |
| 50 | _ = ctx; | 50 | _ = ctx; |
| 51 | if (a.name.ptr == b.name.ptr) return false; | 51 | if (a.name.ptr == b.name.ptr) return false; |
| 52 | | 52 | |
| ... | @@ -92,7 +92,7 @@ pub const Headers = struct { | ... | @@ -92,7 +92,7 @@ pub const Headers = struct { |
| 92 | const value_duped = if (headers.owned) try headers.allocator.dupe(u8, value) else value; | 92 | const value_duped = if (headers.owned) try headers.allocator.dupe(u8, value) else value; |
| 93 | errdefer if (headers.owned) headers.allocator.free(value_duped); | 93 | errdefer if (headers.owned) headers.allocator.free(value_duped); |
| 94 | | 94 | |
| 95 | var entry = HeaderEntry{ .name = undefined, .value = value_duped }; | 95 | var entry = Field{ .name = undefined, .value = value_duped }; |
| 96 | | 96 | |
| 97 | if (headers.index.getEntry(name)) |kv| { | 97 | if (headers.index.getEntry(name)) |kv| { |
| 98 | entry.name = kv.key_ptr.*; | 98 | entry.name = kv.key_ptr.*; |
| ... | @@ -157,7 +157,7 @@ pub const Headers = struct { | ... | @@ -157,7 +157,7 @@ pub const Headers = struct { |
| 157 | } | 157 | } |
| 158 | | 158 | |
| 159 | /// Returns the entry of the first occurrence of a header with the given name. | 159 | /// Returns the entry of the first occurrence of a header with the given name. |
| 160 | pub fn getFirstEntry(headers: Headers, name: []const u8) ?HeaderEntry { | 160 | pub fn getFirstEntry(headers: Headers, name: []const u8) ?Field { |
| 161 | const first_index = headers.firstIndexOf(name) orelse return null; | 161 | const first_index = headers.firstIndexOf(name) orelse return null; |
| 162 | | 162 | |
| 163 | return headers.list.items[first_index]; | 163 | return headers.list.items[first_index]; |
| ... | @@ -165,10 +165,10 @@ pub const Headers = struct { | ... | @@ -165,10 +165,10 @@ pub const Headers = struct { |
| 165 | | 165 | |
| 166 | /// Returns a slice containing each header with the given name. | 166 | /// Returns a slice containing each header with the given name. |
| 167 | /// The caller owns the returned slice, but NOT the values in the slice. | 167 | /// The caller owns the returned slice, but NOT the values in the slice. |
| 168 | pub fn getEntries(headers: Headers, allocator: Allocator, name: []const u8) !?[]const HeaderEntry { | 168 | pub fn getEntries(headers: Headers, allocator: Allocator, name: []const u8) !?[]const Field { |
| 169 | const indices = headers.getIndices(name) orelse return null; | 169 | const indices = headers.getIndices(name) orelse return null; |
| 170 | | 170 | |
| 171 | const buf = try allocator.alloc(HeaderEntry, indices.len); | 171 | const buf = try allocator.alloc(Field, indices.len); |
| 172 | for (indices, 0..) |idx, n| { | 172 | for (indices, 0..) |idx, n| { |
| 173 | buf[n] = headers.list.items[idx]; | 173 | buf[n] = headers.list.items[idx]; |
| 174 | } | 174 | } |
| ... | @@ -211,7 +211,7 @@ pub const Headers = struct { | ... | @@ -211,7 +211,7 @@ pub const Headers = struct { |
| 211 | | 211 | |
| 212 | /// Sorts the headers in lexicographical order. | 212 | /// Sorts the headers in lexicographical order. |
| 213 | pub fn sort(headers: *Headers) void { | 213 | pub fn sort(headers: *Headers) void { |
| 214 | std.sort.sort(HeaderEntry, headers.list.items, {}, HeaderEntry.lessThan); | 214 | std.sort.sort(Field, headers.list.items, {}, Field.lessThan); |
| 215 | headers.rebuildIndex(); | 215 | headers.rebuildIndex(); |
| 216 | } | 216 | } |
| 217 | | 217 | |
| ... | @@ -314,31 +314,31 @@ test "Headers consistency" { | ... | @@ -314,31 +314,31 @@ test "Headers consistency" { |
| 314 | | 314 | |
| 315 | const hello_entries = (try h.getEntries(testing.allocator, "hello")).?; | 315 | const hello_entries = (try h.getEntries(testing.allocator, "hello")).?; |
| 316 | defer testing.allocator.free(hello_entries); | 316 | defer testing.allocator.free(hello_entries); |
| 317 | try testing.expectEqualDeep(@as([]const HeaderEntry, &[_]HeaderEntry{ | 317 | try testing.expectEqualDeep(@as([]const Field, &[_]Field{ |
| 318 | .{ .name = "hello", .value = "world" }, | 318 | .{ .name = "hello", .value = "world" }, |
| 319 | }), hello_entries); | 319 | }), hello_entries); |
| 320 | | 320 | |
| 321 | const foo_entries = (try h.getEntries(testing.allocator, "foo")).?; | 321 | const foo_entries = (try h.getEntries(testing.allocator, "foo")).?; |
| 322 | defer testing.allocator.free(foo_entries); | 322 | defer testing.allocator.free(foo_entries); |
| 323 | try testing.expectEqualDeep(@as([]const HeaderEntry, &[_]HeaderEntry{ | 323 | try testing.expectEqualDeep(@as([]const Field, &[_]Field{ |
| 324 | .{ .name = "foo", .value = "bar" }, | 324 | .{ .name = "foo", .value = "bar" }, |
| 325 | .{ .name = "foo", .value = "baz" }, | 325 | .{ .name = "foo", .value = "baz" }, |
| 326 | }), foo_entries); | 326 | }), foo_entries); |
| 327 | | 327 | |
| 328 | const bar_entries = (try h.getEntries(testing.allocator, "bar")).?; | 328 | const bar_entries = (try h.getEntries(testing.allocator, "bar")).?; |
| 329 | defer testing.allocator.free(bar_entries); | 329 | defer testing.allocator.free(bar_entries); |
| 330 | try testing.expectEqualDeep(@as([]const HeaderEntry, &[_]HeaderEntry{ | 330 | try testing.expectEqualDeep(@as([]const Field, &[_]Field{ |
| 331 | .{ .name = "bar", .value = "world" }, | 331 | .{ .name = "bar", .value = "world" }, |
| 332 | }), bar_entries); | 332 | }), bar_entries); |
| 333 | | 333 | |
| 334 | const baz_entries = (try h.getEntries(testing.allocator, "baz")).?; | 334 | const baz_entries = (try h.getEntries(testing.allocator, "baz")).?; |
| 335 | defer testing.allocator.free(baz_entries); | 335 | defer testing.allocator.free(baz_entries); |
| 336 | try testing.expectEqualDeep(@as([]const HeaderEntry, &[_]HeaderEntry{ | 336 | try testing.expectEqualDeep(@as([]const Field, &[_]Field{ |
| 337 | .{ .name = "baz", .value = "hello" }, | 337 | .{ .name = "baz", .value = "hello" }, |
| 338 | }), baz_entries); | 338 | }), baz_entries); |
| 339 | | 339 | |
| 340 | const pog_entries = (try h.getEntries(testing.allocator, "pog")); | 340 | const pog_entries = (try h.getEntries(testing.allocator, "pog")); |
| 341 | try testing.expectEqual(@as(?[]const HeaderEntry, null), pog_entries); | 341 | try testing.expectEqual(@as(?[]const Field, null), pog_entries); |
| 342 | | 342 | |
| 343 | try testing.expectEqualStrings("world", h.getFirstValue("hello").?); | 343 | try testing.expectEqualStrings("world", h.getFirstValue("hello").?); |
| 344 | try testing.expectEqualStrings("bar", h.getFirstValue("foo").?); | 344 | try testing.expectEqualStrings("bar", h.getFirstValue("foo").?); |