Combine searchMetadata and searchMetadataEncoded types
This commit is contained in:
parent
fa46f68fd0
commit
742c3887c9
1 changed files with 69 additions and 146 deletions
|
|
@ -6,15 +6,6 @@ const Artist = Entities.Artist;
|
|||
const Recording = Entities.Recording;
|
||||
const Release = Entities.Release;
|
||||
|
||||
pub const parseOption = union(enum) {
|
||||
song,
|
||||
album,
|
||||
artist,
|
||||
all,
|
||||
};
|
||||
|
||||
pub const parseByOptions = struct { parse: parseOption = .song, specifyBy: parseOption = .song };
|
||||
|
||||
pub const Result = struct {
|
||||
created: ?[]const u8 = null,
|
||||
count: ?u32 = null,
|
||||
|
|
@ -131,116 +122,70 @@ pub const Result = struct {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//pub fn getArtistID(self: *const Result, smd: searchMetadata, parseByOption: ?parseByOptions) ?[]const u8 {
|
||||
// _ = parseByOption; //
|
||||
// if (self.count) |count| { // Otherwise there was an error
|
||||
// switch (count) {
|
||||
// 0 => return null, // No results
|
||||
// 1 => {
|
||||
// if (self.recordings.?[0].@"artist-credit") |acs| {
|
||||
// for (acs) |ac| {
|
||||
// if (std.mem.eql(u8, ac.name, smd.an)) return ac.artist.id; // Make this case/diacritic insensitive
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// },
|
||||
// else => {
|
||||
// for (self.recordings.?) |rc| {
|
||||
// if (std.mem.eql(u8, rc.title, smd.tn)) { // Make this case/diacritic insensitive
|
||||
// for (rc.@"artist-credit".?) |ac| {
|
||||
// if (std.mem.eql(u8, ac.name, smd.an)) return ac.artist.id;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// return null; // Maybe return error here instead
|
||||
//}
|
||||
|
||||
//// Not sure if I want to get a ReleaseGroup or Release yet. Start with ReleaseGroup
|
||||
//pub fn getReleaseGroupID(self: *const Result, smd: searchMetadata) ?[]const u8 {
|
||||
// if (self.count) |count| {
|
||||
// switch (count) {
|
||||
// 0 => return null,
|
||||
// 1 => {
|
||||
// switch (self.recordings.?[0].releases.?.len) {
|
||||
// 0 => unreachable,
|
||||
// 1 => return self.recordings.?[0].releases.?[0].id,
|
||||
// else => {
|
||||
// for (self.recordings.?[0].releases.?) |re| {
|
||||
// if (std.mem.eql(u8, re.title, smd.rgn)) return re.id;
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// else => { // This is not ideal, limit the number of results
|
||||
// for (self.recordings.?) |rc| {
|
||||
// if (std.mem.eql(u8, rc.title, smd.tn)) {
|
||||
// for (rc.releases.?) |re| {
|
||||
// if (std.mem.eql(u8, re.@"release-group".?.title, smd.rgn)) return re.@"release-group".?.id;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//pub fn getRecordingID(self: *const Result, smd: searchMetadata) ?[]const u8 {
|
||||
// if (self.count) |count| {
|
||||
// switch (count) {
|
||||
// 0 => return null,
|
||||
// 1 => return self.recordings.?[0].id,
|
||||
// else => {
|
||||
// const rcs: []Recording = self.recordings.?;
|
||||
// //for (rcs, 0..) |rc, i| {
|
||||
// // rcs[i].dt = (try zeit.instant(.{ .source = .{ .iso8601 = rc.@"first-release-date".? } })).unixTimestamp();
|
||||
// //}
|
||||
// std.mem.sort(Recording, rcs, {}, Recording.lessThan);
|
||||
// for (rcs) |rc| {
|
||||
// if (std.mem.eql(u8, smd.tn, rc.title)) {
|
||||
// for (rc.@"artist-credit".?) |ac| {
|
||||
// if (std.mem.eql(u8, smd.an, ac.name)) {
|
||||
// for (rc.releases.?) |re| {
|
||||
// if (std.mem.eql(u8, smd.rgn, re.@"release-group".?.title)) {
|
||||
// //std.log.err("{s}", .{rc.id});
|
||||
// return rc.id;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
};
|
||||
|
||||
pub const parseOption = union(enum) {
|
||||
song,
|
||||
album,
|
||||
artist,
|
||||
all,
|
||||
};
|
||||
|
||||
pub const parseByOptions = struct { parse: parseOption = .song, specifyBy: parseOption = .song };
|
||||
|
||||
const eunuchMetadata = struct {
|
||||
tn: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||
rn: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||
an: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||
};
|
||||
|
||||
// Maybe just use a HashMap...
|
||||
pub const searchMetadata = struct {
|
||||
tn: []const u8,
|
||||
rgn: []const u8,
|
||||
an: []const u8,
|
||||
alloc: std.mem.Allocator = undefined,
|
||||
tn: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||
rn: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||
an: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||
|
||||
pub fn deinit(self: *searchMetadata) void {
|
||||
self.alloc.free(self.tn.enc);
|
||||
self.alloc.free(self.rn.enc);
|
||||
self.alloc.free(self.an.enc);
|
||||
}
|
||||
|
||||
pub fn percentEncode(self: *searchMetadata) !void {
|
||||
inline for (std.meta.fields(eunuchMetadata)) |k| {
|
||||
var encoded = std.ArrayList(u8).init(self.alloc);
|
||||
errdefer encoded.deinit();
|
||||
for (@field(self, k.name).dec) |v| {
|
||||
if ((v >= 'A' and v <= 'Z') or (v >= 'a' and v <= 'z') or (v >= '0' and v <= '9') or v == '-' or v == '_' or v == '.' or v == '~') {
|
||||
try encoded.append(v);
|
||||
} else if (v == ' ') {
|
||||
try encoded.append('+');
|
||||
} else {
|
||||
const hex = try std.fmt.allocPrint(self.alloc, "%{x}", .{v});
|
||||
defer self.alloc.free(hex);
|
||||
try encoded.appendSlice(hex);
|
||||
}
|
||||
}
|
||||
@field(self, k.name).enc = try encoded.toOwnedSlice();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// I don't think I need a second type, but I'd like to hold on to the original, unencoded metadata as well, so maybe this is fine
|
||||
// Maybe make fields for encoded data?
|
||||
pub const searchMetadataEncoded = struct {
|
||||
alloc: std.mem.Allocator,
|
||||
tn: []const u8,
|
||||
rgn: []const u8,
|
||||
an: []const u8,
|
||||
|
||||
pub fn deinit(self: *const searchMetadataEncoded) void {
|
||||
self.alloc.free(self.an);
|
||||
self.alloc.free(self.rgn);
|
||||
self.alloc.free(self.tn);
|
||||
}
|
||||
};
|
||||
//pub const searchMetadataEncoded = struct {
|
||||
// alloc: std.mem.Allocator,
|
||||
// tn: []const u8,
|
||||
// rgn: []const u8,
|
||||
// an: []const u8,
|
||||
//
|
||||
// pub fn deinit(self: *const searchMetadataEncoded) void {
|
||||
// self.alloc.free(self.an);
|
||||
// self.alloc.free(self.rgn);
|
||||
// self.alloc.free(self.tn);
|
||||
// }
|
||||
//};
|
||||
|
||||
pub const searchIDs = union {
|
||||
id: []const u8,
|
||||
|
|
@ -251,48 +196,26 @@ pub const searchIDs = union {
|
|||
},
|
||||
};
|
||||
|
||||
pub fn percentEncode(alloc: std.mem.Allocator, smd: searchMetadata) !searchMetadataEncoded {
|
||||
var output = searchMetadataEncoded{ .alloc = alloc, .tn = undefined, .rgn = undefined, .an = undefined };
|
||||
inline for (std.meta.fields(searchMetadata)) |k| {
|
||||
var encoded = std.ArrayList(u8).init(alloc);
|
||||
errdefer encoded.deinit();
|
||||
for (@field(smd, k.name)) |v| {
|
||||
if ((v >= 'A' and v <= 'Z') or (v >= 'a' and v <= 'z') or (v >= '0' and v <= '9') or v == '-' or v == '_' or v == '.' or v == '~') {
|
||||
try encoded.append(v);
|
||||
} else if (v == ' ') {
|
||||
try encoded.append('+');
|
||||
} else {
|
||||
const hex = try std.fmt.allocPrint(alloc, "%{x}", .{v});
|
||||
defer alloc.free(hex);
|
||||
try encoded.appendSlice(hex);
|
||||
}
|
||||
}
|
||||
@field(output, k.name) = try encoded.toOwnedSlice();
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
test "pe_jethro_tull" {
|
||||
const test_alloc = std.testing.allocator;
|
||||
const jt = searchMetadata{ .tn = "Aqualung", .rgn = "Aqualung", .an = "Jethro Tull" };
|
||||
const encoded = try percentEncode(test_alloc, jt);
|
||||
defer encoded.deinit();
|
||||
try testing.expect(std.mem.eql(u8, encoded.an, "Jethro+Tull"));
|
||||
var jt = searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "Aqualung" }, .rn = .{ .dec = "Aqualung" }, .an = .{ .dec = "Jethro Tull" } };
|
||||
try jt.percentEncode();
|
||||
defer jt.deinit();
|
||||
try testing.expect(std.mem.eql(u8, jt.an.enc, "Jethro+Tull"));
|
||||
}
|
||||
|
||||
test "pe_aphex_twin" {
|
||||
const test_alloc = std.testing.allocator;
|
||||
const at = searchMetadata{ .tn = "#3", .rgn = "Selected Ambient Works Volume II", .an = "Aphex Twin" };
|
||||
const encoded = try percentEncode(test_alloc, at);
|
||||
defer encoded.deinit();
|
||||
try testing.expect(std.mem.eql(u8, encoded.tn, "%233"));
|
||||
var at = searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "#3" }, .rn = .{ .dec = "Selected Ambient Works Volume II" }, .an = .{ .dec = "Aphex Twin" } };
|
||||
try at.percentEncode();
|
||||
defer at.deinit();
|
||||
try testing.expect(std.mem.eql(u8, at.tn.enc, "%233"));
|
||||
}
|
||||
|
||||
test "pe_bon_iver" {
|
||||
const test_alloc = std.testing.allocator;
|
||||
const bi = searchMetadata{ .tn = "21 M♢♢N WATER", .rgn = "22, a Million", .an = "Bon Iver" };
|
||||
const encoded = try percentEncode(test_alloc, bi);
|
||||
defer encoded.deinit();
|
||||
try testing.expect(std.mem.eql(u8, encoded.tn, "21+M%e2%99%a2%e2%99%a2N+WATER"));
|
||||
var bi = searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "21 M♢♢N WATER" }, .rn = .{ .dec = "22, a Million" }, .an = .{ .dec = "Bon Iver" } };
|
||||
try bi.percentEncode();
|
||||
defer bi.deinit();
|
||||
try testing.expect(std.mem.eql(u8, bi.tn.enc, "21+M%e2%99%a2%e2%99%a2N+WATER"));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue