Name the Value conversion functions more clearly (#11851)

# Description
This PR renames the conversion functions on `Value` to be more consistent.
It follows the Rust [API guidelines](https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv) for ad-hoc conversions.
The conversion functions on `Value` now come in a few forms:
- `coerce_{type}` takes a `&Value` and attempts to convert the value to
`type` (e.g., `i64` are converted to `f64`). This is the old behavior of
some of the `as_{type}` functions -- these functions have simply been
renamed to better reflect what they do.
- The new `as_{type}` functions take a `&Value` and returns an `Ok`
result only if the value is of `type` (no conversion is attempted). The
returned value will be borrowed if `type` is non-`Copy`, otherwise an
owned value is returned.
- `into_{type}` exists for non-`Copy` types, but otherwise does not
attempt conversion just like `as_type`. It takes an owned `Value` and
always returns an owned result.
- `coerce_into_{type}` has the same relationship with `coerce_{type}` as
`into_{type}` does with `as_{type}`.
- `to_{kind}_string`: conversion to different string formats (debug,
abbreviated, etc.). Only two of the old string conversion functions were
removed, the rest have been renamed only.
- `to_{type}`: other conversion functions. Currently, only `to_path`
exists. (And `to_string` through `Display`.)

This table summaries the above:
| Form | Cost | Input Ownership | Output Ownership | Converts `Value`
case/`type` |
| ---------------------------- | ----- | --------------- |
---------------- | -------- |
| `as_{type}` | Cheap | Borrowed | Borrowed/Owned | No |
| `into_{type}` | Cheap | Owned | Owned | No |
| `coerce_{type}` | Cheap | Borrowed | Borrowed/Owned | Yes |
| `coerce_into_{type}` | Cheap | Owned | Owned | Yes |
| `to_{kind}_string` | Expensive | Borrowed | Owned | Yes |
| `to_{type}` | Expensive | Borrowed | Owned | Yes |

# User-Facing Changes
Breaking API change for `Value` in `nu-protocol` which is exposed as
part of the plugin API.
This commit is contained in:
Ian Manske
2024-02-17 18:14:16 +00:00
committed by GitHub
parent 360ebeb0bc
commit 1c49ca503a
117 changed files with 903 additions and 745 deletions

View File

@ -51,7 +51,7 @@ fn nu_highlight_string(code_string: &str, engine_state: &EngineState, stack: &mu
Value::string(code_string, Span::unknown()).into_pipeline_data(),
) {
let result = output.into_value(Span::unknown());
if let Ok(s) = result.as_string() {
if let Ok(s) = result.coerce_into_string() {
return s; // successfully highlighted string
}
}
@ -139,7 +139,7 @@ fn get_documentation(
if !sig.named.is_empty() {
long_desc.push_str(&get_flags_section(Some(engine_state), sig, |v| {
nu_highlight_string(
&v.into_string_parsable(", ", &engine_state.config),
&v.to_parsable_string(", ", &engine_state.config),
engine_state,
stack,
)
@ -187,7 +187,7 @@ fn get_documentation(
format!(
" (optional, default: {})",
nu_highlight_string(
&value.into_string_parsable(", ", &engine_state.config),
&value.to_parsable_string(", ", &engine_state.config),
engine_state,
stack
)
@ -280,7 +280,7 @@ fn get_documentation(
) {
Ok(output) => {
let result = output.into_value(Span::unknown());
match result.as_string() {
match result.coerce_into_string() {
Ok(s) => {
let _ = write!(long_desc, "\n > {s}\n");
}
@ -316,7 +316,7 @@ fn get_documentation(
let _ = writeln!(
long_desc,
" {}",
item.into_string("", engine_state.get_config())
item.to_expanded_string("", engine_state.get_config())
.replace('\n', "\n ")
.trim()
);
@ -390,7 +390,7 @@ fn get_argument_for_color_value(
},
Expression {
expr: Expr::String(
v.clone().into_string("", engine_state.get_config()),
v.clone().to_expanded_string("", engine_state.get_config()),
),
span,
ty: Type::String,

View File

@ -98,10 +98,10 @@ pub fn env_to_string(
stack: &Stack,
) -> Result<String, ShellError> {
match get_converted_value(engine_state, stack, env_name, value, "to_string") {
ConversionResult::Ok(v) => Ok(v.as_string()?),
ConversionResult::Ok(v) => Ok(v.coerce_into_string()?),
ConversionResult::ConversionError(e) => Err(e),
ConversionResult::GeneralError(e) => Err(e),
ConversionResult::CellPathError => match value.as_string() {
ConversionResult::CellPathError => match value.coerce_string() {
Ok(s) => Ok(s),
Err(_) => {
if env_name == ENV_PATH_NAME {
@ -110,7 +110,7 @@ pub fn env_to_string(
Value::List { vals, .. } => {
let paths = vals
.iter()
.map(|v| v.as_string())
.map(|v| v.coerce_string())
.collect::<Result<Vec<_>, _>>()?;
match std::env::join_paths(paths) {
@ -333,7 +333,7 @@ pub fn find_in_dirs_env(
.ok()?
.iter()
.map(|lib_dir| -> Option<PathBuf> {
let dir = lib_dir.as_path().ok()?;
let dir = lib_dir.to_path().ok()?;
let dir_abs = canonicalize_with(dir, &cwd).ok()?;
canonicalize_with(filename, dir_abs).ok()
})