fix(tvix/eval): handle __toString
when JSON-serialising attrsets
These must be serialised to a JSON string of the *result* of coercing the function application to a string. Change-Id: Ib7f49ccd950503ddbdbf99643cd59565e26b50da Reviewed-on: https://cl.tvl.fyi/c/depot/+/8204 Reviewed-by: raitobezarius <tvl@lahfa.xyz> Tested-by: BuildkiteCI
This commit is contained in:
parent
a9f44721e5
commit
7d339d2762
5 changed files with 29 additions and 0 deletions
|
@ -359,6 +359,15 @@ mod pure_builtins {
|
|||
|
||||
#[builtin("toJSON")]
|
||||
async fn builtin_to_json(co: GenCo, val: Value) -> Result<Value, ErrorKind> {
|
||||
if let Value::Attrs(attrs) = &val {
|
||||
// Attribute sets with a callable `__toString` attribute
|
||||
// serialise to the string-coerced version of the result of
|
||||
// calling that.
|
||||
if let Some(s) = attrs.try_to_string(&co, CoercionKind::Weak).await {
|
||||
return Ok(Value::String(serde_json::to_string(&s)?.into()));
|
||||
}
|
||||
}
|
||||
|
||||
// All thunks need to be evaluated before serialising, as the
|
||||
// data structure is fully traversed by the Serializer.
|
||||
let val = generators::request_deep_force(&co, val, SharedThunkSet::default()).await;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# attribute sets with a non-callable `__toString` can not be
|
||||
# serialised to JSON.
|
||||
builtins.toJSON {
|
||||
__toString = 42;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
# String coercions when using builtins.toJSON on an attribute set with
|
||||
# a `__toString` attribute should be weak.
|
||||
builtins.toJSON {
|
||||
__toString = self: self.x;
|
||||
x = 42;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
"\"it's 42\""
|
|
@ -0,0 +1,8 @@
|
|||
# Attribute sets with a `__toString` attribute JSON-serialise with a
|
||||
# string coercion of the function call result.
|
||||
|
||||
builtins.toJSON {
|
||||
__toString = self: "it's " + (builtins.toString (self.x * self.y));
|
||||
x = 21;
|
||||
y = 2;
|
||||
}
|
Loading…
Reference in a new issue