#pragma once #include #include #include #include #include namespace json { using namespace winrt::Windows::Data::Json; inline std::optional from_file(std::wstring_view file_name) { try { std::ifstream file(file_name.data(), std::ios::binary); if (file.is_open()) { using isbi = std::istreambuf_iterator; std::string obj_str{ isbi{ file }, isbi{} }; return JsonValue::Parse(winrt::to_hstring(obj_str)).GetObjectW(); } return std::nullopt; } catch (...) { return std::nullopt; } } inline void to_file(std::wstring_view file_name, const JsonObject& obj) { std::wstring obj_str{ obj.Stringify().c_str() }; std::ofstream{ file_name.data(), std::ios::binary } << winrt::to_string(obj_str); } inline bool has( const json::JsonObject& o, std::wstring_view name, const json::JsonValueType type = JsonValueType::Object) { return o.HasKey(name) && o.GetNamedValue(name).ValueType() == type; } template inline std::enable_if_t, JsonValue> value(const T arithmetic) { return json::JsonValue::CreateNumberValue(arithmetic); } template inline std::enable_if_t, JsonValue> value(T s) { return json::JsonValue::CreateStringValue(s); } inline JsonValue value(const bool boolean) { return json::JsonValue::CreateBooleanValue(boolean); } inline JsonValue value(JsonObject value) { return value.as(); } inline JsonValue value(JsonValue value) { return value; // identity function overload for convenience } template> requires std::constructible_from, D> void get(const json::JsonObject& o, const wchar_t* name, T& destination, D default_value = std::nullopt) { try { if constexpr (std::is_same_v) { destination = o.GetNamedBoolean(name); } else if constexpr (std::is_arithmetic_v) { destination = static_cast(o.GetNamedNumber(name)); } else if constexpr (std::is_same_v) { destination = o.GetNamedString(name); } else if constexpr (std::is_same_v) { destination = o.GetNamedObject(name); } else { static_assert(std::bool_constant>::value, "Unsupported type"); } } catch (...) { std::optional maybe_default{ std::move(default_value) }; if (maybe_default.has_value()) destination = std::move(*maybe_default); } } }