Skip to content

Commit

Permalink
feat: simplify zf module API
Browse files Browse the repository at this point in the history
Make the zf high-level API simpler to use by removing the filename
parameter.
  • Loading branch information
natecraddock committed Feb 25, 2023
1 parent 935f7ab commit 0e81f7b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 39 deletions.
34 changes: 17 additions & 17 deletions src/clib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ const testing = std.testing;
/// rank a given string against a slice of tokens
export fn rank(
str: [*:0]const u8,
filename: ?[*:0]const u8,
tokens: [*]const [*:0]const u8,
num_tokens: usize,
case_sensitive: bool,
plain: bool,
) f64 {
const string = std.mem.span(str);
const name = if (filename != null) std.mem.span(filename) else null;
const filename = if (plain) null else std.fs.path.basename(string);

var total_rank: f64 = 0;
var index: usize = 0;
while (index < num_tokens) : (index += 1) {
const token = std.mem.span(tokens[index]);
if (filter.rankToken(string, name, token, case_sensitive)) |r| {
if (filter.rankToken(string, filename, token, case_sensitive)) |r| {
total_rank += r;
} else return -1.0;
}
Expand All @@ -42,27 +42,27 @@ export fn rankToken(
test "rank exported C library interface" {
{
const tokens: [2][*:0]const u8 = .{ "a", "z" };
try testing.expect(rank("abcdefg", null, &tokens, 2, false) == -1);
try testing.expect(rank("abcdefg", &tokens, 2, false, false) == -1);
}
{
const tokens: [2][*:0]const u8 = .{ "a", "b" };
try testing.expect(rank("abcdefg", null, &tokens, 2, false) != -1);
try testing.expect(rank("abcdefg", &tokens, 2, false, false) != -1);
}
{
const tokens: [2][*:0]const u8 = .{ "a", "B" };
try testing.expect(rank("abcdefg", null, &tokens, 2, true) == -1);
try testing.expect(rank("abcdefg", &tokens, 2, true, false) == -1);
}
{
const tokens: [2][*:0]const u8 = .{ "a", "B" };
try testing.expect(rank("aBcdefg", null, &tokens, 2, true) != -1);
try testing.expect(rank("aBcdefg", &tokens, 2, true, false) != -1);
}
{
const tokens: [1][*:0]const u8 = .{"zig"};
try testing.expect(rank("a/path/to/file", null, &tokens, 2, false) == -1);
try testing.expect(rank("a/path/to/file", &tokens, 2, false, false) == -1);
}
{
const tokens: [2][*:0]const u8 = .{ "path", "file" };
try testing.expect(rank("a/path/to/file", "file", &tokens, 2, false) != -1);
try testing.expect(rank("a/path/to/file", &tokens, 2, false, false) != -1);
}

try testing.expect(rankToken("abcdefg", null, "a", false) != -1);
Expand All @@ -77,19 +77,19 @@ const Range = filter.Range;

export fn highlight(
str: [*:0]const u8,
filename: ?[*:0]const u8,
ranges: [*]Range,
tokens: [*]const [*:0]const u8,
num: usize,
case_sensitive: bool,
plain: bool,
) void {
const string = std.mem.span(str);
const name = if (filename != null) std.mem.span(filename) else null;
const filename = if (plain) null else std.fs.path.basename(string);

var index: usize = 0;
while (index < num) : (index += 1) {
const token = std.mem.span(tokens[index]);
ranges[index] = filter.highlightToken(string, name, token, case_sensitive);
ranges[index] = filter.highlightToken(string, filename, token, case_sensitive);
}
}

Expand All @@ -108,20 +108,20 @@ export fn highlightToken(
fn testHighlight(
expectedRanges: []const Range,
str: [*:0]const u8,
filename: ?[*:0]const u8,
tokens: []const [*:0]const u8,
case_sensitive: bool,
plain: bool,
) !void {
var ranges = try testing.allocator.alloc(Range, tokens.len);
defer testing.allocator.free(ranges);
highlight(str, filename, ranges.ptr, tokens.ptr, ranges.len, case_sensitive);
highlight(str, ranges.ptr, tokens.ptr, ranges.len, case_sensitive, plain);
try testing.expectEqualSlices(Range, expectedRanges, ranges);
}

test "highlight exported C library interface" {
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdef", null, &.{ "a", "f" }, false);
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdeF", null, &.{ "a", "F" }, true);
try testHighlight(&.{ .{ .start = 2, .end = 5 }, .{ .start = 10, .end = 13 } }, "a/path/to/file", "file", &.{ "path", "file" }, false);
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdef", &.{ "a", "f" }, false, false);
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdeF", &.{ "a", "F" }, true, false);
try testHighlight(&.{ .{ .start = 2, .end = 5 }, .{ .start = 10, .end = 13 } }, "a/path/to/file", &.{ "path", "file" }, false, false);

try testing.expectEqual(Range{ .start = 0, .end = 0 }, highlightToken("abcdef", null, "a", false));
try testing.expectEqual(Range{ .start = 5, .end = 5 }, highlightToken("abcdeF", null, "F", true));
Expand Down
2 changes: 1 addition & 1 deletion src/filter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const IndexIterator = struct {
/// rank a candidate against the given query tokens
///
/// algorithm inspired by https://github.com/garybernhardt/selecta
fn rankCandidate(
pub fn rankCandidate(
candidate: []const u8,
query_tokens: []const []const u8,
case_sensitive: bool,
Expand Down
37 changes: 16 additions & 21 deletions src/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ const testing = std.testing;
/// rank a given string against a slice of tokens
pub fn rank(
str: []const u8,
filename: ?[]const u8,
tokens: []const []const u8,
case_sensitive: bool,
) f64 {
var total_rank: f64 = 0;
for (tokens) |token| {
if (filter.rankToken(str, filename, token, case_sensitive)) |r| {
total_rank += r;
} else return -1.0;
}
return total_rank;
plain: bool,
) ?f64 {
return filter.rankCandidate(str, tokens, case_sensitive, plain);
}

/// rank a given string against a single token
Expand All @@ -29,12 +23,12 @@ pub fn rankToken(
}

test "rank library interface" {
try testing.expect(rank("abcdefg", null, &.{ "a", "z" }, false) == -1);
try testing.expect(rank("abcdefg", null, &.{ "a", "b" }, false) != -1);
try testing.expect(rank("abcdefg", null, &.{ "a", "B" }, true) == -1);
try testing.expect(rank("aBcdefg", null, &.{ "a", "B" }, true) != -1);
try testing.expect(rank("a/path/to/file", "file", &.{"zig"}, false) == -1);
try testing.expect(rank("a/path/to/file", "file", &.{ "path", "file" }, false) != -1);
try testing.expect(rank("abcdefg", &.{ "a", "z" }, false, false) == null);
try testing.expect(rank("abcdefg", &.{ "a", "b" }, false, false) != null);
try testing.expect(rank("abcdefg", &.{ "a", "B" }, true, false) == null);
try testing.expect(rank("aBcdefg", &.{ "a", "B" }, true, false) != null);
try testing.expect(rank("a/path/to/file", &.{"zig"}, false, false) == null);
try testing.expect(rank("a/path/to/file", &.{ "path", "file" }, false, false) != null);

try testing.expect(rankToken("abcdefg", null, "a", false) != null);
try testing.expect(rankToken("abcdefg", null, "z", false) == null);
Expand All @@ -50,11 +44,12 @@ pub const Range = filter.Range;
/// compute matching ranges given a string and a slice of tokens
pub fn highlight(
str: []const u8,
filename: ?[]const u8,
ranges: []Range,
tokens: []const []const u8,
case_sensitive: bool,
plain: bool,
) void {
const filename = if (plain) null else std.fs.path.basename(str);
for (tokens) |token, i| {
ranges[i] = filter.highlightToken(str, filename, token, case_sensitive);
}
Expand All @@ -73,20 +68,20 @@ pub fn highlightToken(
fn testHighlight(
expectedRanges: []const Range,
str: []const u8,
filename: ?[]const u8,
tokens: []const []const u8,
case_sensitive: bool,
plain: bool,
) !void {
var ranges = try testing.allocator.alloc(Range, tokens.len);
defer testing.allocator.free(ranges);
highlight(str, filename, ranges, tokens, case_sensitive);
highlight(str, ranges, tokens, case_sensitive, plain);
try testing.expectEqualSlices(Range, expectedRanges, ranges);
}

test "highlight library interface" {
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdef", null, &.{ "a", "f" }, false);
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdeF", null, &.{ "a", "F" }, true);
try testHighlight(&.{ .{ .start = 2, .end = 5 }, .{ .start = 10, .end = 13 } }, "a/path/to/file", "file", &.{ "path", "file" }, false);
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdef", &.{ "a", "f" }, false, false);
try testHighlight(&.{ .{ .start = 0, .end = 0 }, .{ .start = 5, .end = 5 } }, "abcdeF", &.{ "a", "F" }, true, false);
try testHighlight(&.{ .{ .start = 2, .end = 5 }, .{ .start = 10, .end = 13 } }, "a/path/to/file", &.{ "path", "file" }, false, false);

try testing.expectEqual(Range{ .start = 0, .end = 0 }, highlightToken("abcdef", null, "a", false));
try testing.expectEqual(Range{ .start = 5, .end = 5 }, highlightToken("abcdeF", null, "F", true));
Expand Down

0 comments on commit 0e81f7b

Please sign in to comment.