56 lines
1.9 KiB
Zig
56 lines
1.9 KiB
Zig
const std = @import("std");
|
|
|
|
pub const IntersectionIterator = struct {
|
|
ref: std.mem.TokenIterator(u8),
|
|
rest: []const []const u8,
|
|
|
|
/// Returns the next occurrence or null. Returned value is owned by originally passed slice
|
|
pub fn next(self: *IntersectionIterator) ?[]const u8 {
|
|
// If this returns null, there's no more items to check. We're finished.
|
|
const needle = self.ref.next() orelse return null;
|
|
|
|
// Search into every one of the strings
|
|
haystack: for (self.rest) |haystack| {
|
|
|
|
// The items are separated by spaces, iterate through those
|
|
var haystack_iter = std.mem.tokenize(u8, haystack, " ");
|
|
|
|
// If the word is found, it short circuits and tries the next haystack
|
|
while (haystack_iter.next()) |hay_blade| {
|
|
if (std.mem.eql(u8, hay_blade, needle)) continue :haystack;
|
|
}
|
|
|
|
// If this point is reached, the needle wasn't found.
|
|
// Try the next one
|
|
return self.next();
|
|
}
|
|
|
|
// If we got here, no not-matching haysack was found. A match!
|
|
return needle;
|
|
}
|
|
};
|
|
|
|
/// Finds the common tokens inside space separated strings
|
|
/// and returns a slice to the first token that matches
|
|
pub fn intersection(slices: []const []const u8) IntersectionIterator {
|
|
// Tokenize the first entry and save the rest as references to check
|
|
return IntersectionIterator{
|
|
.ref = std.mem.tokenize(u8, slices[0], " "),
|
|
.rest = slices[1..],
|
|
};
|
|
}
|
|
|
|
pub fn readUntilDelimiterAllocZ(
|
|
reader: anytype, // TODO: Fix this and set the correct type, I got no clue rn
|
|
allocator: std.mem.Allocator,
|
|
delimiter: u8,
|
|
max_size: usize,
|
|
) ![:0]u8 {
|
|
var array_list = std.ArrayList(u8).init(allocator);
|
|
defer array_list.deinit();
|
|
|
|
try reader.readUntilDelimiterArrayList(&array_list, delimiter, max_size);
|
|
|
|
return array_list.toOwnedSliceSentinel(0);
|
|
}
|