VoltMod
C++23 framework for CS2 server plugins
Loading...
Searching...
No Matches
Options.hpp
Go to the documentation of this file.
1#pragma once
2
6#include <concepts>
7#include <functional>
8#include <string>
9#include <string_view>
10#include <utility>
11
12namespace VoltMod
13{
14
15/**
16 * @brief Owns a plugin's settings and republishes them whole on every Load.
17 *
18 * @p TSettings is a plain aggregate whose member names are the JSON keys. A missing key keeps the
19 * member's initializer and unknown keys are ignored. To validate or derive values, name a
20 * @p TSnapshot and pass the function that builds it from the parsed settings. The snapshot is
21 * built before it is published, so a failed Load keeps the previous one. See docs/config.md.
22 */
23template <class TSettings, class TSnapshot = TSettings>
25{
26public:
27 /** @brief Validates the parsed settings and derives whatever Get() offers beside them. */
28 using Builder = std::function<TSnapshot(TSettings)>;
29
30 /** Publishes the parsed settings unchanged. */
32 requires std::same_as<TSettings, TSnapshot>
33 : _build([](TSettings parsed) { return parsed; })
34 {}
35
36 explicit Options(Builder build) : _build(std::move(build)) {}
37
38 /** @brief Load @p path (JSONC tolerated), build the snapshot, then publish it in one move.
39 *
40 * On failure the previously published snapshot stands, and the error names the offending
41 * key with its line and column. */
42 Status Load(std::string_view path)
43 {
44 _path = std::string(path);
45 auto parsed = Json::ReadFile<TSettings>(path);
46 if (!parsed)
47 {
48 return std::unexpected(parsed.error());
49 }
50
51 TSnapshot next = _build(std::move(*parsed));
52 _snapshot = std::move(next);
53 Log::Info("Loaded settings from {}", path);
54 return {};
55 }
56
57 /** Load the path the last @ref Load read, again. */
59 {
60 if (_path.empty())
61 {
62 return std::unexpected(Error::NotReady("no settings file was loaded yet"));
63 }
64 return Load(std::string(_path));
65 }
66
67 /** The effective settings. */
68 const TSnapshot& Get() const { return _snapshot; }
69
70private:
71 Builder _build;
72 std::string _path;
73 TSnapshot _snapshot{};
74};
75
76} // namespace VoltMod
static Result< T > ReadFile(std::string_view path)
Parse path (resolved via ResolvePath) into T.
Definition Json.hpp:46
Owns a plugin's settings and republishes them whole on every Load.
Definition Options.hpp:25
Status Reload()
Definition Options.hpp:58
std::function< TSnapshot(TSettings)> Builder
Validates the parsed settings and derives whatever Get() offers beside them.
Definition Options.hpp:28
const TSnapshot & Get() const
Definition Options.hpp:68
Status Load(std::string_view path)
Load path (JSONC tolerated), build the snapshot, then publish it in one move.
Definition Options.hpp:42
Options(Builder build)
Definition Options.hpp:36
void Info(std::format_string< Args... > fmt, Args &&... args)
Definition Log.hpp:79
static std::string ReadFile(const std::filesystem::path &path)
Definition Loader.cpp:56
std::expected< void, Error > Status
Definition Result.hpp:67
static Error NotReady(std::string detail)
Definition Result.hpp:50