Tidy up IO code
This commit is contained in:
parent
14e5e18228
commit
cfd3e85021
|
@ -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,14 +115,16 @@ 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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Closure that captures a reference to writable resources like block devices, memory buffers,
|
/// Closure that captures a reference to writable resources like block devices, memory buffers,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue