9121fed4b4
Types converted: - `NixStringContextElem` - `OutputsSpec` - `ExtendedOutputsSpec` - `DerivationOutput` - `DerivationType` Existing ones mostly conforming the pattern cleaned up: - `ContentAddressMethod` - `ContentAddressWithReferences` The `DerivationGoal::derivationType` field had a bogus initialization, now caught, so I made it `std::optional`. I think #8829 can make it non-optional again because it will ensure we always have the derivation when we construct a `DerivationGoal`. See that issue (#7479) for details on the general goal. `git grep 'Raw::Raw'` indicates the two types I didn't yet convert `DerivedPath` and `BuiltPath` (and their `Single` variants) . This is because @roberth and I (can't find issue right now...) plan on reworking them somewhat, so I didn't want to churn them more just yet. Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
108 lines
3 KiB
C++
108 lines
3 KiB
C++
#include "value/context.hh"
|
|
|
|
#include <optional>
|
|
|
|
namespace nix {
|
|
|
|
NixStringContextElem NixStringContextElem::parse(
|
|
std::string_view s0,
|
|
const ExperimentalFeatureSettings & xpSettings)
|
|
{
|
|
std::string_view s = s0;
|
|
|
|
std::function<SingleDerivedPath()> parseRest;
|
|
parseRest = [&]() -> SingleDerivedPath {
|
|
// Case on whether there is a '!'
|
|
size_t index = s.find("!");
|
|
if (index == std::string_view::npos) {
|
|
return SingleDerivedPath::Opaque {
|
|
.path = StorePath { s },
|
|
};
|
|
} else {
|
|
std::string output { s.substr(0, index) };
|
|
// Advance string to parse after the '!'
|
|
s = s.substr(index + 1);
|
|
auto drv = make_ref<SingleDerivedPath>(parseRest());
|
|
drvRequireExperiment(*drv, xpSettings);
|
|
return SingleDerivedPath::Built {
|
|
.drvPath = std::move(drv),
|
|
.output = std::move(output),
|
|
};
|
|
}
|
|
};
|
|
|
|
if (s.size() == 0) {
|
|
throw BadNixStringContextElem(s0,
|
|
"String context element should never be an empty string");
|
|
}
|
|
|
|
switch (s.at(0)) {
|
|
case '!': {
|
|
// Advance string to parse after the '!'
|
|
s = s.substr(1);
|
|
|
|
// Find *second* '!'
|
|
if (s.find("!") == std::string_view::npos) {
|
|
throw BadNixStringContextElem(s0,
|
|
"String content element beginning with '!' should have a second '!'");
|
|
}
|
|
|
|
return std::visit(
|
|
[&](auto x) -> NixStringContextElem { return std::move(x); },
|
|
parseRest());
|
|
}
|
|
case '=': {
|
|
return NixStringContextElem::DrvDeep {
|
|
.drvPath = StorePath { s.substr(1) },
|
|
};
|
|
}
|
|
default: {
|
|
// Ensure no '!'
|
|
if (s.find("!") != std::string_view::npos) {
|
|
throw BadNixStringContextElem(s0,
|
|
"String content element not beginning with '!' should not have a second '!'");
|
|
}
|
|
return std::visit(
|
|
[&](auto x) -> NixStringContextElem { return std::move(x); },
|
|
parseRest());
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string NixStringContextElem::to_string() const
|
|
{
|
|
std::string res;
|
|
|
|
std::function<void(const SingleDerivedPath &)> toStringRest;
|
|
toStringRest = [&](auto & p) {
|
|
std::visit(overloaded {
|
|
[&](const SingleDerivedPath::Opaque & o) {
|
|
res += o.path.to_string();
|
|
},
|
|
[&](const SingleDerivedPath::Built & o) {
|
|
res += o.output;
|
|
res += '!';
|
|
toStringRest(*o.drvPath);
|
|
},
|
|
}, p.raw());
|
|
};
|
|
|
|
std::visit(overloaded {
|
|
[&](const NixStringContextElem::Built & b) {
|
|
res += '!';
|
|
toStringRest(b);
|
|
},
|
|
[&](const NixStringContextElem::Opaque & o) {
|
|
toStringRest(o);
|
|
},
|
|
[&](const NixStringContextElem::DrvDeep & d) {
|
|
res += '=';
|
|
res += d.drvPath.to_string();
|
|
},
|
|
}, raw);
|
|
|
|
return res;
|
|
}
|
|
|
|
}
|