diff options
author | regnat <rg@regnat.ovh> | 2021-10-25 15:53:01 +0200 |
---|---|---|
committer | regnat <rg@regnat.ovh> | 2021-10-26 07:02:31 +0200 |
commit | af99941279b80c962ec9cae3e5fa32976a3f5744 (patch) | |
tree | 034ffb01457354b07e9b6dac02892e1b5d8fca09 /src/libutil/experimental-features.cc | |
parent | 4a2b7cc68c7d11ec126bc412ffea838e629345af (diff) |
Make experimental-features a proper type
Rather than having them plain strings scattered through the whole
codebase, create an enum containing all the known experimental features.
This means that
- Nix can now `warn` when an unkwown experimental feature is passed
(making it much nicer to spot typos and spot deprecated features)
- It’s now easy to remove a feature altogether (once the feature isn’t
experimental anymore or is dropped) by just removing the field for the
enum and letting the compiler point us to all the now invalid usages
of it.
Diffstat (limited to 'src/libutil/experimental-features.cc')
-rw-r--r-- | src/libutil/experimental-features.cc | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc new file mode 100644 index 000000000..d1235d8a4 --- /dev/null +++ b/src/libutil/experimental-features.cc @@ -0,0 +1,55 @@ +#include "experimental-features.hh" +#include "nlohmann/json.hpp" + +namespace nix { + +std::map<ExperimentalFeature, std::string> stringifiedXpFeatures = { + { Xp::CaDerivations, "ca-derivations" }, + { Xp::Flakes, "flakes" }, + { Xp::NixCommand, "nix-command" }, + { Xp::RecursiveNix, "recursive-nix" }, + { Xp::NoUrlLiterals, "no-url-literals" }, +}; + +const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::string_view & name) +{ + using ReverseXpMap = std::map<std::string_view, ExperimentalFeature>; + static ReverseXpMap * reverseXpMap; + if (!reverseXpMap) { + reverseXpMap = new ReverseXpMap{}; + for (auto & [feature, name] : stringifiedXpFeatures) + (*reverseXpMap)[name] = feature; + } + + auto featureIter = reverseXpMap->find(name); + if (featureIter == reverseXpMap->end()) + return std::nullopt; + return {featureIter->second}; +} + +std::string_view showExperimentalFeature(const ExperimentalFeature feature) +{ + return stringifiedXpFeatures.at(feature); +} + +std::set<ExperimentalFeature> parseFeatures(const std::set<std::string> & rawFeatures) +{ + std::set<ExperimentalFeature> res; + for (auto & rawFeature : rawFeatures) { + if (auto feature = parseExperimentalFeature(rawFeature)) + res.insert(*feature); + } + return res; +} + +MissingExperimentalFeature::MissingExperimentalFeature(ExperimentalFeature feature) + : Error("experimental Nix feature '%1%' is disabled; use '--extra-experimental-features %1%' to override", showExperimentalFeature(feature)) + , missingFeature(feature) + {} + +std::ostream & operator <<(std::ostream & str, const ExperimentalFeature & feature) +{ + return str << showExperimentalFeature(feature); +} + +} |