aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2022-03-04 09:44:00 +0100
committerregnat <rg@regnat.ovh>2022-03-07 10:09:10 +0100
commit98e361ad4c1a26d4ffe4762a6f33bb9e39321a39 (patch)
tree44d0ab1781f96511d4c95c274f6b64f943a070b0 /src/libutil
parent2405bbbb5edd204d6031edcd470a2057f4a25782 (diff)
Also display suggestions for the commands using the eval cache
Make `nix build .#nix-armv8l-linux` work for example
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/suggestions.hh58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/libutil/suggestions.hh b/src/libutil/suggestions.hh
index 76063a261..63426259d 100644
--- a/src/libutil/suggestions.hh
+++ b/src/libutil/suggestions.hh
@@ -40,4 +40,62 @@ public:
Suggestions& operator+=(const Suggestions & other);
};
+// Either a value of type `T`, or some suggestions
+template<typename T>
+class OrSuggestions {
+public:
+ using Raw = std::variant<T, Suggestions>;
+
+ Raw raw;
+
+ T* operator ->()
+ {
+ return &**this;
+ }
+
+ T& operator *()
+ {
+ if (auto elt = std::get_if<T>(&raw))
+ return *elt;
+ throw Error("Invalid access to a failed value");
+ }
+
+ operator bool() const noexcept
+ {
+ return std::holds_alternative<T>(raw);
+ }
+
+ OrSuggestions(T t)
+ : raw(t)
+ {
+ }
+
+ OrSuggestions()
+ : raw(Suggestions{})
+ {
+ }
+
+ static OrSuggestions<T> failed(const Suggestions & s)
+ {
+ auto res = OrSuggestions<T>();
+ res.raw = s;
+ return res;
+ }
+
+ static OrSuggestions<T> failed()
+ {
+ return OrSuggestions<T>::failed(Suggestions{});
+ }
+
+ const Suggestions & get_suggestions()
+ {
+ static Suggestions noSuggestions;
+ if (const auto & suggestions = std::get_if<Suggestions>(&raw))
+ return *suggestions;
+ else
+ return noSuggestions;
+ }
+
+};
+
}