zuletzt/src/apply_rule.zig

73 lines
2.9 KiB
Zig

const std = @import("std");
const Rules = @import("./types.zig").Rules;
const Data = @import("./types.zig");
// Wrapper for containsAtLeast to make the switch below to work
fn containsWrapper(haystack: []const u8, needle: []const u8) bool {
return std.mem.containsAtLeast(u8, haystack, 1, needle);
}
fn eqlWrapper(haystack: []const u8, needle: []const u8) bool {
return std.mem.eql(u8, haystack, needle);
}
pub fn applyScrobbleRule(allocator: std.mem.Allocator, scrobble: Data.ImportedScrobble, rules: Rules) !Data.Scrobble {
const artists = try allocator.alloc([]const u8, 1);
artists[0] = scrobble.artist;
var output_scrobble = Data.Scrobble{
.track = scrobble.track,
.artists_track = artists,
.album = scrobble.album,
.artists_album = artists,
.date = scrobble.date,
};
for (rules.rules) |rule| {
var match_found: bool = switch (rule.cond_req) {
.any => false,
.all => true,
};
for (rule.conditionals) |cond| {
const match_fn: *const fn ([]const u8, []const u8) bool = switch (cond.match_cond) {
.is => eqlWrapper,
.contains => containsWrapper,
};
switch (rule.cond_req) {
.any => switch (cond.match_on) {
inline else => |on| match_found = match_found or match_fn(@field(scrobble, @tagName(on)), cond.match_txt),
},
.all => switch (cond.match_on) {
inline else => |on| match_found = match_found and match_fn(@field(scrobble, @tagName(on)), cond.match_txt),
},
}
}
if (match_found) {
for (rule.actions) |act| {
switch (act.action) {
.add => {
var al = std.ArrayList([]const u8).init(allocator);
switch (act.action_on) {
.album, .track => unreachable,
inline else => |on| {
try al.appendSlice(@field(output_scrobble, @tagName(on)));
try al.append(act.action_txt);
const list = try al.toOwnedSlice();
@field(output_scrobble, @tagName(on)) = list;
},
}
},
.replace => switch (act.action_on) {
inline .album, .track => |on| @field(output_scrobble, @tagName(on)) = act.action_txt,
inline .artists_album, .artists_track => |on| {
const artist = try allocator.alloc([]const u8, 1);
artist[0] = act.action_txt;
@field(output_scrobble, @tagName(on)) = artist;
},
},
}
}
}
}
return output_scrobble;
}