aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobin Gloster <mail@glob.in>2019-10-27 10:15:51 +0100
committerRobin Gloster <mail@glob.in>2019-10-27 10:15:51 +0100
commite583df52800b4baa1564b027fe3b83a21756c2cc (patch)
tree397408408f306285a85d38ecfb9c6d6040d5e8e0 /src
parentc0559a1d6092b94c7ce46a065d72fc74e4db51dd (diff)
builtins.toJSON: fix __toString usage
Diffstat (limited to 'src')
-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 d8e10d9f2..8f728b906 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -1565,6 +1565,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)
{
@@ -1583,13 +1596,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 a314e01e0..82e6ca877 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -8,6 +8,7 @@
#include "config.hh"
#include <map>
+#include <optional>
#include <unordered_map>
@@ -195,6 +196,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;