Formatting
ci / checks (push) Successful in 42m54s

This commit is contained in:
khodowany
2026-09-15 00:06:02 -05:00
parent 44e100985a
commit fe42d811fa
81 changed files with 4349 additions and 3340 deletions
+61 -64
View File
@@ -1,27 +1,20 @@
#include <vamp_zero/library.hpp>
#include <algorithm>
#include <expected>
#include <filesystem>
#include <fstream>
#include <iterator>
#include <limits>
#include <sstream>
#include <string>
#include <string_view>
#include <system_error>
#include <utility>
#include <vector>
#include <boost/json/array.hpp>
#include <boost/json/object.hpp>
#include <boost/json/parse.hpp>
#include <boost/json/value.hpp>
#include <boost/system/error_code.hpp>
#include <vamp_zero/errors.hpp>
#include <vamp_zero/score.hpp>
#include <vamp_zero/library.hpp>
#include <vamp_zero/notation.hpp>
namespace {
auto invalid(std::string message) -> modulus::error {
@@ -33,7 +26,7 @@ auto human_label(std::string value) -> std::string {
return "Score";
}
auto capitalize_next = std::bool_t{true};
for (auto& ch : value) {
for (auto &ch : value) {
if (ch == '-' || ch == '_') {
ch = ' ';
capitalize_next = true;
@@ -47,33 +40,40 @@ auto human_label(std::string value) -> std::string {
return value;
}
auto practice_type_label(std::string const& value) -> std::string {
auto practice_type_label(std::string const &value) -> std::string {
return human_label(value) + " Practice";
}
auto load_score_documents(std::filesystem::path const& directory, std::bool_t required) -> std::expected<std::vector<vamp_zero::score_document>, modulus::error> {
auto load_score_documents(std::filesystem::path const &directory, std::bool_t required) -> std::expected<std::vector<vamp_zero::score_document>, modulus::error> {
auto error = std::error_code{};
if (!std::filesystem::exists(directory, error)) {
auto exists = std::filesystem::exists(directory, error);
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to inspect score assets: " + error.message()));
}
if (!exists) {
if (required) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::NOT_FOUND, "score asset directory not found: " + directory.string()));
}
return std::vector<vamp_zero::score_document>{};
}
auto paths = std::vector<std::filesystem::path>{};
for (auto const& entry : std::filesystem::directory_iterator{directory, error}) {
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to scan score assets: " + error.message()));
auto entries = std::filesystem::directory_iterator{directory, error};
auto end = std::filesystem::directory_iterator{};
while (!error && entries != end) {
auto const &entry = *entries;
if (entry.is_regular_file(error) && entry.path().extension() == ".json") {
paths.push_back(entry.path());
}
if (!entry.is_regular_file() || entry.path().extension() != ".json") {
continue;
if (!error) {
entries.increment(error);
}
paths.push_back(entry.path());
}
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to scan score assets: " + error.message()));
}
std::sort(paths.begin(), paths.end());
auto documents = std::vector<vamp_zero::score_document>{};
for (auto const& path : paths) {
for (auto const &path : paths) {
auto input = std::ifstream{path, std::ios::binary};
if (!input) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::NOT_FOUND, "failed to open score JSON: " + path.string()));
@@ -88,15 +88,15 @@ auto load_score_documents(std::filesystem::path const& directory, std::bool_t re
return documents;
}
auto path_parts(std::filesystem::path const& path) -> std::vector<std::string> {
auto path_parts(std::filesystem::path const &path) -> std::vector<std::string> {
auto parts = std::vector<std::string>{};
for (auto const& part : path) {
for (auto const &part : path) {
parts.push_back(part.string());
}
return parts;
}
auto key_rank(std::string const& key) -> std::size_t {
auto key_rank(std::string const &key) -> std::size_t {
static auto const keys = std::vector<std::string>{
"C",
"Db",
@@ -116,8 +116,8 @@ auto key_rank(std::string const& key) -> std::size_t {
return found == keys.end() ? keys.size() : static_cast<std::size_t>(std::distance(keys.begin(), found));
}
auto sync_primary_variant(vamp_zero::practice_exercise& exercise) -> void {
std::sort(exercise.variants.begin(), exercise.variants.end(), [](auto const& left, auto const& right) {
auto sync_primary_variant(vamp_zero::practice_exercise &exercise) -> void {
std::sort(exercise.variants.begin(), exercise.variants.end(), [](auto const &left, auto const &right) {
auto left_rank = key_rank(left.key_signature);
auto right_rank = key_rank(right.key_signature);
if (left_rank != right_rank) {
@@ -128,7 +128,7 @@ auto sync_primary_variant(vamp_zero::practice_exercise& exercise) -> void {
if (exercise.variants.empty()) {
return;
}
auto const& primary = exercise.variants.front();
auto const &primary = exercise.variants.front();
exercise.key_signature = primary.key_signature;
exercise.source_path = primary.source_path;
exercise.source_json = primary.source_json;
@@ -136,10 +136,9 @@ auto sync_primary_variant(vamp_zero::practice_exercise& exercise) -> void {
exercise.total_pages = primary.total_pages;
}
auto same_practice_exercise(vamp_zero::practice_exercise const& left, vamp_zero::practice_exercise const& right) -> std::bool_t {
return left.id == right.id
&& left.practice_type_id == right.practice_type_id
&& left.lesson_group_id == right.lesson_group_id;
auto same_practice_exercise(vamp_zero::practice_exercise const &left, vamp_zero::practice_exercise const &right) -> std::bool_t {
return left.id == right.id && left.practice_type_id == right.practice_type_id &&
left.lesson_group_id == right.lesson_group_id;
}
}
@@ -149,15 +148,14 @@ auto vamp_zero::parse_score_document(std::string_view json, std::string source_p
}
auto vamp_zero::group_library_parts(std::vector<vamp_zero::library_part> parts) -> vamp_zero::library_state {
std::sort(parts.begin(), parts.end(), [](auto const& left, auto const& right) {
std::sort(parts.begin(), parts.end(), [](auto const &left, auto const &right) {
if (left.title != right.title) {
return left.title < right.title;
}
return left.part < right.part;
});
auto groups = std::vector<vamp_zero::song_group>{};
for (auto const& part : parts) {
for (auto const &part : parts) {
if (groups.empty() || groups.back().title != part.title || groups.back().composer != part.composer) {
groups.push_back({
.title = part.title,
@@ -173,7 +171,7 @@ auto vamp_zero::group_library_parts(std::vector<vamp_zero::library_part> parts)
}
auto vamp_zero::group_practice_exercises(std::vector<vamp_zero::practice_exercise> exercises) -> vamp_zero::practice_library {
std::sort(exercises.begin(), exercises.end(), [](auto const& left, auto const& right) {
std::sort(exercises.begin(), exercises.end(), [](auto const &left, auto const &right) {
if (left.practice_type_id != right.practice_type_id) {
return left.practice_type_id < right.practice_type_id;
}
@@ -188,27 +186,20 @@ auto vamp_zero::group_practice_exercises(std::vector<vamp_zero::practice_exercis
}
return left.source_path < right.source_path;
});
auto merged = std::vector<vamp_zero::practice_exercise>{};
for (auto& exercise : exercises) {
for (auto &exercise : exercises) {
if (!merged.empty() && same_practice_exercise(merged.back(), exercise)) {
merged.back().variants.insert(
merged.back().variants.end(),
std::make_move_iterator(exercise.variants.begin()),
std::make_move_iterator(exercise.variants.end())
);
merged.back().variants.insert(merged.back().variants.end(), std::make_move_iterator(exercise.variants.begin()), std::make_move_iterator(exercise.variants.end()));
sync_primary_variant(merged.back());
continue;
}
sync_primary_variant(exercise);
merged.push_back(std::move(exercise));
}
auto types = std::vector<vamp_zero::practice_type_group>{};
for (auto const& exercise : merged) {
auto type = std::find_if(types.begin(), types.end(), [&](auto const& item) {
return item.id == exercise.practice_type_id;
});
for (auto const &exercise : merged) {
auto type =
std::find_if(types.begin(), types.end(), [&](auto const &item) { return item.id == exercise.practice_type_id; });
if (type == types.end()) {
types.push_back({
.id = exercise.practice_type_id,
@@ -216,7 +207,7 @@ auto vamp_zero::group_practice_exercises(std::vector<vamp_zero::practice_exercis
});
type = std::prev(types.end());
}
auto lesson = std::find_if(type->lesson_groups.begin(), type->lesson_groups.end(), [&](auto const& item) {
auto lesson = std::find_if(type->lesson_groups.begin(), type->lesson_groups.end(), [&](auto const &item) {
return item.id == exercise.lesson_group_id;
});
if (lesson == type->lesson_groups.end()) {
@@ -234,13 +225,13 @@ auto vamp_zero::group_practice_exercises(std::vector<vamp_zero::practice_exercis
};
}
auto vamp_zero::load_performance_library(std::string const& assets_path) -> std::expected<vamp_zero::library_state, modulus::error> {
auto vamp_zero::load_performance_library(std::string const &assets_path) -> std::expected<vamp_zero::library_state, modulus::error> {
auto documents = load_score_documents(std::filesystem::path{assets_path} / "songs", true);
if (!documents) {
return std::unexpected(documents.error());
}
auto parts = std::vector<vamp_zero::library_part>{};
for (auto& document : *documents) {
for (auto &document : *documents) {
parts.push_back({
.id = document.id,
.title = document.title,
@@ -256,27 +247,34 @@ auto vamp_zero::load_performance_library(std::string const& assets_path) -> std:
return vamp_zero::group_library_parts(std::move(parts));
}
auto vamp_zero::load_practice_library(std::string const& assets_path) -> std::expected<vamp_zero::practice_library, modulus::error> {
auto vamp_zero::load_practice_library(std::string const &assets_path) -> std::expected<vamp_zero::practice_library, modulus::error> {
auto root = std::filesystem::path{assets_path} / "practice";
auto error = std::error_code{};
if (!std::filesystem::exists(root, error)) {
auto exists = std::filesystem::exists(root, error);
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to inspect practice assets: " + error.message()));
}
if (!exists) {
return vamp_zero::practice_library{};
}
auto paths = std::vector<std::filesystem::path>{};
for (auto const& entry : std::filesystem::recursive_directory_iterator{root, error}) {
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to scan practice assets: " + error.message()));
auto entries = std::filesystem::recursive_directory_iterator{root, error};
auto end = std::filesystem::recursive_directory_iterator{};
while (!error && entries != end) {
auto const &entry = *entries;
if (entry.is_regular_file(error) && entry.path().extension() == ".json") {
paths.push_back(entry.path());
}
if (!entry.is_regular_file() || entry.path().extension() != ".json") {
continue;
if (!error) {
entries.increment(error);
}
paths.push_back(entry.path());
}
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to scan practice assets: " + error.message()));
}
std::sort(paths.begin(), paths.end());
auto exercises = std::vector<vamp_zero::practice_exercise>{};
for (auto const& path : paths) {
for (auto const &path : paths) {
auto relative = std::filesystem::relative(path, root, error);
if (error) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::UNAVAILABLE, "failed to inspect practice asset path: " + error.message()));
@@ -285,7 +283,6 @@ auto vamp_zero::load_practice_library(std::string const& assets_path) -> std::ex
if (parts.size() != 4U) {
return std::unexpected(invalid("practice JSON must be stored as practice/<type>/<lesson_group>/<exercise>/<key>.json: " + path.string()));
}
auto input = std::ifstream{path, std::ios::binary};
if (!input) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::NOT_FOUND, "failed to open practice JSON: " + path.string()));