feat(tvix/eval): contextful JSON operations

`toJSON` transform a Nix structure into a JSON string.

For each context in that Nix structure, the JSON string must possess it.

Thus, it is necessary to take the union of all contexts and attach it to
the final structure.

Unfortunately, the return type of `into_json` is a serde's JSON object,
not a string. Therefore, it is not possible to reuse `NixString`
machinery.

Context tests are reinforced as Nix does not test those behaviors.

Fixes b/393.

Change-Id: I5afdbc4e18dd70469192c1aa657d1049ba330149
Signed-off-by: Ryan Lahfa <tvl@lahfa.xyz>
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11266
Reviewed-by: flokli <flokli@flokli.de>
Tested-by: BuildkiteCI
This commit is contained in:
Ryan Lahfa 2024-03-25 03:36:32 +01:00 committed by raitobezarius
parent 45cf7ae657
commit 863c4207cc
11 changed files with 102 additions and 33 deletions

View file

@ -372,14 +372,13 @@ pub(crate) mod derivation_builtins {
return Ok(val);
}
// TODO(raitobezarius): context for json values?
// input_context.mimic(&val);
let val_json = match val.into_json(&co).await? {
let (val_json, mut context) = match val.into_contextful_json(&co).await? {
Ok(v) => v,
Err(cek) => return Ok(Value::from(cek)),
};
input_context = input_context.join(&mut context);
// No need to check for dups, we only iterate over every attribute name once
structured_attrs.insert(arg_name.to_owned(), val_json);
} else {

View file

@ -1 +1 @@
[ true true true true true true true true true true true ]
[ true true true true true true true true true true true true true ]

View file

@ -41,6 +41,13 @@ let
reconstructed-path = appendContextFrom combo-path
(builtins.unsafeDiscardStringContext combo-path);
an-str = {
a = "${drv}";
};
an-list = {
b = [ drv ];
};
# Eta rule for strings with context.
etaRule = str:
str == appendContextFrom
@ -70,4 +77,7 @@ in
(etaRule "foo")
(etaRule drv.drvPath)
(etaRule drv.foo.outPath)
# `toJSON` tests
(builtins.hasContext (builtins.toJSON an-str))
(builtins.hasContext (builtins.toJSON an-list))
]

View file

@ -1 +1 @@
[ true true true true true true true true true true true true true true true true true true true true true true true true true true true true ]
[ true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true true ]

View file

@ -93,4 +93,27 @@ in
(preserveContext other-drv (builtins.concatStringsSep "${other-drv}" [ "abc" "def" ]))
# `attrNames` will never ever produce context.
(preserveContext "abc" (toString (builtins.attrNames { a = { }; b = { }; c = { }; })))
# `toJSON` preserves context of its inputs.
(preserveContexts [ drv other-drv ] (builtins.toJSON {
a = [ drv ];
b = [ other-drv ];
}))
(preserveContexts [ drv other-drv ] (builtins.toJSON {
a.deep = [ drv ];
b = [ other-drv ];
}))
(preserveContexts [ drv other-drv ] (builtins.toJSON {
a = "${drv}";
b = [ other-drv ];
}))
(preserveContexts [ drv other-drv ] (builtins.toJSON {
a.deep = "${drv}";
b = [ other-drv ];
}))
(preserveContexts [ drv other-drv ] (builtins.toJSON {
a = "${drv} ${other-drv}";
}))
(preserveContexts [ drv other-drv ] (builtins.toJSON {
a.b.c.d.e.f = "${drv} ${other-drv}";
}))
]