3#include <nix/attr-path.hh>
4#include <nix/nixexpr.hh>
5#include <nix/symbol-table.hh>
10std::optional<nix::Value>
nixt::getField(nix::EvalState &State, nix::Value &V,
11 std::string_view Field) {
12 State.forceValue(V, nix::noPos);
13 if (V.type() != nix::ValueType::nAttrs)
16 nix::Symbol SFiled = State.symbols.create(Field);
17 if (
auto *It = V.attrs()->find(SFiled); It != V.attrs()->end())
25 std::string_view Field) {
26 if (
auto OptV =
getField(State, V, Field)) {
27 State.forceValue(*OptV, nix::noPos);
28 if (OptV->type() == nix::ValueType::nString) {
29 return State.forceStringNoCtx(*OptV, nix::noPos,
30 "nixt::getFieldString()");
37 std::string_view Field, std::string_view Pred) {
42 std::string_view Pred) {
51 return checkField(State, V,
"type",
"derivation");
55 const std::string &AttrPath) {
56 auto &AutoArgs = *State.allocBindings(0);
57 auto [VPath, Pos] = nix::findAlongAttrPath(State, AttrPath, AutoArgs, V);
58 State.forceValue(*VPath, Pos);
59 return std::string(State.forceStringNoCtx(*VPath, nix::noPos,
""));
62std::vector<nix::Symbol>
64 const std::vector<std::string> &Names) {
65 std::vector<nix::Symbol> Res;
66 Res.reserve(Names.size());
67 for (
const auto &Name : Names) {
68 Res.emplace_back(STable.create(Name));
73std::vector<nix::Symbol>
75 const std::vector<std::string_view> &Names) {
76 std::vector<nix::Symbol> Res;
77 Res.reserve(Names.size());
78 for (
const auto &Name : Names) {
79 Res.emplace_back(STable.create(Name));
86 State.forceValue(V, nix::noPos);
88 if (V.type() != nix::ValueType::nAttrs)
89 throw nix::TypeError(State,
"value is not an attrset");
91 assert(V.attrs() &&
"nix must allocate non-null attrs!");
92 auto *Nested = V.attrs()->find(Attr);
93 if (Nested == V.attrs()->end())
94 throw nix::AttrPathNotFound(
"attrname " + State.symbols[Attr] +
95 " not found in attrset");
97 assert(Nested->value &&
"nix must allocate non-null nested value!");
98 return *Nested->value;
103 std::vector<nix::Symbol>::const_iterator Begin,
104 std::vector<nix::Symbol>::const_iterator End) {
110 nix::Value &Nested =
selectAttr(State, V, *Begin);
117bool isTypeSubmodule(nix::EvalState &State, nix::Value &Type) {
118 return checkField(State, Type,
"name",
"submodule");
121nix::Value *trySelectAttr(nix::EvalState &State, nix::Value &V, nix::Symbol S) {
125 }
catch (nix::TypeError &) {
128 }
catch (nix::AttrPathNotFound &) {
136nix::Value *tryGetSubmoduleType(nix::EvalState &State, nix::Value &V) {
137 if (nix::Value *Type = trySelectAttr(State, V, State.sType))
138 return isTypeSubmodule(State, *Type) ?
Type :
nullptr;
143nix::Value getSubOptions(nix::EvalState &State, nix::Value &Type) {
145 nix::Value &GetSubOptions =
146 selectAttr(State, Type, State.symbols.create(
"getSubOptions"));
148 auto list = State.buildList(0);
149 auto EmptyList = State.allocValue();
150 EmptyList->mkList(list);
153 State.callFunction(GetSubOptions, *EmptyList, VResult, nix::noPos);
160 std::vector<nix::Symbol>::const_iterator Begin,
161 std::vector<nix::Symbol>::const_iterator End) {
163 if (nix::Value *SubType = tryGetSubmoduleType(State, V))
165 V = getSubOptions(State, *SubType);
177 nix::Value &Type =
selectAttr(State, V, State.sType);
178 if (
checkField(State, Type,
"name",
"attrsOf")) {
179 nix::Value NestedTypes =
180 selectAttr(State, Type, State.symbols.create(
"nestedTypes"));
181 nix::Value ElemType =
182 selectAttr(State, NestedTypes, State.symbols.create(
"elemType"));
184 if (isTypeSubmodule(State, ElemType)) {
185 nix::Value ElemOptions = getSubOptions(State, ElemType);
192 nix::Value &Nested =
selectAttr(State, V, *Begin);
Access EvalCache in nix::EvalState.
std::optional< std::string_view > getFieldString(nix::EvalState &State, nix::Value &V, std::string_view Field)
nix::Value & selectAttrPath(nix::EvalState &State, nix::Value &V, std::vector< nix::Symbol >::const_iterator Begin, std::vector< nix::Symbol >::const_iterator End)
Given an attrpath in nix::Value V, select it.
bool isOption(nix::EvalState &State, nix::Value &V)
bool checkField(nix::EvalState &State, nix::Value &V, std::string_view Field, std::string_view Pred)
Check if value V is an attrset, has the field, and equals to Pred.
bool checkType(nix::EvalState &State, nix::Value &V, std::string_view Pred)
Check if value is an attrset, and it's "_type" equals to Pred.
std::string attrPathStr(nix::EvalState &State, nix::Value &V, const std::string &AttrPath)
bool isDerivation(nix::EvalState &State, nix::Value &V)
nix::Value selectOptions(nix::EvalState &State, nix::Value &V, std::vector< nix::Symbol >::const_iterator Begin, std::vector< nix::Symbol >::const_iterator End)
Select the option declaration list, V, dive into "submodules".
std::vector< nix::Symbol > toSymbols(nix::SymbolTable &STable, const std::vector< std::string > &Names)
Transform a vector of string into a vector of nix symbols.
nix::Value & selectAttr(nix::EvalState &State, nix::Value &V, nix::Symbol Attr)
Select attribute Attr.
std::optional< nix::Value > getField(nix::EvalState &State, nix::Value &V, std::string_view Field)