mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
150 lines
4.7 KiB
C++
150 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include <glm/detail/qualifier.hpp>
|
|
#include <glm/detail/type_vec1.hpp>
|
|
#include <nlohmann/json.hpp>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "WallpaperEngine/Data/Builders/UserSettingBuilder.h"
|
|
#include "WallpaperEngine/Data/Builders/VectorBuilder.h"
|
|
#include "WallpaperEngine/Data/Model/Types.h"
|
|
#include "WallpaperEngine/Data/Utils/SFINAE.h"
|
|
#include "WallpaperEngine/Logging/Log.h"
|
|
|
|
namespace WallpaperEngine::Data::JSON {
|
|
using namespace WallpaperEngine::Data::Builders;
|
|
using namespace WallpaperEngine::Data::Model;
|
|
using namespace WallpaperEngine::Data::Utils::SFINAE;
|
|
|
|
class JsonExtensions;
|
|
|
|
using JSON = nlohmann::basic_json<
|
|
std::map,
|
|
std::vector,
|
|
std::string,
|
|
bool,
|
|
std::int64_t,
|
|
std::uint64_t,
|
|
double,
|
|
std::allocator,
|
|
nlohmann::adl_serializer,
|
|
std::vector<std::uint8_t>,
|
|
JsonExtensions
|
|
>;
|
|
|
|
/**
|
|
* Small extensions class that is used as base class of nlohmann's implementation.
|
|
*
|
|
* Provides shorthand methods to reduce the amount of handling required for specific situations
|
|
* (mainly throwing readable exceptions when a value is missing, optional/default values, user settings...)
|
|
*/
|
|
class JsonExtensions {
|
|
public:
|
|
using base_type = JSON;
|
|
|
|
template <typename T, typename std::enable_if_t<is_glm_vec<T>::value, int> = 0>
|
|
[[nodiscard]] T get () const {
|
|
constexpr int length = GlmVecTraits<T>::length;
|
|
constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
|
|
|
|
// call the specialized version of the function
|
|
return get <length, typename GlmVecTraits<T>::type, qualifier> ();
|
|
}
|
|
template <int length, typename type, glm::qualifier qualifier>
|
|
[[nodiscard]] glm::vec <length, type, qualifier> get () const {
|
|
return VectorBuilder::parse <length, type, qualifier> (this->base ().get <std::string> ());
|
|
}
|
|
[[nodiscard]] base_type require (const std::string& key, const std::string& message) const {
|
|
auto base = this->base ();
|
|
auto it = base.find (key);
|
|
|
|
if (it == base.end ()) {
|
|
sLog.exception (message);
|
|
}
|
|
|
|
return *it;
|
|
}
|
|
template <typename T>
|
|
[[nodiscard]] T require (const std::string& key, const std::string& message) const {
|
|
auto base = this->base ();
|
|
auto it = base.find (key);
|
|
|
|
if (it == base.end ()) {
|
|
sLog.exception (message);
|
|
}
|
|
|
|
return (*it);
|
|
}
|
|
[[nodiscard]] std::optional <base_type> optional (const std::string& key) const noexcept {
|
|
auto base = this->base ();
|
|
auto it = base.find (key);
|
|
auto result = std::optional<base_type> {};
|
|
|
|
if (it != base.end ()) {
|
|
result.emplace (*it);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
[[nodiscard]] std::optional <T> optional (const std::string& key) const noexcept {
|
|
auto base = this->base ();
|
|
auto it = base.find (key);
|
|
|
|
if (it == base.end ()) {
|
|
return std::nullopt;
|
|
}
|
|
|
|
return *it;
|
|
}
|
|
template <typename T>
|
|
[[nodiscard]] T optional (const std::string& key, T defaultValue) const noexcept {
|
|
auto base = this->base ();
|
|
auto it = base.find (key);
|
|
|
|
if (it == base.end ()) {
|
|
return defaultValue;
|
|
}
|
|
|
|
return (*it);
|
|
}
|
|
[[nodiscard]] UserSettingUniquePtr user (const std::string& key, const Properties& properties) const;
|
|
template <typename T>
|
|
[[nodiscard]] UserSettingUniquePtr user (const std::string& key, const Properties& properties, T defaultValue) const {
|
|
const auto value = this->optional (key);
|
|
|
|
if (!value.has_value ()) {
|
|
return UserSettingBuilder::fromValue <T> (defaultValue);
|
|
}
|
|
|
|
// performs a second lookup, but handles the actual call to UserSettingParser outside of this header
|
|
// this resolving the include loop
|
|
return this->user (key, properties);
|
|
}
|
|
|
|
template <int length, typename type, glm::qualifier qualifier>
|
|
operator glm::vec <length, type, qualifier> () const {
|
|
return get <length, type, qualifier> ();
|
|
}
|
|
template <typename T, typename std::enable_if_t<is_glm_vec<T>::value> = 0>
|
|
operator T () const {
|
|
constexpr int length = GlmVecTraits<T>::length;
|
|
constexpr glm::qualifier qualifier = GlmVecTraits<T>::qualifier;
|
|
|
|
// call the specialized version of the function
|
|
return operator glm::vec <length, typename GlmVecTraits<T>::type, qualifier> ();
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* @return The base json object to be used by the extension methods
|
|
*/
|
|
[[nodiscard]] const base_type& base () const {
|
|
return *static_cast<const base_type*> (this);
|
|
}
|
|
};
|
|
|
|
} // namespace WallpaperEngine::Data::JSON
|