190 lines
5.6 KiB
C++
190 lines
5.6 KiB
C++
|
|
#pragma once
|
|
|
|
#if !defined(RAID_PUBLIC_RAID_CONFIG_HPP_INCLUDED)
|
|
#define RAID_PUBLIC_RAID_CONFIG_HPP_INCLUDED 1
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
#include <mijin/async/coroutine.hpp>
|
|
#include <mijin/container/vector_map.hpp>
|
|
#include <mijin/memory/dynamic_pointer.hpp>
|
|
#include <mijin/types/result.hpp>
|
|
#include <mijin/virtual_filesystem/filesystem.hpp>
|
|
|
|
namespace raid
|
|
{
|
|
class ConfigValue;
|
|
|
|
class ConfigArray
|
|
{
|
|
public:
|
|
using iterator = std::vector<ConfigValue>::iterator;
|
|
using const_iterator = std::vector<ConfigValue>::const_iterator;
|
|
private:
|
|
std::vector<ConfigValue> mValues;
|
|
public:
|
|
ConfigArray() noexcept = default;
|
|
ConfigArray(const ConfigArray&) = default;
|
|
ConfigArray(ConfigArray&&) noexcept = default;
|
|
explicit ConfigArray(std::vector<ConfigValue> values) noexcept : mValues(std::move(values)) {}
|
|
|
|
ConfigArray& operator=(const ConfigArray&) = default;
|
|
ConfigArray& operator=(ConfigArray&&) noexcept = default;
|
|
|
|
const ConfigValue& operator[](std::size_t idx) const noexcept { return mValues[idx]; }
|
|
|
|
[[nodiscard]]
|
|
const std::vector<ConfigValue>& getValues() const noexcept { return mValues; }
|
|
|
|
[[nodiscard]]
|
|
std::size_t getSize() const noexcept { return mValues.size(); }
|
|
|
|
void append(ConfigValue value);
|
|
void setAt(std::size_t idx, ConfigValue value);
|
|
void removeAt(std::size_t idx, std::size_t count = 1);
|
|
|
|
[[nodiscard]]
|
|
bool isEmpty() const noexcept { return mValues.empty(); }
|
|
|
|
[[nodiscard]]
|
|
iterator begin() noexcept { return mValues.begin(); }
|
|
|
|
[[nodiscard]]
|
|
iterator end() noexcept { return mValues.end(); }
|
|
|
|
[[nodiscard]]
|
|
const_iterator begin() const noexcept { return mValues.begin(); }
|
|
|
|
[[nodiscard]]
|
|
const_iterator end() const noexcept { return mValues.end(); }
|
|
};
|
|
|
|
class ConfigSection
|
|
{
|
|
private:
|
|
mijin::VectorMap<std::string, ConfigValue> mValues;
|
|
public:
|
|
ConfigSection() noexcept = default;
|
|
ConfigSection(const ConfigSection&) = default;
|
|
ConfigSection(ConfigSection&&) noexcept = default;
|
|
explicit ConfigSection(mijin::VectorMap<std::string, ConfigValue> values) noexcept : mValues(std::move(values)) {}
|
|
|
|
ConfigSection& operator=(const ConfigSection&) = default;
|
|
ConfigSection& operator=(ConfigSection&&) noexcept = default;
|
|
|
|
const ConfigValue& operator[](std::string_view key) const noexcept;
|
|
|
|
[[nodiscard]]
|
|
ConfigValue& getOrAdd(std::string_view key);
|
|
|
|
void set(std::string_view key, ConfigValue value);
|
|
|
|
[[nodiscard]]
|
|
mijin::VectorMap<std::string, ConfigValue>& getValues() noexcept { return mValues; }
|
|
|
|
[[nodiscard]]
|
|
const mijin::VectorMap<std::string, ConfigValue>& getValues() const noexcept { return mValues; }
|
|
};
|
|
|
|
using config_int_t = std::int64_t;
|
|
class ConfigValue
|
|
{
|
|
private:
|
|
std::variant<std::nullptr_t, bool, config_int_t, double, std::string, ConfigArray, ConfigSection> mContent;
|
|
public:
|
|
ConfigValue() noexcept : mContent(nullptr) {}
|
|
ConfigValue(const ConfigValue&) = default;
|
|
ConfigValue(ConfigValue&&) noexcept = default;
|
|
ConfigValue(bool content) noexcept : mContent(content) {}
|
|
ConfigValue(config_int_t content) noexcept : mContent(content) {}
|
|
ConfigValue(double content) noexcept : mContent(content) {}
|
|
ConfigValue(std::string content) noexcept : mContent(std::move(content)) {}
|
|
ConfigValue(const char* content) noexcept : mContent(std::string(content)) {}
|
|
ConfigValue(ConfigArray content) noexcept : mContent(std::move(content)) {}
|
|
ConfigValue(ConfigSection content) noexcept : mContent(std::move(content)) {}
|
|
|
|
ConfigValue& operator=(const ConfigValue&) = default;
|
|
ConfigValue& operator=(ConfigValue&&) noexcept = default;
|
|
|
|
[[nodiscard]]
|
|
bool isUndefined() const noexcept { return std::holds_alternative<std::nullptr_t>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool isBool() const noexcept { return std::holds_alternative<bool>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool isInt() const noexcept { return std::holds_alternative<config_int_t>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool isDouble() const noexcept { return std::holds_alternative<double>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool isString() const noexcept { return std::holds_alternative<std::string>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool isArray() const noexcept { return std::holds_alternative<ConfigArray>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool isSection() const noexcept { return std::holds_alternative<ConfigSection>(mContent); }
|
|
|
|
[[nodiscard]]
|
|
bool asBool() const noexcept;
|
|
|
|
[[nodiscard]]
|
|
config_int_t asInt() const noexcept;
|
|
|
|
[[nodiscard]]
|
|
double asDouble() const noexcept;
|
|
|
|
[[nodiscard]]
|
|
const std::string& asString() const noexcept;
|
|
|
|
[[nodiscard]]
|
|
const ConfigArray& asArray() const noexcept;
|
|
|
|
[[nodiscard]]
|
|
ConfigSection& asMutableSection() noexcept;
|
|
|
|
[[nodiscard]]
|
|
const ConfigSection& asSection() const noexcept;
|
|
|
|
template<typename TFunc>
|
|
decltype(auto) visit(TFunc&& func) const noexcept
|
|
{
|
|
return std::visit(std::forward<TFunc>(func), mContent);
|
|
}
|
|
};
|
|
|
|
class FileConfig
|
|
{
|
|
private:
|
|
ConfigSection mRoot;
|
|
mijin::PathReference mPath;
|
|
bool mDirty = false;
|
|
public:
|
|
[[nodiscard]]
|
|
const ConfigSection& getRoot() const noexcept { return mRoot; }
|
|
|
|
[[nodiscard]]
|
|
const ConfigValue& getValue(std::string_view path) const noexcept;
|
|
|
|
void setValue(std::string_view path, ConfigValue value) noexcept;
|
|
|
|
[[nodiscard]]
|
|
mijin::Result<> init(mijin::PathReference path);
|
|
|
|
[[nodiscard]]
|
|
mijin::Result<> load();
|
|
|
|
[[nodiscard]]
|
|
mijin::Result<> save(bool force = false);
|
|
};
|
|
}
|
|
|
|
#endif // !defined(RAID_PUBLIC_RAID_CONFIG_HPP_INCLUDED)
|