Implement ApiNap::market_list()

This commit is contained in:
King_DuckZ 2020-09-04 00:46:21 +01:00
parent 1cb40fd5ba
commit 571a92aa2e
3 changed files with 78 additions and 10 deletions

View file

@ -21,6 +21,9 @@
#include "duckhandy/int_conv.hpp"
#include <optional>
namespace sjd = simdjson::dom;
namespace sj = simdjson;
namespace oro {
namespace {
@ -50,14 +53,21 @@ void fill_base_json (const simdjson::dom::element& doc, BaseJsonReply& out) {
out.version = static_cast<int>(doc["version"].get_int64());
}
template <typename R, typename T=R>
std::optional<R> get_optional (const simdjson::dom::element& elem, const char* name) {
template <typename R, typename T>
std::optional<R> get_optional (const sj::simdjson_result<sjd::element>& elem) {
typedef std::optional<R> RetType;
T retval;
simdjson::error_code error = elem[name].get(retval);
if (not error)
return {static_cast<R>(retval)};
else
return {};
const simdjson::error_code error = elem.get(retval);
return (not error ? RetType{static_cast<R>(retval)} : RetType{});
}
template <typename R, typename T>
R get_or_default (const sj::simdjson_result<sjd::element>& elem, R def) {
T retval;
const simdjson::error_code error = elem.get(retval);
return (not error ? static_cast<R>(retval) : def);
}
}
} //unnamed namespace
@ -111,9 +121,9 @@ std::pair<Header, Items> ApiNap::items_list() {
new_entry.unique_name = item["unique_name"];
new_entry.name = item["name"];
new_entry.type = item["type"].get_string();
new_entry.subtype = get_optional<ItemSubtypeWrapper, std::string_view>(item, "subtype");
new_entry.subtype = get_optional<ItemSubtypeWrapper, std::string_view>(item["subtype"]);
new_entry.npc_price = static_cast<unsigned int>(item["npc_price"].get_uint64());
new_entry.slots = get_optional<unsigned int, uint64_t>(item, "slots");
new_entry.slots = get_optional<unsigned int, uint64_t>(item["slots"]);
out.items.push_back(std::move(new_entry));
}
}
@ -137,6 +147,53 @@ std::pair<Header, Icons> ApiNap::items_icons() {
}
std::pair<Header, Shops> ApiNap::market_list() {
return fetch_and_parse<Shops>(
g_endpoint_market_list,
[](const simdjson::dom::element& doc, Shops& out) {
auto shops = doc["shops"].get_array();
out.shops.reserve(shops.size());
for (auto shop : shops) {
Shop new_shop;
new_shop.title = shop["title"];
new_shop.owner = shop["owner"];
new_shop.creation_date = std::string(shop["creation_date"]);
new_shop.type = shop["type"].get_string();
{
auto loc = shop["location"];
new_shop.location.map = loc["map"];
new_shop.location.x = static_cast<int>(loc["x"].get_int64());
new_shop.location.y = static_cast<int>(loc["y"].get_int64());
}
{
auto items = shop["items"].get_array();
new_shop.items.reserve(items.size());
for (auto item : items) {
ShopItem new_item;
new_item.item_id = static_cast<unsigned int>(item["item_id"].get_uint64());
new_item.amount = static_cast<unsigned int>(item["amount"].get_uint64());
new_item.price = static_cast<unsigned int>(item["price"].get_uint64());
new_item.refine = get_or_default<unsigned int, uint64_t>(item["refine"], 0);
new_item.star_crumbs = get_or_default<unsigned int, uint64_t>(item["star_crumbs"], 0);
new_item.element = get_optional<std::string, std::string_view>(item["element"]);
new_item.creator = get_optional<unsigned int, uint64_t>(item["creator"]);
new_item.beloved = get_optional<bool, bool>(item["beloved"]);
auto item_cards = item["cards"];
if (item_cards.is_array()) {
auto cards = item_cards.get_array();
new_item.cards.reserve(cards.size());
for (uint64_t card : cards) {
new_item.cards.push_back(static_cast<unsigned int>(card));
}
}
new_shop.items.push_back(std::move(new_item));
}
}
out.shops.push_back(std::move(new_shop));
}
}
);
}
std::pair<Header, Creators> ApiNap::fame_list() {

View file

@ -28,6 +28,10 @@ ShopTypeWrapper::ShopTypeWrapper (const std::string& str) {
*this = str;
}
ShopTypeWrapper::ShopTypeWrapper (std::string_view str) {
*this = str;
}
ShopTypeWrapper& ShopTypeWrapper::operator= (int val) {
if (static_cast<int>(ShopType::Vending) == val)
value = ShopType::Vending;
@ -39,12 +43,16 @@ ShopTypeWrapper& ShopTypeWrapper::operator= (int val) {
}
ShopTypeWrapper& ShopTypeWrapper::operator= (const std::string& str) {
return this->operator=(std::string_view(str));
}
ShopTypeWrapper& ShopTypeWrapper::operator= (std::string_view str) {
if ("V" == str)
value = ShopType::Vending;
else if ("B" == str)
value = ShopType::Buying;
else
throw std::runtime_error("Unknown shop type '" + str + "'");
throw std::runtime_error("Unknown shop type '" + std::string(str) + "'");
return *this;
}

View file

@ -20,6 +20,7 @@
#include "datatypes.hpp"
#include <vector>
#include <string>
#include <string_view>
#include <optional>
namespace oro {
@ -33,8 +34,10 @@ namespace oro {
ShopTypeWrapper() = default;
ShopTypeWrapper (int val);
ShopTypeWrapper (const std::string& str);
ShopTypeWrapper (std::string_view str);
ShopTypeWrapper& operator= (int val);
ShopTypeWrapper& operator= (const std::string& str);
ShopTypeWrapper& operator= (std::string_view str);
operator ShopType() const {return value;}
ShopType value {ShopType::Unknown};
};