diff --git a/src/libutil/configuration.cc b/src/libutil/configuration.cc index 7a0ed22ea..ee24bb4e5 100644 --- a/src/libutil/configuration.cc +++ b/src/libutil/configuration.cc @@ -433,6 +433,42 @@ std::string BaseSetting::to_string() const [](const auto & kvpair) { return kvpair.first + "=" + kvpair.second; }); } +static Path parsePath(const AbstractSetting & s, const std::string & str) +{ + if (str == "") + throw UsageError("setting '%s' is a path and paths cannot be empty", s.name); + else + return canonPath(str); +} + +template<> +std::filesystem::path BaseSetting::parse(const std::string & str) const +{ + return parsePath(*this, str); +} + +template<> +std::string BaseSetting::to_string() const +{ + return value.string(); +} + +template<> +std::optional +BaseSetting>::parse(const std::string & str) const +{ + if (str == "") + return std::nullopt; + else + return parsePath(*this, str); +} + +template<> +std::string BaseSetting>::to_string() const +{ + return value ? value->string() : ""; +} + template class BaseSetting; template class BaseSetting; template class BaseSetting; @@ -445,14 +481,8 @@ template class BaseSetting; template class BaseSetting; template class BaseSetting; template class BaseSetting>; - -static Path parsePath(const AbstractSetting & s, const std::string & str) -{ - if (str == "") - throw UsageError("setting '%s' is a path and paths cannot be empty", s.name); - else - return canonPath(str); -} +template class BaseSetting; +template class BaseSetting>; PathSetting::PathSetting( Config * options, diff --git a/src/libutil/include/nix/util/config-impl.hh b/src/libutil/include/nix/util/config-impl.hh index f407bc862..8f6f9a358 100644 --- a/src/libutil/include/nix/util/config-impl.hh +++ b/src/libutil/include/nix/util/config-impl.hh @@ -16,6 +16,7 @@ #include "nix/util/configuration.hh" #include "nix/util/args.hh" #include "nix/util/logging.hh" +#include "nix/util/file-path.hh" namespace nix { @@ -134,6 +135,8 @@ DECLARE_CONFIG_SERIALISER(Strings) DECLARE_CONFIG_SERIALISER(StringSet) DECLARE_CONFIG_SERIALISER(StringMap) DECLARE_CONFIG_SERIALISER(std::set) +DECLARE_CONFIG_SERIALISER(std::filesystem::path) +DECLARE_CONFIG_SERIALISER(std::optional) template T BaseSetting::parse(const std::string & str) const diff --git a/src/libutil/include/nix/util/file-path.hh b/src/libutil/include/nix/util/file-path.hh index 25349eaf7..52dae32ff 100644 --- a/src/libutil/include/nix/util/file-path.hh +++ b/src/libutil/include/nix/util/file-path.hh @@ -5,6 +5,7 @@ #include "nix/util/types.hh" #include "nix/util/os-string.hh" +#include "nix/util/json-non-null.hh" namespace nix { @@ -53,4 +54,8 @@ std::optional maybePath(PathView path); std::filesystem::path pathNG(PathView path); +template<> +struct json_avoids_null : std::true_type +{}; + } // namespace nix diff --git a/src/libutil/include/nix/util/logging.hh b/src/libutil/include/nix/util/logging.hh index 500d443e6..4673895aa 100644 --- a/src/libutil/include/nix/util/logging.hh +++ b/src/libutil/include/nix/util/logging.hh @@ -54,9 +54,9 @@ struct LoggerSettings : Config expression evaluation errors. )"}; - Setting jsonLogPath{ + Setting> jsonLogPath{ this, - "", + {}, "json-log-path", R"( A file or unix socket to which JSON records of Nix's log output are diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index e2f28f553..8f7ec2d29 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -367,10 +367,10 @@ std::unique_ptr makeJSONLogger(const std::filesystem::path & path, bool void applyJSONLogger() { - if (!loggerSettings.jsonLogPath.get().empty()) { + if (auto & opt = loggerSettings.jsonLogPath.get()) { try { std::vector> loggers; - loggers.push_back(makeJSONLogger(std::filesystem::path(loggerSettings.jsonLogPath.get()), false)); + loggers.push_back(makeJSONLogger(*opt, false)); try { logger = makeTeeLogger(std::move(logger), std::move(loggers)); } catch (...) {