Unify closure serializing logic for to nuon, to msgpack, and to json (#15285)

# Description
Before this PR, `to msgpack`/`to msgpackz` and `to json` serialize
closures as `nil`/`null` respectively, when the `--serialize` option
isn't passed. This PR makes it an error to serialize closures to msgpack
or JSON without the `--serialize` flag, which is the behavior of `to
nuon`.

This PR also adds the `--serialize` flag to `to msgpack`.

This PR also changes `to nuon` and `to json` to return an error if they
cannot find the block contents of a closure, rather than serializing an
empty string or an error string, respectively. This behavior is
replicated for `to msgpack`.

It also changes `to nuon`'s error message for serializing closures
without `--serialize` to be the same as the new errors for `to json` and
`to msgpack`.

# User-Facing Changes

* Add `--serialize` flag to `to msgpack`, similar to the `--serialize`
flag for `to nuon` and `to json`.
* Serializing closures to JSON or msgpack without `--serialize`

Partially fixes #11738
This commit is contained in:
132ikl
2025-03-16 15:15:02 -04:00
committed by GitHub
parent 00e5e6d719
commit 83de8560ee
9 changed files with 136 additions and 69 deletions

View File

@@ -99,17 +99,10 @@ fn value_to_string(
}
Value::Closure { val, .. } => {
if serialize_types {
let block = engine_state.get_block(val.block_id);
if let Some(span) = block.span {
let contents_bytes = engine_state.get_span_contents(span);
let contents_string = String::from_utf8_lossy(contents_bytes);
Ok(contents_string.to_string())
} else {
Ok(String::new())
}
Ok(val.coerce_into_string(engine_state, span)?.to_string())
} else {
Err(ShellError::UnsupportedInput {
msg: "closures are currently not nuon-compatible".into(),
msg: "closures are currently not deserializable (use --serialize to serialize as a string)".into(),
input: "value originates from here".into(),
msg_span: span,
input_span: v.span(),