aboutsummaryrefslogtreecommitdiffstats
path: root/nihil.config
diff options
context:
space:
mode:
authorLexi Winter <lexi@le-fay.org>2025-06-23 18:34:18 +0100
committerLexi Winter <lexi@le-fay.org>2025-06-23 18:34:18 +0100
commit32b4443ba2ec5c3f7c09221ab9b21911a3126ef9 (patch)
treecb6346997078626dc512e5e46e95796e375690ee /nihil.config
parentd5963532328ce5f1c9f266bf7e760b7d18a60c15 (diff)
downloadnihil-32b4443ba2ec5c3f7c09221ab9b21911a3126ef9.tar.gz
nihil-32b4443ba2ec5c3f7c09221ab9b21911a3126ef9.tar.bz2
add separate module implementation files
Diffstat (limited to 'nihil.config')
-rw-r--r--nihil.config/CMakeLists.txt10
-rw-r--r--nihil.config/option.cc67
-rw-r--r--nihil.config/option.ccm50
-rw-r--r--nihil.config/store.cc89
-rw-r--r--nihil.config/store.ccm68
-rw-r--r--nihil.config/string.cc57
-rw-r--r--nihil.config/string.ccm42
7 files changed, 246 insertions, 137 deletions
diff --git a/nihil.config/CMakeLists.txt b/nihil.config/CMakeLists.txt
index ed2bba3..6b1073d 100644
--- a/nihil.config/CMakeLists.txt
+++ b/nihil.config/CMakeLists.txt
@@ -2,9 +2,8 @@
add_library(nihil.config STATIC)
target_link_libraries(nihil.config PUBLIC nihil nihil.ucl)
-target_sources(nihil.config PUBLIC
- FILE_SET modules TYPE CXX_MODULES FILES
-
+target_sources(nihil.config
+ PUBLIC FILE_SET modules TYPE CXX_MODULES FILES
nihil.config.ccm
error.ccm
read.ccm
@@ -13,6 +12,11 @@ target_sources(nihil.config PUBLIC
option.ccm
string.ccm
+
+ PRIVATE
+ option.cc
+ store.cc
+ string.cc
)
if(NIHIL_TESTS)
diff --git a/nihil.config/option.cc b/nihil.config/option.cc
new file mode 100644
index 0000000..9bf77c9
--- /dev/null
+++ b/nihil.config/option.cc
@@ -0,0 +1,67 @@
+/*
+ * This source code is released into the public domain.
+ */
+
+module;
+
+#include <iostream>
+#include <string>
+
+module nihil.config;
+
+namespace nihil::config {
+
+auto option::name(this option const &self) noexcept
+-> std::string_view
+{
+ return self._name;
+}
+
+// Human-readable description of this option.
+auto option::description(this option const &self) noexcept
+-> std::string_view
+{
+ return self._description;
+}
+
+// If true, this option is set to its default value.
+auto option::is_default(this option const &self) noexcept
+-> bool
+{
+ return self._is_default;
+}
+
+// Get or set this option as a string.
+auto option::string(this option const &self)
+-> std::string
+{
+ return self.get_string();
+}
+
+auto option::string(this option &self, std::string_view value)
+-> void
+{
+ self.set_string(value);
+ self._is_default = false;
+}
+
+option::option(std::string_view name,
+ std::string_view description)
+ : _name(name)
+ , _description(description)
+{
+}
+
+auto option::is_default(bool b)
+-> void
+{
+ _is_default = b;
+}
+
+auto operator<<(std::ostream &strm, option const &opt)
+-> std::ostream &
+{
+ return strm << "<" << opt.name() << "=" << opt.string() << ">";
+}
+
+} // namespace nihil
diff --git a/nihil.config/option.ccm b/nihil.config/option.ccm
index 1be542e..c6a8329 100644
--- a/nihil.config/option.ccm
+++ b/nihil.config/option.ccm
@@ -4,11 +4,9 @@
module;
-#include <iostream>
+#include <iosfwd>
#include <string>
-#include <ucl++.h>
-
export module nihil.config:option;
import nihil.ucl;
@@ -23,34 +21,17 @@ namespace nihil::config {
export struct option
{
// Short name of this option.
- auto name(this option const &self) noexcept -> std::string_view
- {
- return self._name;
- }
+ auto name(this option const &self) noexcept -> std::string_view;
// Human-readable description of this option.
- auto description(this option const &self) noexcept -> std::string_view
- {
- return self._description;
- }
+ auto description(this option const &self) noexcept -> std::string_view;
// If true, this option is set to its default value.
- auto is_default(this option const &self) noexcept -> bool
- {
- return self._is_default;
- }
+ auto is_default(this option const &self) noexcept -> bool;
// Get or set this option as a string.
- auto string(this option const &self) -> std::string
- {
- return self.get_string();
- }
-
- void string(this option &self, std::string_view value)
- {
- self.set_string(value);
- self._is_default = false;
- }
+ auto string(this option const &self) -> std::string;
+ auto string(this option &self, std::string_view value) -> void;
/*
* Return this object as a UCL object. This is used when writing the
@@ -69,17 +50,9 @@ export struct option
auto operator=(option const &) -> option& = delete;
protected:
- option(std::string_view name,
- std::string_view description)
- : _name(name)
- , _description(description)
- {
- }
-
- auto is_default(bool b) -> void
- {
- _is_default = b;
- }
+ option(std::string_view name, std::string_view description);
+
+ auto is_default(bool b) -> void;
/*
* Get or set this option as a string.
@@ -96,9 +69,6 @@ private:
/*
* Make options printable. This is mostly useful for testing.
*/
-export auto operator<<(std::ostream &strm, option const &opt) -> std::ostream &
-{
- return strm << "<" << opt.name() << "=" << opt.string() << ">";
-}
+export auto operator<<(std::ostream &strm, option const &opt) -> std::ostream &;
} // namespace nihil
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
diff --git a/nihil.config/store.ccm b/nihil.config/store.ccm
index e0eebc0..77b44b5 100644
--- a/nihil.config/store.ccm
+++ b/nihil.config/store.ccm
@@ -9,12 +9,12 @@ module;
*/
#include <coroutine>
-#include <filesystem>
-#include <format>
+#include <string>
#include <map>
export module nihil.config:store;
+import nihil;
import :error;
import :option;
@@ -22,16 +22,8 @@ namespace nihil::config {
// Exception thrown on an attempt to fetch an undefined option.
export struct unknown_option final : error {
- unknown_option(std::string_view option_name)
- : error(std::format("unknown configuration variable '{}'",
- option_name))
- , _option_name(option_name)
- {}
-
- auto option_name(this unknown_option const &self) -> std::string_view
- {
- return self._option_name;
- }
+ unknown_option(std::string_view option_name);
+ auto option_name(this unknown_option const &self) -> std::string_view;
private:
std::string _option_name;
@@ -41,64 +33,27 @@ struct store final {
/*
* Get the global config store.
*/
- static auto get() -> store& {
- if (instance == nullptr)
- instance = new store;
-
- return *instance;
- }
-
+ static auto get() -> store &;
/*
* Register a new value with the config store.
*/
- auto 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 register_option(this store &self, option *object) -> void;
/*
* Remove a value from the config store.
*/
- auto 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 unregister_option(this store &self, option *object) -> void;
/*
* Fetch an existing value in the config store.
*/
- auto 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 fetch(this store const &self, std::string_view name) -> option &;
/*
* Fetch all values in the configuration store.
*/
- auto all(this auto &&self) -> nihil::generator<option const &>
- {
- for (auto &&it : self.options)
- co_yield *it.second;
- }
+ auto all(this store const &self) -> nihil::generator<option const &>;
// Not movable or copyable.
store(store const &) = delete;
@@ -120,9 +75,6 @@ private:
/*
* The public API.
*/
-export auto get_option(std::string_view option_name) -> option &
-{
- return store::get().fetch(option_name);
-}
+export auto get_option(std::string_view option_name) -> option &;
} // namespace nihil::config
diff --git a/nihil.config/string.cc b/nihil.config/string.cc
new file mode 100644
index 0000000..6b201ae
--- /dev/null
+++ b/nihil.config/string.cc
@@ -0,0 +1,57 @@
+/*
+ * This source code is released into the public domain.
+ */
+
+module;
+
+#include <format>
+#include <string>
+
+module nihil.config;
+
+import nihil.ucl;
+
+namespace nihil::config {
+
+string::string(
+ std::string &storage,
+ std::string_view name,
+ std::string_view description) noexcept
+ : option(name, description)
+ , _storage(storage)
+{
+ store::get().register_option(this);
+}
+
+string::~string()
+{
+ store::get().unregister_option(this);
+}
+
+auto string::get_string() const -> std::string
+{
+ return _storage;
+}
+
+auto string::set_string(std::string_view new_value) -> void
+{
+ _storage = new_value;
+}
+
+auto string::to_ucl() const -> ucl::object
+{
+ return ucl::string(_storage);
+}
+
+auto string::from_ucl(ucl::object const &uclobj) -> void
+{
+ try {
+ _storage = object_cast<ucl::string>(uclobj).value();
+ is_default(false);
+ } catch (ucl::type_mismatch const &exc) {
+ throw error(std::format("'{}': expected string, not {}",
+ name(), str(exc.actual_type())));
+ }
+}
+
+} // namespace nihil::config
diff --git a/nihil.config/string.ccm b/nihil.config/string.ccm
index 57770ae..ae5efb9 100644
--- a/nihil.config/string.ccm
+++ b/nihil.config/string.ccm
@@ -9,10 +9,8 @@ module;
export module nihil.config:string;
-import nihil;
import nihil.ucl;
import :option;
-import :store;
namespace nihil::config {
@@ -20,43 +18,15 @@ export struct string final : option
{
string(std::string &storage,
std::string_view name,
- std::string_view description) noexcept
- : option(name, description)
- , _storage(storage)
- {
- store::get().register_option(this);
- }
+ std::string_view description) noexcept;
- ~string()
- {
- store::get().unregister_option(this);
- }
+ ~string();
- auto get_string() const -> std::string override
- {
- return _storage;
- };
+ auto get_string() const -> std::string override;
+ auto set_string(std::string_view new_value) -> void override;
- auto set_string(std::string_view new_value) -> void override
- {
- _storage = new_value;
- }
-
- auto to_ucl() const -> ucl::object override
- {
- return ucl::string(_storage);
- }
-
- auto from_ucl(ucl::object const &uclobj) -> void override
- {
- try {
- _storage = object_cast<ucl::string>(uclobj).value();
- is_default(false);
- } catch (ucl::type_mismatch const &exc) {
- throw error(std::format("'{}': expected string, not {}",
- name(), str(exc.actual_type())));
- }
- }
+ auto to_ucl() const -> ucl::object override;
+ auto from_ucl(ucl::object const &uclobj) -> void override;
private:
std::string &_storage;