diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2023-02-05 12:16:17 -0500 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2023-03-16 20:06:46 -0400 |
commit | c998e0172f31fd5707a8361962ec99b3ff9b1b10 (patch) | |
tree | c8556e4e261fb80faebe66558b5bcccf92d1b26f /src/libcmd/installable-value.cc | |
parent | acd707acca8acbc276af5181c7724c70a6a69ad5 (diff) |
Move value-only methods to `InstallableValue`
These methods would previously fail on the other `Installable`s, so
moving them to this class is more correct as to where they actually
work.
Additionally, a `InstallableValueCommand` is created to make it easier
(or rather no worse than before) to write commands that just work on
`InstallableValue`s.
Besides being a cleanup to avoid failing default methods, this gets us
closer to https://github.com/NixOS/rfcs/pull/134.
Diffstat (limited to 'src/libcmd/installable-value.cc')
-rw-r--r-- | src/libcmd/installable-value.cc | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/libcmd/installable-value.cc b/src/libcmd/installable-value.cc new file mode 100644 index 000000000..30f80edb2 --- /dev/null +++ b/src/libcmd/installable-value.cc @@ -0,0 +1,44 @@ +#include "installable-value.hh" +#include "eval-cache.hh" + +namespace nix { + +std::vector<ref<eval_cache::AttrCursor>> +InstallableValue::getCursors(EvalState & state) +{ + auto evalCache = + std::make_shared<nix::eval_cache::EvalCache>(std::nullopt, state, + [&]() { return toValue(state).first; }); + return {evalCache->getRoot()}; +} + +ref<eval_cache::AttrCursor> +InstallableValue::getCursor(EvalState & state) +{ + /* Although getCursors should return at least one element, in case it doesn't, + bound check to avoid an undefined behavior for vector[0] */ + return getCursors(state).at(0); +} + +static UsageError nonValueInstallable(Installable & installable) +{ + return UsageError("installable '%s' does not correspond to a Nix language value", installable.what()); +} + +InstallableValue & InstallableValue::require(Installable & installable) +{ + auto * castedInstallable = dynamic_cast<InstallableValue *>(&installable); + if (!castedInstallable) + throw nonValueInstallable(installable); + return *castedInstallable; +} + +ref<InstallableValue> InstallableValue::require(ref<Installable> installable) +{ + auto castedInstallable = installable.dynamic_pointer_cast<InstallableValue>(); + if (!castedInstallable) + throw nonValueInstallable(*installable); + return ref { castedInstallable }; +} + +} |