aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-10-27 12:18:35 +0100
committerEelco Dolstra <edolstra@gmail.com>2019-10-27 12:18:35 +0100
commite012384fe99bd7d229fffa78f890d3ede915709b (patch)
tree780705f8e12e26836e5eb9ddd2879473394bfd66 /src/libexpr
parent2f96a89646c6e55e2f1bbb80805dcbbe60fa94ae (diff)
parente583df52800b4baa1564b027fe3b83a21756c2cc (diff)
Merge branch 'tojson-tostring-fix' of https://github.com/mayflower/nix
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc23
-rw-r--r--src/libexpr/eval.hh4
-rw-r--r--src/libexpr/value-to-json.cc7
3 files changed, 27 insertions, 7 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index f60e8d3ab..dc16d20b5 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1567,6 +1567,19 @@ bool EvalState::isDerivation(Value & v)
}
+std::optional<string> EvalState::tryAttrsToString(const Pos & pos, Value & v,
+ PathSet & context, bool coerceMore, bool copyToStore)
+{
+ auto i = v.attrs->find(sToString);
+ if (i != v.attrs->end()) {
+ Value v1;
+ callFunction(*i->value, v, v1, pos);
+ return coerceToString(pos, v1, context, coerceMore, copyToStore);
+ }
+
+ return {};
+}
+
string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
bool coerceMore, bool copyToStore)
{
@@ -1585,13 +1598,11 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
}
if (v.type == tAttrs) {
- auto i = v.attrs->find(sToString);
- if (i != v.attrs->end()) {
- Value v1;
- callFunction(*i->value, v, v1, pos);
- return coerceToString(pos, v1, context, coerceMore, copyToStore);
+ auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore);
+ if (maybeString) {
+ return *maybeString;
}
- i = v.attrs->find(sOutPath);
+ auto i = v.attrs->find(sOutPath);
if (i == v.attrs->end()) throwTypeError("cannot coerce a set to a string, at %1%", pos);
return coerceToString(pos, *i->value, context, coerceMore, copyToStore);
}
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 22472fd72..61ee4a73b 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -9,6 +9,7 @@
#include "function-trace.hh"
#include <map>
+#include <optional>
#include <unordered_map>
@@ -196,6 +197,9 @@ public:
set with attribute `type = "derivation"'). */
bool isDerivation(Value & v);
+ std::optional<string> tryAttrsToString(const Pos & pos, Value & v,
+ PathSet & context, bool coerceMore = false, bool copyToStore = true);
+
/* String coercion. Converts strings, paths and derivations to a
string. If `coerceMore' is set, also converts nulls, integers,
booleans and lists to a string. If `copyToStore' is set,
diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc
index 72e413e44..5fe8570ad 100644
--- a/src/libexpr/value-to-json.cc
+++ b/src/libexpr/value-to-json.cc
@@ -40,7 +40,12 @@ void printValueAsJSON(EvalState & state, bool strict,
break;
case tAttrs: {
- Bindings::iterator i = v.attrs->find(state.sOutPath);
+ auto maybeString = state.tryAttrsToString(noPos, v, context, false, false);
+ if (maybeString) {
+ out.write(*maybeString);
+ break;
+ }
+ auto i = v.attrs->find(state.sOutPath);
if (i == v.attrs->end()) {
auto obj(out.object());
StringSet names;