Make custom value type handling more consistent (#12230)

[Context on
Discord](https://discord.com/channels/601130461678272522/855947301380947968/1219425984990806207)

# Description

- Rename `CustomValue::value_string()` to `type_name()` to reflect its
usage better.
- Change print behavior to always call `to_base_value()` first, to give
the custom value better control over the output.
- Change `describe --detailed` to show the type name as the subtype,
rather than trying to describe the base value.
- Change custom `Type` to use `type_name()` rather than `typetag_name()`
to make things like `PluginCustomValue` more transparent

One question: should `describe --detailed` still include a description
of the base value somewhere? I'm torn on it, it seems possibly useful
for some things (maybe sqlite databases?), but having `describe -d` not
include the custom type name anywhere felt weird. Another option would
be to add another method to `CustomValue` for info to be displayed in
`describe`, so that it can be more type-specific?

# User-Facing Changes
Everything above has implications for printing and `describe` on custom
values

# Tests + Formatting
- 🟢 `toolkit fmt`
- 🟢 `toolkit clippy`
- 🟢 `toolkit test`
- 🟢 `toolkit test stdlib`
This commit is contained in:
Devyn Cairns
2024-03-19 03:09:59 -07:00
committed by GitHub
parent 931f522616
commit 6795ad7e33
19 changed files with 51 additions and 45 deletions

View File

@ -235,7 +235,7 @@ fn run(
if options.no_collect {
Value::string("any", head)
} else {
describe_value(input.into_value(head), head, engine_state, call, options)?
describe_value(input.into_value(head), head, engine_state, options)?
}
},
"metadata" => metadata_to_value(metadata, head),
@ -246,10 +246,7 @@ fn run(
Value::string("stream", head)
} else {
let value = input.into_value(head);
let base_description = match value {
Value::CustomValue { val, .. } => val.value_string(),
_ => value.get_type().to_string(),
};
let base_description = value.get_type().to_string();
Value::string(format!("{} (stream)", base_description), head)
}
@ -257,12 +254,9 @@ fn run(
_ => {
let value = input.into_value(head);
if !options.detailed {
match value {
Value::CustomValue { val, .. } => Value::string(val.value_string(), head),
_ => Value::string(value.get_type().to_string(), head),
}
Value::string(value.get_type().to_string(), head)
} else {
describe_value(value, head, engine_state, call, options)?
describe_value(value, head, engine_state, options)?
}
}
};
@ -286,14 +280,13 @@ fn describe_value(
value: Value,
head: nu_protocol::Span,
engine_state: Option<&EngineState>,
call: &Call,
options: Options,
) -> Result<Value, ShellError> {
Ok(match value {
Value::CustomValue { val, internal_span } => Value::record(
Value::CustomValue { val, .. } => Value::record(
record!(
"type" => Value::string("custom", head),
"subtype" => run(engine_state,call, val.to_base_value(internal_span)?.into_pipeline_data(), options)?.into_value(head),
"subtype" => Value::string(val.type_name(), head),
),
head,
),
@ -318,7 +311,6 @@ fn describe_value(
std::mem::take(v),
head,
engine_state,
call,
options,
)?);
}
@ -338,7 +330,7 @@ fn describe_value(
"length" => Value::int(vals.len() as i64, head),
"values" => Value::list(vals.into_iter().map(|v|
Ok(compact_primitive_description(
describe_value(v, head, engine_state, call, options)?
describe_value(v, head, engine_state, options)?
))
)
.collect::<Result<Vec<Value>, ShellError>>()?, head),
@ -406,7 +398,7 @@ fn describe_value(
if options.collect_lazyrecords {
let collected = val.collect()?;
if let Value::Record { mut val, .. } =
describe_value(collected, head, engine_state, call, options)?
describe_value(collected, head, engine_state, options)?
{
record.push("length", Value::int(val.len() as i64, head));
for (_k, v) in val.iter_mut() {
@ -414,7 +406,6 @@ fn describe_value(
std::mem::take(v),
head,
engine_state,
call,
options,
)?);
}