Application Context Implementation #4

Closed
kayomn wants to merge 93 commits from event-loop-dev into main
1 changed files with 82 additions and 76 deletions
Showing only changes of commit cfd3e85021 - Show all commits

View File

@ -32,26 +32,6 @@ pub fn Spliterator(comptime Element: type) type {
return (self.source.len != 0); return (self.source.len != 0);
} }
test "Check has data" {
var empty_spliterator = Spliterator(u8){
.source = "",
.delimiter = "/",
};
try testing.expect(!empty_spliterator.hasNext());
var stateful_spliterator = Spliterator(u8){
.source = "data",
.delimiter = "/",
};
try testing.expect(stateful_spliterator.hasNext());
_ = try stateful_spliterator.next();
try testing.expect(!stateful_spliterator.hasNext());
}
/// ///
/// Iterates on `self` and returns the next view of [Spliterator.source] that matches /// Iterates on `self` and returns the next view of [Spliterator.source] that matches
/// [Spliterator.delimiter], or `null` if there is no more data to be processed. /// [Spliterator.delimiter], or `null` if there is no more data to be processed.
@ -59,24 +39,52 @@ pub fn Spliterator(comptime Element: type) type {
pub fn next(self: *Self) ?[]const Element { pub fn next(self: *Self) ?[]const Element {
if (!self.hasNext()) return null; if (!self.hasNext()) return null;
if (self.delimiter.len == 0) {
defer self.source = self.source[self.source.len .. self.source.len];
return self.source[0 .. self.source.len];
}
if (findFirstOf(Element, self.source, self.delimiter, struct { if (findFirstOf(Element, self.source, self.delimiter, struct {
fn testEquality(this: Element, that: Element) bool { fn testEquality(this: Element, that: Element) bool {
return this == that; return this == that;
} }
}.testEquality)) |head| { }.testEquality)) |head| {
const tail = (head + self.delimiter.len); defer self.source = self.source[(head + self.delimiter.len) .. self.source.len];
defer self.source = self.source[tail .. self.source.len]; return self.source[0 .. head];
return self.source[0 .. (tail - 1)];
} }
defer self.source = self.source[self.source.len .. self.source.len]; defer self.source = self.source[self.source.len .. self.source.len];
return self.source; return self.source;
} }
};
}
test "Spliterator of string literals" {
// Empty source.
{
var spliterator = Spliterator(u8){
.source = "",
.delimiter = " ",
};
try testing.expect(!spliterator.hasNext());
}
// Empty delimiter.
{
var spliterator = Spliterator(u8){
.source = "aaa",
.delimiter = "",
};
try testing.expect(spliterator.hasNext());
try testing.expect(equals(u8, spliterator.next().?, "aaa"));
try testing.expect(!spliterator.hasNext());
}
test "Iterate through data" {
// Single-character delimiter. // Single-character delimiter.
{ {
var spliterator = Spliterator(u8){ var spliterator = Spliterator(u8){
@ -88,10 +96,14 @@ pub fn Spliterator(comptime Element: type) type {
"character", "separated", "hello", "world"}; "character", "separated", "hello", "world"};
var index = @as(usize, 0); var index = @as(usize, 0);
const components_tail = components.len - 1;
while (spliterator.next()) |split| : (index += 1) { while (spliterator.next()) |split| : (index += 1) {
try testing.expect(spliterator.hasNext() == (index < components_tail));
try testing.expect(equals(u8, split, components[index])); try testing.expect(equals(u8, split, components[index]));
} }
try testing.expect(!spliterator.hasNext());
} }
// Multi-character delimiter. // Multi-character delimiter.
@ -103,13 +115,15 @@ pub fn Spliterator(comptime Element: type) type {
const components = [_][]const u8{"finding a ", " in a ", " stack"}; const components = [_][]const u8{"finding a ", " in a ", " stack"};
var index = @as(usize, 0); var index = @as(usize, 0);
const components_tail = components.len - 1;
while (spliterator.next()) |split| : (index += 1) { while (spliterator.next()) |split| : (index += 1) {
try testing.expect(spliterator.hasNext() == (index < components_tail));
try testing.expect(equals(u8, split, components[index])); try testing.expect(equals(u8, split, components[index]));
} }
try testing.expect(!spliterator.hasNext());
} }
}
};
} }
/// ///
@ -118,22 +132,6 @@ pub fn Spliterator(comptime Element: type) type {
/// ///
pub const Writer = meta.Function(@sizeOf(usize), []const u8, usize); pub const Writer = meta.Function(@sizeOf(usize), []const u8, usize);
///
/// Returns `true` if `elements` starts with the characters in `with`, otherwise `false`.
///
pub fn begins(comptime Element: type, elements: []const Element, with: []const Element) bool {
if (elements.len < with.len) return false;
return equals(Element, elements[0 .. with.len], with);
}
test "Check memory begins with" {
const bytes_sequence = &.{69, 42};
try testing.expect(begins(u8, &.{69, 42, 0, 89}, bytes_sequence));
try testing.expect(!begins(u8, &.{69, 89, 42, 0}, bytes_sequence));
}
/// ///
/// Returns a sliced reference of the raw bytes in `pointer`. /// Returns a sliced reference of the raw bytes in `pointer`.
/// ///
@ -260,9 +258,8 @@ pub fn findFirstOf(comptime Element: type, haystack: []const Element,
const tail = (haystack.len - needle.len); const tail = (haystack.len - needle.len);
walk_haystack: while (head <= tail) : (head += 1) { walk_haystack: while (head <= tail) : (head += 1) {
for (needle) |element, index| { for (needle) |element, index|
if (!testEquality(haystack[head + index], element)) continue: walk_haystack; if (!testEquality(haystack[head + index], element)) continue: walk_haystack;
}
return head; return head;
} }
@ -271,7 +268,16 @@ pub fn findFirstOf(comptime Element: type, haystack: []const Element,
} }
test "Find first of sequence" { test "Find first of sequence" {
const haystack = &.{"foo", "bar", "baz"};
const testEquality = struct {
fn testEquality(this: []const u8, that: []const u8) bool {
return equals(u8, this, that);
}
}.testEquality;
try testing.expect(findFirstOf([]const u8, haystack, &.{"bar", "baz"}, testEquality).? == 1);
try testing.expect(findFirstOf([]const u8, haystack, &.{"baz", "bar"}, testEquality) == null);
} }
kayomn marked this conversation as resolved Outdated

Worth mentioning that this uses linear search?

Worth mentioning that this uses linear search?
/// ///