Mercurial > minori
changeset 305:91ac90a34003
core/time: remove Duration class, use regular functions instead
this class was pretty useless anyway
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 19 May 2024 15:56:20 -0400 |
parents | 2115488eb302 |
children | f4538a4c91ba |
files | include/core/time.h include/gui/dialog/information.h src/core/anime.cc src/core/time.cc src/gui/dialog/information.cc src/gui/pages/anime_list.cc src/gui/pages/search.cc src/gui/pages/statistics.cc src/gui/theme.cc src/gui/widgets/sidebar.cc src/services/anilist.cc |
diffstat | 11 files changed, 132 insertions(+), 150 deletions(-) [+] |
line wrap: on
line diff
--- a/include/core/time.h Mon May 13 17:02:35 2024 -0400 +++ b/include/core/time.h Sun May 19 15:56:20 2024 -0400 @@ -5,19 +5,17 @@ #include <string> namespace Time { -class Duration { -public: - Duration(int64_t l); - int64_t InSeconds(); - int64_t InMinutes(); - int64_t InHours(); - int64_t InDays(); - std::string AsRelativeString(); +/* this is in SECONDS */ +using Timestamp = uint64_t; -private: - int64_t length; +enum class Units { + Seconds, + Minutes }; +std::string GetSecondsAsRelativeString(Timestamp length); +std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds = 1.0); + int64_t GetSystemTime(); }; // namespace Time
--- a/include/gui/dialog/information.h Mon May 13 17:02:35 2024 -0400 +++ b/include/gui/dialog/information.h Sun May 19 15:56:20 2024 -0400 @@ -15,14 +15,14 @@ PAGE_MY_LIST }; - InformationDialog(Anime::Anime& anime, std::function<void()> accept = {}, enum Pages page = Pages::PAGE_MAIN_INFO, + InformationDialog(Anime::Anime* anime, std::function<void(Anime::Anime*)> accept = {}, enum Pages page = Pages::PAGE_MAIN_INFO, QWidget* parent = nullptr); protected: void showEvent(QShowEvent* event) override; private: - void SaveData(Anime::Anime& anime); + void SaveData(Anime::Anime* anime); unsigned int _progress; unsigned int _score; bool _rewatching;
--- a/src/core/anime.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/core/anime.cc Sun May 19 15:56:20 2024 -0400 @@ -13,6 +13,8 @@ #include <vector> #include <cassert> +#include <iostream> + namespace Anime { /* User list data */
--- a/src/core/time.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/core/time.cc Sun May 19 15:56:20 2024 -0400 @@ -9,29 +9,37 @@ namespace Time { -Duration::Duration(int64_t l) { - length = l; +static int64_t GetSecondsInMinutes(Timestamp length) { + return std::llround(static_cast<double>(length) / 60.0); } -std::string Duration::AsRelativeString() { +static int64_t GetSecondsInHours(Timestamp length) { + return std::llround(static_cast<double>(length) / 3600.0); +} + +static int64_t GetSecondsInDays(Timestamp length) { + return std::llround(static_cast<double>(length) / 86400.0); +} + +std::string GetSecondsAsRelativeString(Timestamp length) { std::string result; auto get = [](int64_t val, const std::string& s, const std::string& p) { return Strings::ToUtf8String(val) + " " + (val == 1 ? s : p); }; - if (InSeconds() < 60) - result = get(InSeconds(), "second", "seconds"); - else if (InMinutes() < 60) - result = get(InMinutes(), "minute", "minutes"); - else if (InHours() < 24) - result = get(InHours(), "hour", "hours"); - else if (InDays() < 28) - result = get(InDays(), "day", "days"); - else if (InDays() < 365) - result = get(InDays() / 30, "month", "months"); + if (length < 60) + result = get(length, "second", "seconds"); + else if (GetSecondsInMinutes(length) < 60) + result = get(GetSecondsInMinutes(length), "minute", "minutes"); + else if (GetSecondsInHours(length) < 24) + result = get(GetSecondsInHours(length), "hour", "hours"); + else if (GetSecondsInDays(length) < 28) + result = get(GetSecondsInDays(length), "day", "days"); + else if (GetSecondsInDays(length) < 365) + result = get(GetSecondsInDays(length) / 30, "month", "months"); else - result = get(InDays() / 365, "year", "years"); + result = get(GetSecondsInDays(length) / 365, "year", "years"); if (length < 0) result = "In " + result; @@ -41,26 +49,51 @@ return result; } -int64_t Duration::InSeconds() { - return length; -} +std::string GetSecondsAsAbsoluteString(Units unit_cutoff, Timestamp amount, double unit_in_seconds) { + /* avoid calculating this twice */ + const double years_conv = (31556952.0 / unit_in_seconds); + const double months_conv = (2629746.0 / unit_in_seconds); + const double days_conv = (86400.0 / unit_in_seconds); + const double hours_conv = (3600.0 / unit_in_seconds); + const double minutes_conv = (60.0 / unit_in_seconds); + const double seconds_conv = (1.0 / unit_in_seconds); + + const int years = amount / years_conv; + const int months = std::fmod(amount, years_conv) / months_conv; + const int days = std::fmod(amount, months_conv) / days_conv; + const int hours = std::fmod(amount, days_conv) / hours_conv; + const int minutes = std::fmod(amount, hours_conv) / minutes_conv; + const int seconds = std::fmod(amount, minutes_conv) / seconds_conv; -int64_t Duration::InMinutes() { - return std::llround(static_cast<double>(length) / 60.0); -} + const auto add_time_segment = [](std::ostringstream& str, int64_t amount, const std::string_view& singular, + const std::string_view& plural, bool always = false) { + if (amount > 0 || always) + str << amount << ((amount == 1) ? singular : plural); + }; + + /* for now, this function is very en_US specific */ -int64_t Duration::InHours() { - return std::llround(static_cast<double>(length) / 3600.0); -} + std::ostringstream string; + add_time_segment(string, years, " year ", " years "); + add_time_segment(string, months, " month ", " months "); + add_time_segment(string, days, " day ", " days "); + add_time_segment(string, hours, " hour ", " hours "); -int64_t Duration::InDays() { - return std::llround(static_cast<double>(length) / 86400.0); + if (unit_cutoff == Units::Minutes) { + add_time_segment(string, minutes, " minute", " minutes", true); + return string.str(); + } else { + add_time_segment(string, minutes, " minute ", " minutes "); + } + + add_time_segment(string, seconds, " second", " seconds", true); + return string.str(); } int64_t GetSystemTime() { static_assert(sizeof(int64_t) >= sizeof(time_t)); time_t t = std::time(nullptr); - return *reinterpret_cast<int64_t*>(&t); + return reinterpret_cast<int64_t>(t); } } // namespace Time
--- a/src/gui/dialog/information.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/gui/dialog/information.cc Sun May 19 15:56:20 2024 -0400 @@ -25,28 +25,29 @@ #include <QVBoxLayout> #include <functional> +#include <iostream> #ifdef WIN32 # include "sys/win32/dark_theme.h" #endif /* TODO: Taiga disables rendering of the tab widget entirely when the anime is not part of a list, which sucks. Think of a better way to implement this later. */ -void InformationDialog::SaveData(Anime::Anime& anime) { - if (!anime.IsInUserList()) +void InformationDialog::SaveData(Anime::Anime* anime) { + if (!anime->IsInUserList()) return; - anime.SetUserProgress(_progress); - anime.SetUserScore(_score); - anime.SetUserIsRewatching(_rewatching); - anime.SetUserStatus(_status); - anime.SetUserNotes(_notes); - anime.SetUserDateStarted(_started); - anime.SetUserDateCompleted(_completed); + anime->SetUserProgress(_progress); + anime->SetUserScore(_score); + anime->SetUserIsRewatching(_rewatching); + anime->SetUserStatus(_status); + anime->SetUserNotes(_notes); + anime->SetUserDateStarted(_started); + anime->SetUserDateCompleted(_completed); } -InformationDialog::InformationDialog(Anime::Anime& anime, std::function<void()> accept, enum Pages page, +InformationDialog::InformationDialog(Anime::Anime* anime, std::function<void(Anime::Anime*)> accept, enum Pages page, QWidget* parent) - : QDialog(parent) { + : QDialog(parent) { /* ack. lots of brackets here, but MUCH, MUCH MUCH better than what it used to be */ setFixedSize(842, 613); setWindowTitle(tr("Anime Information")); @@ -71,7 +72,7 @@ QVBoxLayout* sidebar_layout = new QVBoxLayout(sidebar); { /* Poster */ - Poster* poster = new Poster(anime, sidebar); + Poster* poster = new Poster(*anime, sidebar); sidebar_layout->addWidget(poster); } sidebar_layout->setContentsMargins(0, 0, 0, 0); @@ -89,7 +90,7 @@ { /* Anime title */ TextWidgets::Title* anime_title = - new TextWidgets::Title(Strings::ToQString(anime.GetUserPreferredTitle()), main_widget); + new TextWidgets::Title(Strings::ToQString(anime->GetUserPreferredTitle()), main_widget); main_layout->addWidget(anime_title); } @@ -100,11 +101,11 @@ { /* Main information */ - AnimeInfoWidget* main_information_widget = new AnimeInfoWidget(anime, tabbed_widget); + AnimeInfoWidget* main_information_widget = new AnimeInfoWidget(*anime, tabbed_widget); tabbed_widget->addTab(main_information_widget, tr("Main information")); } - if (anime.IsInUserList()) { + if (anime->IsInUserList()) { /* My list and settings */ QWidget* settings_widget = new QWidget(tabbed_widget); settings_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); @@ -143,9 +144,9 @@ QSpinBox* spin_box = new QSpinBox(section); connect(spin_box, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int i) { _progress = i; }); - spin_box->setRange(0, anime.GetEpisodes()); + spin_box->setRange(0, anime->GetEpisodes()); spin_box->setSingleStep(1); - spin_box->setValue(_progress = anime.GetUserProgress()); + spin_box->setValue(_progress = anime->GetUserProgress()); spin_box->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(spin_box, 1, 0); } @@ -155,8 +156,8 @@ QCheckBox* checkbox = new QCheckBox(tr("Rewatching")); connect(checkbox, QOverload<int>::of(&QCheckBox::stateChanged), this, [this](int state) { _rewatching = (state == Qt::Checked); }); - checkbox->setCheckState((_rewatching = anime.GetUserIsRewatching()) ? Qt::Checked - : Qt::Unchecked); + checkbox->setCheckState((_rewatching = anime->GetUserIsRewatching()) ? Qt::Checked + : Qt::Unchecked); checkbox->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(checkbox, 1, 1); } @@ -170,9 +171,13 @@ QComboBox* combo_box = new QComboBox(section); - for (unsigned int i = 0; i < Anime::ListStatuses.size(); i++) + _status = anime->GetUserStatus(); + for (unsigned int i = 0; i < Anime::ListStatuses.size(); i++) { combo_box->addItem(Strings::ToQString(Translate::ToLocalString(Anime::ListStatuses[i])), static_cast<int>(Anime::ListStatuses[i])); + if (Anime::ListStatuses[i] == _status) + combo_box->setCurrentIndex(i); + } connect(combo_box, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this, combo_box](int) { @@ -180,7 +185,6 @@ }); /* this should NEVER, EVER, be NOT_IN_LIST */ - combo_box->setCurrentIndex(static_cast<int>(_status = anime.GetUserStatus()) - 1); combo_box->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(combo_box, 1, 0); } @@ -194,7 +198,7 @@ [this](int i) { _score = i; }); spin_box->setRange(0, 100); spin_box->setSingleStep(5); - spin_box->setValue(_score = anime.GetUserScore()); + spin_box->setValue(_score = anime->GetUserScore()); spin_box->setFixedWidth(LAYOUT_ITEM_WIDTH); layout->addWidget(spin_box, 1, 1); } @@ -209,7 +213,7 @@ /* this sucks but I don't really want to implement anything smarter :) */ _notes = Strings::ToUtf8String(text); }); - line_edit->setText(Strings::ToQString(_notes = anime.GetUserNotes())); + line_edit->setText(Strings::ToQString(_notes = anime->GetUserNotes())); line_edit->setPlaceholderText(tr("Enter your notes about this anime")); layout->addWidget(line_edit, 1, 0); }); @@ -223,10 +227,10 @@ connect(date, &OptionalDate::DataChanged, this, [this](bool enabled, Date date) { _started = enabled ? date : Date(); }); date->setFixedWidth(LAYOUT_ITEM_WIDTH); - _started = anime.GetUserDateStarted(); + _started = anime->GetUserDateStarted(); if (!_started.IsValid()) { date->SetEnabled(false); - _started = anime.GetAirDate(); + _started = anime->GetAirDate(); } date->SetDate(_started); layout->addWidget(date, 1, 0); @@ -240,10 +244,10 @@ connect(date, &OptionalDate::DataChanged, this, [this](bool enabled, Date date) { _completed = enabled ? date : Date(); }); date->setFixedWidth(LAYOUT_ITEM_WIDTH); - _completed = anime.GetUserDateCompleted(); + _completed = anime->GetUserDateCompleted(); if (!_completed.IsValid()) { date->SetEnabled(false); - _completed = anime.GetAirDate(); + _completed = anime->GetAirDate(); } date->SetDate(_completed); layout->addWidget(date, 1, 1); @@ -301,9 +305,9 @@ { /* Dialog box buttons */ QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); - connect(button_box, &QDialogButtonBox::accepted, this, [this, accept, &anime] { + connect(button_box, &QDialogButtonBox::accepted, this, [this, accept, anime] { SaveData(anime); - accept(); + accept(anime); QDialog::accept(); }); connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
--- a/src/gui/pages/anime_list.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/gui/pages/anime_list.cc Sun May 19 15:56:20 2024 -0400 @@ -140,7 +140,7 @@ case AL_SEASON: { std::optional<unsigned int> year = list[index.row()].GetAirDate().GetYear(); if (!year) - return "Unknown Unknown"; + return tr("Unknown Unknown"); return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " + Strings::ToUtf8String(year.value())); } @@ -150,8 +150,7 @@ case AL_UPDATED: { if (list[index.row()].GetUserTimeUpdated() == 0) return QString("-"); - Time::Duration duration(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated()); - return Strings::ToQString(duration.AsRelativeString()); + return Strings::ToQString(Time::GetSecondsAsRelativeString(Time::GetSystemTime() - list[index.row()].GetUserTimeUpdated())); } case AL_NOTES: return Strings::ToQString(list[index.row()].GetUserNotes()); default: return ""; @@ -203,11 +202,9 @@ list.clear(); - for (const auto& a : Anime::db.items) { - if (a.second.IsInUserList() && a.second.GetUserStatus() == status) { + for (const auto& a : Anime::db.items) + if (a.second.IsInUserList() && a.second.GetUserStatus() == status) list.push_back(a.second); - } - } endResetModel(); } @@ -315,7 +312,7 @@ menu->addAction(tr("Information"), [this, animes] { for (auto& anime : animes) { InformationDialog* dialog = new InformationDialog( - *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); + anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); dialog->show(); dialog->raise(); @@ -327,7 +324,7 @@ menu->addAction(tr("Edit"), [this, animes] { for (auto& anime : animes) { InformationDialog* dialog = new InformationDialog( - *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this); + anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MY_LIST, this); dialog->show(); dialog->raise(); @@ -358,7 +355,7 @@ Anime::Anime* anime = source_model->GetAnimeFromIndex(index); InformationDialog* dialog = new InformationDialog( - *anime, [this, anime] { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); + anime, [this](Anime::Anime* anime) { UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); dialog->show(); dialog->raise();
--- a/src/gui/pages/search.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/gui/pages/search.cc Sun May 19 15:56:20 2024 -0400 @@ -196,8 +196,8 @@ menu->addAction(tr("Information"), [this, animes] { for (auto& anime : animes) { InformationDialog* dialog = new InformationDialog( - *anime, - [this, anime] { + anime, + [this](Anime::Anime* anime) { // UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this); @@ -235,8 +235,8 @@ Anime::Anime* anime = model->GetAnimeFromIndex(index); InformationDialog* dialog = new InformationDialog( - *anime, - [this, anime] { + anime, + [this](Anime::Anime* anime) { // UpdateAnime(anime->GetId()); }, InformationDialog::PAGE_MAIN_INFO, this);
--- a/src/gui/pages/statistics.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/gui/pages/statistics.cc Sun May 19 15:56:20 2024 -0400 @@ -2,6 +2,7 @@ #include "core/anime_db.h" #include "core/session.h" #include "core/strings.h" +#include "core/time.h" #include "gui/pages/anime_list.h" #include "gui/widgets/graph.h" #include "gui/widgets/text.h" @@ -16,11 +17,6 @@ #include <cmath> #include <sstream> -enum class TimeUnits { - SECONDS, - MINUTES -}; - StatisticsPage::StatisticsPage(QWidget* parent) : QFrame(parent) { setBackgroundRole(QPalette::Base); @@ -79,54 +75,6 @@ UpdateStatistics(); } -/* [in] enum TimeUnits unit: - * which unit to stop on - * [in] int amount: - * amount of units to parse - * [in, defaults to 1.0] double unit_in_seconds: - * equivalent of one of 'amount' in seconds, e.g. minutes would be 60.0 - */ -static std::string TimeToDateString(TimeUnits unit, int amount, double unit_in_seconds = 1.0) { - /* avoid calculating this twice */ - const double years_conv = (31556952.0 / unit_in_seconds); - const double months_conv = (2629746.0 / unit_in_seconds); - const double days_conv = (86400.0 / unit_in_seconds); - const double hours_conv = (3600.0 / unit_in_seconds); - const double minutes_conv = (60.0 / unit_in_seconds); - const double seconds_conv = (1.0 / unit_in_seconds); - - const int years = amount / years_conv; - const int months = std::fmod(amount, years_conv) / months_conv; - const int days = std::fmod(amount, months_conv) / days_conv; - const int hours = std::fmod(amount, days_conv) / hours_conv; - const int minutes = std::fmod(amount, hours_conv) / minutes_conv; - const int seconds = std::fmod(amount, minutes_conv) / seconds_conv; - - const auto add_time_segment = [](std::ostringstream& str, int amount, const std::string_view& singular, - const std::string_view& plural, bool always = false) { - if (amount > 0 || always) - str << amount << ((amount == 1) ? singular : plural); - }; - - /* for now, this function is very en_US specific */ - - std::ostringstream string; - add_time_segment(string, years, " year ", " years "); - add_time_segment(string, months, " month ", " months "); - add_time_segment(string, days, " day ", " days "); - add_time_segment(string, hours, " hour ", " hours "); - - if (unit == TimeUnits::MINUTES) { - add_time_segment(string, minutes, " minute", " minutes", true); - return string.str(); - } else { - add_time_segment(string, minutes, " minute ", " minutes "); - } - - add_time_segment(string, seconds, " second", " seconds", true); - return string.str(); -} - inline int GetTotalWithScore(const int score) { int count = 0; for (const auto& item : Anime::db.items) @@ -141,8 +89,8 @@ QTextStream ts(&string); ts << Anime::db.GetTotalAnimeAmount() << '\n'; ts << Anime::db.GetTotalEpisodeAmount() << '\n'; - ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalWatchedAmount(), 60.0)) << '\n'; - ts << Strings::ToQString(TimeToDateString(TimeUnits::MINUTES, Anime::db.GetTotalPlannedAmount(), 60.0)) << '\n'; + ts << Strings::ToQString(Time::GetSecondsAsAbsoluteString(Time::Units::Minutes, Anime::db.GetTotalWatchedAmount(), 60.0)) << '\n'; + ts << Strings::ToQString(Time::GetSecondsAsAbsoluteString(Time::Units::Minutes, Anime::db.GetTotalPlannedAmount(), 60.0)) << '\n'; ts << Anime::db.GetAverageScore() << '\n'; ts << Anime::db.GetScoreDeviation(); _anime_list->GetData()->setText(string); @@ -152,7 +100,7 @@ _score_distribution_graph->AddItem(i, GetTotalWithScore(i)); string = ""; - ts << Strings::ToQString(TimeToDateString(TimeUnits::SECONDS, session.uptime() / 1000)) << '\n'; + ts << Strings::ToQString(Time::GetSecondsAsAbsoluteString(Time::Units::Seconds, session.uptime() / 1000)) << '\n'; ts << session.GetRequests(); /* Application */ // UiUtils::SetPlainTextEditData(application_data, QString::number(session.uptime() / 1000));
--- a/src/gui/theme.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/gui/theme.cc Sun May 19 15:56:20 2024 -0400 @@ -93,7 +93,8 @@ const QColor black(25, 25, 25); const QColor blue(42, 130, 218); - QPalette pal(QApplication::style()->standardPalette()); + QPalette pal; + pal.setColor(QPalette::Window, darkGray); pal.setColor(QPalette::WindowText, Qt::white); pal.setColor(QPalette::Base, black); @@ -112,6 +113,7 @@ pal.setColor(QPalette::Disabled, QPalette::WindowText, gray); pal.setColor(QPalette::Disabled, QPalette::Text, gray); pal.setColor(QPalette::Disabled, QPalette::Light, darkGray); + qApp->setPalette(pal); #ifdef WIN32 @@ -127,7 +129,7 @@ break; } default: - /* this sucks. */ + /* this sucks */ QPalette pal(QApplication::style()->standardPalette()); #ifdef WIN32 /* fuck you Qt 6 */ pal.setColor(QPalette::Window, QColor(0xF0, 0xF0, 0xF0));
--- a/src/gui/widgets/sidebar.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/gui/widgets/sidebar.cc Sun May 19 15:56:20 2024 -0400 @@ -11,7 +11,7 @@ setSelectionMode(QAbstractItemView::SingleSelection); setSelectionBehavior(QAbstractItemView::SelectItems); setMouseTracking(true); - /* FIXME: is there an easy way to do this with palettes? */ + setStyleSheet("QListWidget::item:disabled { background: transparent }"); SetBackgroundTransparent(true);
--- a/src/services/anilist.cc Mon May 13 17:02:35 2024 -0400 +++ b/src/services/anilist.cc Sun May 19 15:56:20 2024 -0400 @@ -136,17 +136,15 @@ } static void ParseTitle(const nlohmann::json& json, Anime::Anime& anime) { - nlohmann::json::json_pointer g = "/native"_json_pointer; - if (json.contains(g) && json[g].is_string()) - anime.SetTitle(Anime::TitleLanguage::Native, json[g]); + static const std::unordered_map<Anime::TitleLanguage, nlohmann::json::json_pointer> map = { + {Anime::TitleLanguage::Native, "/native"_json_pointer}, + {Anime::TitleLanguage::English, "/english"_json_pointer}, + {Anime::TitleLanguage::Romaji, "/romaji"_json_pointer}, + }; - g = "/english"_json_pointer; - if (json.contains(g) && json[g].is_string()) - anime.SetTitle(Anime::TitleLanguage::English, json[g]); - - g = "/romaji"_json_pointer; - if (json.contains(g) && json[g].is_string()) - anime.SetTitle(Anime::TitleLanguage::Romaji, json[g]); + for (const auto& [language, ptr] : map) + if (json.contains(ptr) && json[ptr].is_string()) + anime.SetTitle(language, json[ptr]); } static int ParseMediaJson(const nlohmann::json& json) {