libcmd: turn autoArgs into a map that points to std::variant

This is a little more elegant and easier to reason about than prefixing
strings with whatever type the rest of the string is.

Change-Id: I7769535303dcb9f67b79e89bef162beec990e2a0
This commit is contained in:
Maximilian Bosch
2026-03-21 23:16:29 +01:00
parent 66d702d28d
commit c5d21b36c5
2 changed files with 24 additions and 8 deletions
+14 -7
View File
@@ -44,7 +44,7 @@ MixEvalArgs::MixEvalArgs()
.labels = {"name", "expr"},
.handler = {[&](std::string name, std::string expr) {
checkValidNixIdentifier(name);
autoArgs[name] = 'E' + expr;
autoArgs[name] = ExprArgument(expr);
}}}
);
@@ -55,7 +55,7 @@ MixEvalArgs::MixEvalArgs()
.labels = {"name", "string"},
.handler = {[&](std::string name, std::string s) {
checkValidNixIdentifier(name);
autoArgs[name] = 'S' + s;
autoArgs[name] = StringArgument(s);
}},
});
@@ -182,11 +182,18 @@ MixEvalArgs::MixEvalArgs()
Bindings * MixEvalArgs::getAutoArgs(Evaluator & state)
{
auto res = state.buildBindings(autoArgs.size());
for (auto & i : autoArgs) {
Value v = i.second[0] == 'E'
? state.evalLazily(state.parseExprFromString(i.second.substr(1), CanonPath::fromCwd()))
: Value{NewValueAs::string, ((std::string_view) i.second).substr(1)};
res.insert(state.symbols.create(i.first), v);
for (auto & [name, value] : autoArgs) {
Value v = std::visit(
overloaded{
[&](StringArgument & str) -> Value { return {NewValueAs::string, (std::string_view) str.value}; },
[&](ExprArgument & e) -> Value {
return state.evalLazily(state.parseExprFromString(e.expr, CanonPath::fromCwd()));
}
},
value
);
res.insert(state.symbols.create(name), v);
}
return res.finish();
}
+10 -1
View File
@@ -14,6 +14,15 @@ class EvalState;
class Bindings;
struct SourcePath;
struct StringArgument
{
std::string value;
};
struct ExprArgument
{
std::string expr;
};
struct MixEvalArgs : virtual Args, virtual MixRepair
{
static constexpr auto category = "Common evaluation options";
@@ -27,7 +36,7 @@ struct MixEvalArgs : virtual Args, virtual MixRepair
std::optional<std::string> evalStoreUrl;
private:
std::map<std::string, std::string> autoArgs;
std::map<std::string, std::variant<StringArgument, ExprArgument>> autoArgs;
};
/** @brief Resolve an argument that is generally a file, but could be something that