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 Recording = Entities.Recording;
|
||||||
const Release = Entities.Release;
|
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 {
|
pub const Result = struct {
|
||||||
created: ?[]const u8 = null,
|
created: ?[]const u8 = null,
|
||||||
count: ?u32 = null,
|
count: ?u32 = null,
|
||||||
|
|
@ -131,116 +122,70 @@ pub const Result = struct {
|
||||||
}
|
}
|
||||||
return null;
|
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 {
|
pub const searchMetadata = struct {
|
||||||
tn: []const u8,
|
alloc: std.mem.Allocator = undefined,
|
||||||
rgn: []const u8,
|
tn: struct { dec: []const u8, enc: []const u8 = undefined },
|
||||||
an: []const u8,
|
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
|
// 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?
|
// Maybe make fields for encoded data?
|
||||||
pub const searchMetadataEncoded = struct {
|
//pub const searchMetadataEncoded = struct {
|
||||||
alloc: std.mem.Allocator,
|
// alloc: std.mem.Allocator,
|
||||||
tn: []const u8,
|
// tn: []const u8,
|
||||||
rgn: []const u8,
|
// rgn: []const u8,
|
||||||
an: []const u8,
|
// an: []const u8,
|
||||||
|
//
|
||||||
pub fn deinit(self: *const searchMetadataEncoded) void {
|
// pub fn deinit(self: *const searchMetadataEncoded) void {
|
||||||
self.alloc.free(self.an);
|
// self.alloc.free(self.an);
|
||||||
self.alloc.free(self.rgn);
|
// self.alloc.free(self.rgn);
|
||||||
self.alloc.free(self.tn);
|
// self.alloc.free(self.tn);
|
||||||
}
|
// }
|
||||||
};
|
//};
|
||||||
|
|
||||||
pub const searchIDs = union {
|
pub const searchIDs = union {
|
||||||
id: []const u8,
|
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" {
|
test "pe_jethro_tull" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
const jt = searchMetadata{ .tn = "Aqualung", .rgn = "Aqualung", .an = "Jethro Tull" };
|
var jt = searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "Aqualung" }, .rn = .{ .dec = "Aqualung" }, .an = .{ .dec = "Jethro Tull" } };
|
||||||
const encoded = try percentEncode(test_alloc, jt);
|
try jt.percentEncode();
|
||||||
defer encoded.deinit();
|
defer jt.deinit();
|
||||||
try testing.expect(std.mem.eql(u8, encoded.an, "Jethro+Tull"));
|
try testing.expect(std.mem.eql(u8, jt.an.enc, "Jethro+Tull"));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "pe_aphex_twin" {
|
test "pe_aphex_twin" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
const at = searchMetadata{ .tn = "#3", .rgn = "Selected Ambient Works Volume II", .an = "Aphex Twin" };
|
var at = searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "#3" }, .rn = .{ .dec = "Selected Ambient Works Volume II" }, .an = .{ .dec = "Aphex Twin" } };
|
||||||
const encoded = try percentEncode(test_alloc, at);
|
try at.percentEncode();
|
||||||
defer encoded.deinit();
|
defer at.deinit();
|
||||||
try testing.expect(std.mem.eql(u8, encoded.tn, "%233"));
|
try testing.expect(std.mem.eql(u8, at.tn.enc, "%233"));
|
||||||
}
|
}
|
||||||
|
|
||||||
test "pe_bon_iver" {
|
test "pe_bon_iver" {
|
||||||
const test_alloc = std.testing.allocator;
|
const test_alloc = std.testing.allocator;
|
||||||
const bi = searchMetadata{ .tn = "21 M♢♢N WATER", .rgn = "22, a Million", .an = "Bon Iver" };
|
var bi = searchMetadata{ .alloc = test_alloc, .tn = .{ .dec = "21 M♢♢N WATER" }, .rn = .{ .dec = "22, a Million" }, .an = .{ .dec = "Bon Iver" } };
|
||||||
const encoded = try percentEncode(test_alloc, bi);
|
try bi.percentEncode();
|
||||||
defer encoded.deinit();
|
defer bi.deinit();
|
||||||
try testing.expect(std.mem.eql(u8, encoded.tn, "21+M%e2%99%a2%e2%99%a2N+WATER"));
|
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