diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 3242ef9d..953bf6aa 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -89,6 +89,11 @@ template<> std::string BaseSetting::to_string() else abort(); } +template<> void BaseSetting::toJSON(JSONPlaceholder & out) +{ + AbstractSetting::toJSON(out); +} + void MaxBuildJobsSetting::set(const std::string & str) { if (str == "auto") value = std::max(1U, std::thread::hardware_concurrency()); diff --git a/src/libutil/config.cc b/src/libutil/config.cc index 72b6cf80..62c6433c 100644 --- a/src/libutil/config.cc +++ b/src/libutil/config.cc @@ -1,5 +1,6 @@ #include "config.hh" #include "args.hh" +#include "json.hh" namespace nix { @@ -103,6 +104,17 @@ void Config::resetOverriden() s.second.setting->overriden = false; } +void Config::toJSON(JSONObject & out) +{ + for (auto & s : _settings) + if (!s.second.isAlias) { + JSONObject out2(out.object(s.first)); + out2.attr("description", s.second.setting->description); + JSONPlaceholder out3(out2.placeholder("value")); + s.second.setting->toJSON(out3); + } +} + AbstractSetting::AbstractSetting( const std::string & name, const std::string & description, @@ -111,6 +123,17 @@ AbstractSetting::AbstractSetting( { } +void AbstractSetting::toJSON(JSONPlaceholder & out) +{ + out.write(to_string()); +} + +template +void BaseSetting::toJSON(JSONPlaceholder & out) +{ + out.write(value); +} + template<> void BaseSetting::set(const std::string & str) { value = str; @@ -161,6 +184,13 @@ template<> std::string BaseSetting::to_string() return concatStringsSep(" ", value); } +template<> void BaseSetting::toJSON(JSONPlaceholder & out) +{ + JSONList list(out.list()); + for (auto & s : value) + list.elem(s); +} + template<> void BaseSetting::set(const std::string & str) { value = tokenizeString(str); @@ -171,12 +201,20 @@ template<> std::string BaseSetting::to_string() return concatStringsSep(" ", value); } +template<> void BaseSetting::toJSON(JSONPlaceholder & out) +{ + JSONList list(out.list()); + for (auto & s : value) + list.elem(s); +} + template class BaseSetting; template class BaseSetting; template class BaseSetting; template class BaseSetting; template class BaseSetting; template class BaseSetting; +template class BaseSetting; void PathSetting::set(const std::string & str) { diff --git a/src/libutil/config.hh b/src/libutil/config.hh index 130f59e2..91962109 100644 --- a/src/libutil/config.hh +++ b/src/libutil/config.hh @@ -9,6 +9,8 @@ namespace nix { class Args; class AbstractSetting; +class JSONPlaceholder; +class JSONObject; /* A class to simplify providing configuration settings. The typical use is to inherit Config and add Setting members: @@ -56,6 +58,8 @@ public: void applyConfigFile(const Path & path, bool fatal = false); void resetOverriden(); + + void toJSON(JSONObject & out); }; class AbstractSetting @@ -90,6 +94,8 @@ protected: virtual std::string to_string() = 0; + virtual void toJSON(JSONPlaceholder & out); + bool isOverriden() { return overriden; } }; @@ -122,6 +128,8 @@ public: void set(const std::string & str) override; std::string to_string() override; + + void toJSON(JSONPlaceholder & out) override; }; template diff --git a/src/libutil/json.cc b/src/libutil/json.cc index 6023d1d4..b8b8ef9c 100644 --- a/src/libutil/json.cc +++ b/src/libutil/json.cc @@ -19,51 +19,34 @@ void toJSON(std::ostream & str, const char * start, const char * end) str << '"'; } -void toJSON(std::ostream & str, const std::string & s) -{ - toJSON(str, s.c_str(), s.c_str() + s.size()); -} - void toJSON(std::ostream & str, const char * s) { if (!s) str << "null"; else toJSON(str, s, s + strlen(s)); } -void toJSON(std::ostream & str, unsigned long long n) +template<> void toJSON(std::ostream & str, const int & n) { str << n; } +template<> void toJSON(std::ostream & str, const unsigned int & n) { str << n; } +template<> void toJSON(std::ostream & str, const long & n) { str << n; } +template<> void toJSON(std::ostream & str, const unsigned long & n) { str << n; } +template<> void toJSON(std::ostream & str, const long long & n) { str << n; } +template<> void toJSON(std::ostream & str, const unsigned long long & n) { str << n; } +template<> void toJSON(std::ostream & str, const float & n) { str << n; } + +template<> void toJSON(std::ostream & str, const std::string & s) { - str << n; + toJSON(str, s.c_str(), s.c_str() + s.size()); } -void toJSON(std::ostream & str, unsigned long n) -{ - str << n; -} - -void toJSON(std::ostream & str, long n) -{ - str << n; -} - -void toJSON(std::ostream & str, unsigned int n) -{ - str << n; -} - -void toJSON(std::ostream & str, int n) -{ - str << n; -} - -void toJSON(std::ostream & str, double f) -{ - str << f; -} - -void toJSON(std::ostream & str, bool b) +template<> void toJSON(std::ostream & str, const bool & b) { str << (b ? "true" : "false"); } +template<> void toJSON(std::ostream & str, const std::nullptr_t & b) +{ + str << "null"; +} + JSONWriter::JSONWriter(std::ostream & str, bool indent) : state(new JSONState(str, indent)) { diff --git a/src/libutil/json.hh b/src/libutil/json.hh index 03eecb73..595e9bbe 100644 --- a/src/libutil/json.hh +++ b/src/libutil/json.hh @@ -7,15 +7,10 @@ namespace nix { void toJSON(std::ostream & str, const char * start, const char * end); -void toJSON(std::ostream & str, const std::string & s); void toJSON(std::ostream & str, const char * s); -void toJSON(std::ostream & str, unsigned long long n); -void toJSON(std::ostream & str, unsigned long n); -void toJSON(std::ostream & str, long n); -void toJSON(std::ostream & str, unsigned int n); -void toJSON(std::ostream & str, int n); -void toJSON(std::ostream & str, double f); -void toJSON(std::ostream & str, bool b); + +template +void toJSON(std::ostream & str, const T & n); class JSONWriter { diff --git a/src/nix/show-config.cc b/src/nix/show-config.cc index ba39e2bb..aade2ade 100644 --- a/src/nix/show-config.cc +++ b/src/nix/show-config.cc @@ -31,8 +31,7 @@ struct CmdShowConfig : Command if (json) { // FIXME: use appropriate JSON types (bool, ints, etc). JSONObject jsonObj(std::cout, true); - for (auto & s : settings.getSettings()) - jsonObj.attr(s.first, s.second); + settings.toJSON(jsonObj); } else { for (auto & s : settings.getSettings()) std::cout << s.first + " = " + s.second + "\n";