aboutsummaryrefslogtreecommitdiffstats
path: root/nihil.config/store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'nihil.config/store.cc')
-rw-r--r--nihil.config/store.cc89
1 files changed, 89 insertions, 0 deletions
diff --git a/nihil.config/store.cc b/nihil.config/store.cc
new file mode 100644
index 0000000..2ec8ade
--- /dev/null
+++ b/nihil.config/store.cc
@@ -0,0 +1,89 @@
+/*
+ * This source code is released into the public domain.
+ */
+
+module;
+
+#include <coroutine>
+#include <filesystem>
+#include <format>
+#include <map>
+
+module nihil.config;
+
+import nihil;
+
+namespace nihil::config {
+
+unknown_option::unknown_option(std::string_view option_name)
+ : error(std::format("unknown configuration variable '{}'",
+ option_name))
+ , _option_name(option_name)
+{
+}
+
+auto unknown_option::option_name(this unknown_option const &self)
+-> std::string_view
+{
+ return self._option_name;
+}
+
+auto store::get()
+-> store&
+{
+ if (instance == nullptr)
+ instance = new store;
+
+ return *instance;
+}
+
+
+auto store::register_option(this store &self, option *object)
+-> void
+{
+ auto [it, okay] = self.options.insert(
+ std::pair{object->name(), object});
+
+ if (!okay)
+ throw error(std::format(
+ "INTERNAL ERROR: attempt to register "
+ "duplicate config value '{0}'",
+ object->name()));
+}
+
+auto store::unregister_option(this store &self, option *object)
+-> void
+{
+ auto it = self.options.find(object->name());
+ if (it == self.options.end())
+ throw error(std::format(
+ "INTERNAL ERROR: attempt to unregister "
+ "non-existent config value '{}'",
+ object->name()));
+
+ self.options.erase(it);
+}
+
+auto store::fetch(this store const &self, std::string_view name)
+-> option &
+{
+ if (auto it = self.options.find(name); it != self.options.end())
+ return *it->second;
+
+ throw unknown_option(name);
+}
+
+auto store::all(this store const &self)
+-> nihil::generator<option const &>
+{
+ for (auto &&it : self.options)
+ co_yield *it.second;
+}
+
+auto get_option(std::string_view option_name)
+-> option &
+{
+ return store::get().fetch(option_name);
+}
+
+} // namespace nihil::config