nushell/crates/nu-protocol/src/pipeline
Bahex 55de232a1c
refactor Value::follow_cell_path to reduce clones and return Cow (#15640)
# Description
While working on something else, I noticed that
`Value::follow_cell_path` receives `self`.

While it would be ideal for the signature to be `(&'a self, cell_path)
-> &'a Value`, that's not possible because:
1. Selecting a row from a list and field from a record can be done with
a reference but selecting a column from a table requires creating a new
list.
2. `Value::Custom` returns new `Value`s when indexed.

So the signature becomes `(&'a self, cell_path) -> Cow<'a, Value>`.

Another complication that arises is, once a new `Value` is created, and
it is further indexed, the `current` variable
1. can't be `&'a Value`, as the lifetime requirement means it can't
refer to local variables
2. _shouldn't_ be `Cow<'a, Value>`, as once it becomes an owned value,
it can't be borrowed ever again, as `current` is derived from its
previous value in further iterations. So once it's owned, it can't be
indexed by reference, leading to more clones

We need `current` to have _two_ possible lifetimes
1. `'out`: references derived from `&self`
2. `'local`: references derived from an owned value stored in a local
variable

```rust
enum MultiLife<'out, 'local, T>
where
    'out: 'local,
    T: ?Sized,
{
    Out(&'out T),
    Local(&'local T),
}
```
With `current: MultiLife<'out, '_, Value>`, we can traverse values with
minimal clones, and we can transform it to `Cow<'out, Value>` easily
(`MultiLife::Out -> Cow::Borrowed, MultiLife::Local -> Cow::Owned`) to
return it

# User-Facing Changes

# Tests + Formatting

# After Submitting

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
2025-05-01 09:43:57 -05:00
..
byte_stream.rs Enable nushell error with backtrace (#14945) 2025-02-06 22:05:58 +08:00
handlers.rs fix: relay Signals reset to plugins (#13510) 2024-08-06 03:35:40 -07:00
list_stream.rs Enable nushell error with backtrace (#14945) 2025-02-06 22:05:58 +08:00
metadata.rs Make pipeline metadata available to plugins (#13495) 2024-08-02 11:01:20 -07:00
mod.rs fix: relay Signals reset to plugins (#13510) 2024-08-06 03:35:40 -07:00
out_dest.rs Fix try printing when it is not the last pipeline element (#13992) 2024-10-12 14:37:10 +08:00
pipeline_data.rs refactor Value::follow_cell_path to reduce clones and return Cow (#15640) 2025-05-01 09:43:57 -05:00
signals.rs Remove nu-glob's dependency on nu-protocol (#15349) 2025-03-20 17:32:41 +01:00