nu_plugin_tera/src/helpers.rs
Jesús Pérez 8d6598211b chore: update all plugins to Nushell 0.111.0
- Bump all 18 plugins from 0.110.0 to 0.111.0
  - Update rust-toolchain.toml channel to 1.93.1 (nu 0.111.0 requires ≥1.91.1)

  Fixes:
  - interprocess pin =2.2.x → ^2.3.1 in nu_plugin_mcp, nu_plugin_nats, nu_plugin_typedialog
    (required by nu-plugin-core 0.111.0)
  - nu_plugin_typedialog: BackendType::Web initializer — add open_browser: false field
  - nu_plugin_auth: implement missing user_info_to_value helper referenced in tests

  Scripts:
  - update_all_plugins.nu: fix [package].version update on minor bumps; add [dev-dependencies]
    pass; add nu-plugin-test-support to managed crates
  - download_nushell.nu: rustup override unset before rm -rf on nushell dir replace;
    fix unclosed ) in string interpolation
2026-03-11 03:21:44 +00:00

66 lines
2.4 KiB
Rust

use nu_protocol::{LabeledError, Value};
/// Convert a Nushell Value to a serde_json::Value suitable for Tera context.
///
/// - Records are converted to JSON objects.
/// - Lists, strings, ints, and bools are wrapped in an object with key "value".
/// - Other types return an error.
pub fn value_to_serde_json(value: Value) -> Result<serde_json::Value, LabeledError> {
match value {
Value::Record { val, .. } => {
let record = &*val;
let mut map = serde_json::Map::new();
for (col, val) in record.columns().zip(record.values()) {
map.insert(col.clone(), value_to_serde_json(val.clone())?);
}
Ok(serde_json::Value::Object(map))
}
Value::List { vals, .. } => {
let vec = vals
.into_iter()
.map(value_to_serde_json)
.collect::<Result<Vec<_>, _>>()?;
Ok(serde_json::Value::Array(vec))
}
Value::String { val, .. } => Ok(serde_json::Value::String(val)),
Value::Int { val, .. } => Ok(serde_json::Value::Number(val.into())),
Value::Bool { val, .. } => Ok(serde_json::Value::Bool(val)),
_ => Err(LabeledError::new("Type not supported")
.with_label("Use records, lists or primitives", value.span())),
}
}
/// Removes the top-level 'value' key if it is the only key in the object, and always returns an object (wraps non-objects as { "value": ... }).
pub fn unwrap_value_key(json: serde_json::Value) -> serde_json::Value {
let unwrapped = if let serde_json::Value::Object(mut map) = json {
if map.len() == 1
&& let Some(inner) = map.remove("value")
{
return unwrap_value_key(inner);
}
serde_json::Value::Object(map)
} else {
json
};
match unwrapped {
serde_json::Value::Object(_) => unwrapped,
other => {
let mut map = serde_json::Map::new();
map.insert("value".to_string(), other);
serde_json::Value::Object(map)
}
}
}
/// Wraps the top-level value if it is not an object.
pub fn wrap_top_level_if_needed(json: serde_json::Value) -> serde_json::Value {
match json {
serde_json::Value::Object(_) => json,
other => {
let mut map = serde_json::Map::new();
map.insert("value".to_string(), other);
serde_json::Value::Object(map)
}
}
}