From 16c8c6cd7db312a892ff30772befb997c9594967 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 17:35:33 -0400 Subject: [PATCH 01/12] Use `ecow::EcowVec` in `Record` --- Cargo.lock | 12 +++++++++++- crates/nu-protocol/Cargo.toml | 1 + crates/nu-protocol/src/value/mod.rs | 2 +- crates/nu-protocol/src/value/record.rs | 27 +++++++++++++------------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 865c4bd112..369b489c17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -398,7 +398,7 @@ dependencies = [ "bitflags 2.5.0", "cexpr", "clang-sys", - "itertools 0.11.0", + "itertools 0.12.1", "lazy_static", "lazycell", "proc-macro2", @@ -1348,6 +1348,15 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ecow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54bfbb1708988623190a6c4dbedaeaf0f53c20c6395abd6a01feb327b3146f4b" +dependencies = [ + "serde", +] + [[package]] name = "ego-tree" version = "0.6.2" @@ -3300,6 +3309,7 @@ dependencies = [ "byte-unit", "chrono", "chrono-humanize", + "ecow", "fancy-regex", "indexmap", "lru", diff --git a/crates/nu-protocol/Cargo.toml b/crates/nu-protocol/Cargo.toml index a491a38e74..d51b34a622 100644 --- a/crates/nu-protocol/Cargo.toml +++ b/crates/nu-protocol/Cargo.toml @@ -31,6 +31,7 @@ serde = { workspace = true, default-features = false } serde_json = { workspace = true, optional = true } thiserror = "1.0" typetag = "0.2" +ecow = { version = "0.2.2", features = ["serde"] } [features] plugin = [ diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 29319ae8f2..cf142856ba 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -110,7 +110,7 @@ pub enum Value { internal_span: Span, }, Record { - val: SharedCow, + val: Record, // note: spans are being refactored out of Value // please use .span() instead of matching this span value #[serde(rename = "span")] diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index 8b61e61f7f..0f8aedbf9d 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -1,12 +1,11 @@ -use std::{iter::FusedIterator, ops::RangeBounds}; - use crate::{ShellError, Span, Value}; - +use ecow::EcoVec; use serde::{de::Visitor, ser::SerializeMap, Deserialize, Serialize}; +use std::{iter::FusedIterator, ops::RangeBounds}; #[derive(Debug, Clone, Default)] pub struct Record { - inner: Vec<(String, Value)>, + inner: EcoVec<(String, Value)>, } impl Record { @@ -16,7 +15,7 @@ impl Record { pub fn with_capacity(capacity: usize) -> Self { Self { - inner: Vec::with_capacity(capacity), + inner: EcoVec::with_capacity(capacity), } } @@ -139,7 +138,7 @@ impl Record { where F: FnMut(&str, &Value) -> bool, { - self.retain_mut(|k, v| keep(k, v)); + self.inner.retain(|(k, v)| keep(k, v)) } /// Remove elements in-place that do not satisfy `keep` while allowing mutation of the value. @@ -183,7 +182,8 @@ impl Record { where F: FnMut(&str, &mut Value) -> bool, { - self.inner.retain_mut(|(col, val)| keep(col, val)); + todo!() + // self.inner.retain_mut(|(col, val)| keep(col, val)); } /// Truncate record to the first `len` elements. @@ -259,9 +259,10 @@ impl Record { where R: RangeBounds + Clone, { - Drain { - iter: self.inner.drain(range), - } + todo!() + // Drain { + // iter: self.inner.drain(range), + // } } /// Sort the record by its columns. @@ -382,7 +383,7 @@ impl Extend<(String, Value)> for Record { } pub struct IntoIter { - iter: std::vec::IntoIter<(String, Value)>, + iter: ecow::vec::IntoIter<(String, Value)>, } impl Iterator for IntoIter { @@ -538,7 +539,7 @@ impl<'a> ExactSizeIterator for Columns<'a> { impl FusedIterator for Columns<'_> {} pub struct IntoColumns { - iter: std::vec::IntoIter<(String, Value)>, + iter: ecow::vec::IntoIter<(String, Value)>, } impl Iterator for IntoColumns { @@ -598,7 +599,7 @@ impl<'a> ExactSizeIterator for Values<'a> { impl FusedIterator for Values<'_> {} pub struct IntoValues { - iter: std::vec::IntoIter<(String, Value)>, + iter: ecow::vec::IntoIter<(String, Value)>, } impl Iterator for IntoValues { From 7e38cc0363c7995874b0e6a48cbcb7e8e7f28fd3 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 17:50:31 -0400 Subject: [PATCH 02/12] Fix compile errors --- crates/nu-cmd-base/src/hook.rs | 2 +- .../src/extra/filters/roll/mod.rs | 2 +- .../nu-cmd-extra/src/extra/filters/rotate.rs | 2 +- .../src/extra/filters/update_cells.rs | 1 - .../nu-cmd-lang/src/core_commands/describe.rs | 5 +- crates/nu-cmd-lang/src/example_support.rs | 2 +- .../nu-command/src/conversions/into/value.rs | 3 +- .../nu-command/src/database/values/sqlite.rs | 2 +- crates/nu-command/src/debug/inspect_table.rs | 2 +- crates/nu-command/src/env/load_env.rs | 2 +- crates/nu-command/src/env/with_env.rs | 4 +- crates/nu-command/src/filters/columns.rs | 1 - crates/nu-command/src/filters/default.rs | 4 +- crates/nu-command/src/filters/drop/column.rs | 6 +- crates/nu-command/src/filters/flatten.rs | 4 +- crates/nu-command/src/filters/headers.rs | 1 - crates/nu-command/src/filters/items.rs | 1 - crates/nu-command/src/filters/rename.rs | 7 +-- crates/nu-command/src/filters/sort.rs | 9 +-- crates/nu-command/src/filters/split_by.rs | 4 +- crates/nu-command/src/filters/uniq.rs | 1 - crates/nu-command/src/filters/values.rs | 3 +- crates/nu-command/src/formats/to/json.rs | 2 +- crates/nu-command/src/formats/to/text.rs | 1 - crates/nu-command/src/formats/to/toml.rs | 2 +- crates/nu-command/src/formats/to/xml.rs | 2 +- crates/nu-command/src/formats/to/yaml.rs | 2 +- crates/nu-command/src/generators/generate.rs | 2 +- crates/nu-command/src/help/help_.rs | 2 +- crates/nu-command/src/math/utils.rs | 10 ++-- crates/nu-command/src/network/http/client.rs | 6 +- .../nu-command/src/network/url/build_query.rs | 2 +- crates/nu-command/src/network/url/join.rs | 2 - crates/nu-command/src/viewers/griddle.rs | 2 +- crates/nu-command/src/viewers/table.rs | 6 +- crates/nu-engine/src/documentation.rs | 2 +- crates/nu-explore/src/nu_common/value.rs | 2 +- crates/nu-explore/src/pager/mod.rs | 2 +- .../nu-plugin-test-support/src/plugin_test.rs | 4 +- crates/nu-protocol/src/config/hooks.rs | 2 +- crates/nu-protocol/src/config/mod.rs | 22 +++---- crates/nu-protocol/src/config/plugin_gc.rs | 6 +- .../nu-protocol/src/engine/pattern_match.rs | 2 +- crates/nu-protocol/src/eval_base.rs | 2 +- crates/nu-protocol/src/value/from_value.rs | 2 +- crates/nu-protocol/src/value/mod.rs | 57 +++++++++---------- crates/nu-protocol/src/value/record.rs | 5 +- crates/nu-table/src/types/collapse.rs | 26 ++++----- crates/nu-table/src/unstructured_table.rs | 5 +- .../src/dataframe/values/nu_dataframe/mod.rs | 8 +-- crates/nuon/src/to.rs | 2 +- 51 files changed, 114 insertions(+), 144 deletions(-) diff --git a/crates/nu-cmd-base/src/hook.rs b/crates/nu-cmd-base/src/hook.rs index 76c13bd5c3..102a7a383f 100644 --- a/crates/nu-cmd-base/src/hook.rs +++ b/crates/nu-cmd-base/src/hook.rs @@ -18,7 +18,7 @@ pub fn eval_env_change_hook( if let Some(hook) = env_change_hook { match hook { Value::Record { val, .. } => { - for (env_name, hook_value) in &*val { + for (env_name, hook_value) in &val { let before = engine_state .previous_env_vars .get(env_name) diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs b/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs index 77c668167a..446200e0b8 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs @@ -58,7 +58,7 @@ fn horizontal_rotate_value( Value::Record { val: record, .. } => { let rotations = by.map(|n| n % record.len()).unwrap_or(1); - let (mut cols, mut vals): (Vec<_>, Vec<_>) = record.into_owned().into_iter().unzip(); + let (mut cols, mut vals): (Vec<_>, Vec<_>) = record.into_iter().unzip(); if !cells_only { match direction { HorizontalDirection::Right => cols.rotate_right(rotations), diff --git a/crates/nu-cmd-extra/src/extra/filters/rotate.rs b/crates/nu-cmd-extra/src/extra/filters/rotate.rs index ba393f45ef..f3988bcadb 100644 --- a/crates/nu-cmd-extra/src/extra/filters/rotate.rs +++ b/crates/nu-cmd-extra/src/extra/filters/rotate.rs @@ -171,7 +171,7 @@ pub fn rotate( let span = val.span(); match val { Value::Record { val: record, .. } => { - let (cols, vals): (Vec<_>, Vec<_>) = record.into_owned().into_iter().unzip(); + let (cols, vals): (Vec<_>, Vec<_>) = record.into_iter().unzip(); old_column_names = cols; new_values.extend_from_slice(&vals); } diff --git a/crates/nu-cmd-extra/src/extra/filters/update_cells.rs b/crates/nu-cmd-extra/src/extra/filters/update_cells.rs index 7cc43678ce..32176976dc 100644 --- a/crates/nu-cmd-extra/src/extra/filters/update_cells.rs +++ b/crates/nu-cmd-extra/src/extra/filters/update_cells.rs @@ -127,7 +127,6 @@ impl Iterator for UpdateCellIterator { let mut value = self.iter.next()?; let value = if let Value::Record { val, .. } = &mut value { - let val = val.to_mut(); if let Some(columns) = &self.columns { for (col, val) in val.iter_mut() { if columns.contains(col) { diff --git a/crates/nu-cmd-lang/src/core_commands/describe.rs b/crates/nu-cmd-lang/src/core_commands/describe.rs index 35bb3e2ae4..968be74ab7 100644 --- a/crates/nu-cmd-lang/src/core_commands/describe.rs +++ b/crates/nu-cmd-lang/src/core_commands/describe.rs @@ -264,7 +264,7 @@ fn compact_primitive_description(mut value: Value) -> Value { if val.len() != 1 { return value; } - if let Some(type_name) = val.to_mut().get_mut("type") { + if let Some(type_name) = val.get_mut("type") { return std::mem::take(type_name); } } @@ -300,8 +300,7 @@ fn describe_value( ), head, ), - Value::Record { val, .. } => { - let mut val = val.into_owned(); + Value::Record { mut val, .. } => { for (_k, v) in val.iter_mut() { *v = compact_primitive_description(describe_value( std::mem::take(v), diff --git a/crates/nu-cmd-lang/src/example_support.rs b/crates/nu-cmd-lang/src/example_support.rs index 5b9b0b3a07..0732cbf662 100644 --- a/crates/nu-cmd-lang/src/example_support.rs +++ b/crates/nu-cmd-lang/src/example_support.rs @@ -269,7 +269,7 @@ impl<'a> std::fmt::Debug for DebuggableValue<'a> { Value::Record { val, .. } => { write!(f, "{{")?; let mut first = true; - for (col, value) in (&**val).into_iter() { + for (col, value) in val { if !first { write!(f, ", ")?; } diff --git a/crates/nu-command/src/conversions/into/value.rs b/crates/nu-command/src/conversions/into/value.rs index e19ecf3c0c..9c3cda77a2 100644 --- a/crates/nu-command/src/conversions/into/value.rs +++ b/crates/nu-command/src/conversions/into/value.rs @@ -108,8 +108,7 @@ impl Iterator for UpdateCellIterator { let span = val.span(); match val { Value::Record { val, .. } => Some(Value::record( - val.into_owned() - .into_iter() + val.into_iter() .map(|(col, val)| match &self.columns { Some(cols) if !cols.contains(&col) => (col, val), _ => ( diff --git a/crates/nu-command/src/database/values/sqlite.rs b/crates/nu-command/src/database/values/sqlite.rs index 9778f44993..a581d7dfc3 100644 --- a/crates/nu-command/src/database/values/sqlite.rs +++ b/crates/nu-command/src/database/values/sqlite.rs @@ -500,7 +500,7 @@ pub fn nu_value_to_params(value: Value) -> Result { Value::Record { val, .. } => { let mut params = Vec::with_capacity(val.len()); - for (mut column, value) in val.into_owned().into_iter() { + for (mut column, value) in val { let sql_type_erased = value_to_sql(value)?; if !column.starts_with([':', '@', '$']) { diff --git a/crates/nu-command/src/debug/inspect_table.rs b/crates/nu-command/src/debug/inspect_table.rs index c7d5a87d9e..d2a112c70e 100644 --- a/crates/nu-command/src/debug/inspect_table.rs +++ b/crates/nu-command/src/debug/inspect_table.rs @@ -199,7 +199,7 @@ mod util { let span = value.span(); match value { Value::Record { val: record, .. } => { - let (cols, vals): (Vec<_>, Vec<_>) = record.into_owned().into_iter().unzip(); + let (cols, vals): (Vec<_>, Vec<_>) = record.into_iter().unzip(); ( cols, vec![vals diff --git a/crates/nu-command/src/env/load_env.rs b/crates/nu-command/src/env/load_env.rs index a8a4fe1c47..d9706adb1a 100644 --- a/crates/nu-command/src/env/load_env.rs +++ b/crates/nu-command/src/env/load_env.rs @@ -40,7 +40,7 @@ impl Command for LoadEnv { let record = match arg { Some(record) => record, None => match input { - PipelineData::Value(Value::Record { val, .. }, ..) => val.into_owned(), + PipelineData::Value(Value::Record { val, .. }, ..) => val, _ => { return Err(ShellError::UnsupportedInput { msg: "'load-env' expects a single record".into(), diff --git a/crates/nu-command/src/env/with_env.rs b/crates/nu-command/src/env/with_env.rs index 7eaf64cb54..bfd7c89130 100644 --- a/crates/nu-command/src/env/with_env.rs +++ b/crates/nu-command/src/env/with_env.rs @@ -82,7 +82,7 @@ fn with_env( // single row([[X W]; [Y Z]]) match &table[0] { Value::Record { val, .. } => { - for (k, v) in &**val { + for (k, v) in val { env.insert(k.to_string(), v.clone()); } } @@ -116,7 +116,7 @@ fn with_env( } // when get object by `open x.json` or `from json` Value::Record { val, .. } => { - for (k, v) in &**val { + for (k, v) in val { env.insert(k.clone(), v.clone()); } } diff --git a/crates/nu-command/src/filters/columns.rs b/crates/nu-command/src/filters/columns.rs index 394370a644..6d0535bad1 100644 --- a/crates/nu-command/src/filters/columns.rs +++ b/crates/nu-command/src/filters/columns.rs @@ -118,7 +118,6 @@ fn getcol( }) } Value::Record { val, .. } => Ok(val - .into_owned() .into_iter() .map(move |(x, _)| Value::string(x, head)) .into_pipeline_data(ctrlc) diff --git a/crates/nu-command/src/filters/default.rs b/crates/nu-command/src/filters/default.rs index 3eaa8d342e..02b9b0f85b 100644 --- a/crates/nu-command/src/filters/default.rs +++ b/crates/nu-command/src/filters/default.rs @@ -92,7 +92,7 @@ fn default( } => { let mut found = false; - for (col, val) in record.to_mut().iter_mut() { + for (col, val) in record.iter_mut() { if *col == column.item { found = true; if matches!(val, Value::Nothing { .. }) { @@ -102,7 +102,7 @@ fn default( } if !found { - record.to_mut().push(column.item.clone(), value.clone()); + record.push(column.item.clone(), value.clone()); } item diff --git a/crates/nu-command/src/filters/drop/column.rs b/crates/nu-command/src/filters/drop/column.rs index a19190cbd6..80f55bbe13 100644 --- a/crates/nu-command/src/filters/drop/column.rs +++ b/crates/nu-command/src/filters/drop/column.rs @@ -123,7 +123,7 @@ fn drop_cols( .. } => { let len = record.len().saturating_sub(columns); - record.to_mut().truncate(len); + record.truncate(len); Ok(v.into_pipeline_data_with_metadata(metadata)) } // Propagate errors @@ -144,7 +144,7 @@ fn drop_cols( fn drop_cols_set(val: &mut Value, head: Span, drop: usize) -> Result, ShellError> { if let Value::Record { val: record, .. } = val { let len = record.len().saturating_sub(drop); - Ok(record.to_mut().drain(len..).map(|(col, _)| col).collect()) + Ok(record.drain(len..).map(|(col, _)| col).collect()) } else { Err(unsupported_value_error(val, head)) } @@ -156,7 +156,7 @@ fn drop_record_cols( drop_cols: &HashSet, ) -> Result<(), ShellError> { if let Value::Record { val, .. } = val { - val.to_mut().retain(|col, _| !drop_cols.contains(col)); + val.retain(|col, _| !drop_cols.contains(col)); Ok(()) } else { Err(unsupported_value_error(val, head)) diff --git a/crates/nu-command/src/filters/flatten.rs b/crates/nu-command/src/filters/flatten.rs index 073e84368d..84e235a2b6 100644 --- a/crates/nu-command/src/filters/flatten.rs +++ b/crates/nu-command/src/filters/flatten.rs @@ -156,7 +156,7 @@ fn flat_value(columns: &[CellPath], item: Value, all: bool) -> Vec { let mut out = IndexMap::::new(); let mut inner_table = None; - for (column_index, (column, value)) in val.into_owned().into_iter().enumerate() { + for (column_index, (column, value)) in val.into_iter().enumerate() { let column_requested = columns.iter().find(|c| c.to_string() == column); let need_flatten = { columns.is_empty() || column_requested.is_some() }; let span = value.span(); @@ -164,7 +164,7 @@ fn flat_value(columns: &[CellPath], item: Value, all: bool) -> Vec { match value { Value::Record { ref val, .. } => { if need_flatten { - for (col, val) in val.clone().into_owned() { + for (col, val) in val.clone() { if out.contains_key(&col) { out.insert(format!("{column}_{col}"), val); } else { diff --git a/crates/nu-command/src/filters/headers.rs b/crates/nu-command/src/filters/headers.rs index f84f49b4be..0e34977014 100644 --- a/crates/nu-command/src/filters/headers.rs +++ b/crates/nu-command/src/filters/headers.rs @@ -149,7 +149,6 @@ fn replace_headers( if let Value::Record { val: record, .. } = value { Ok(Value::record( record - .into_owned() .into_iter() .filter_map(|(col, val)| { old_headers diff --git a/crates/nu-command/src/filters/items.rs b/crates/nu-command/src/filters/items.rs index 38d8305a41..4f586fb2c4 100644 --- a/crates/nu-command/src/filters/items.rs +++ b/crates/nu-command/src/filters/items.rs @@ -55,7 +55,6 @@ impl Command for Items { Value::Record { val, .. } => { let mut closure = ClosureEval::new(engine_state, stack, closure); Ok(val - .into_owned() .into_iter() .map_while(move |(col, val)| { let result = closure diff --git a/crates/nu-command/src/filters/rename.rs b/crates/nu-command/src/filters/rename.rs index 53920a95d0..dc9ac85e49 100644 --- a/crates/nu-command/src/filters/rename.rs +++ b/crates/nu-command/src/filters/rename.rs @@ -148,8 +148,7 @@ fn rename( Value::Record { val: record, .. } => { let record = if let Some(closure) = &mut closure { - record - .into_owned().into_iter() + record.into_iter() .map(|(col, val)| { let col = Value::string(col, span); let data = closure.run_with_value(col)?; @@ -163,7 +162,7 @@ fn rename( // record columns are unique so we can track the number // of renamed columns to check if any were missed let mut renamed = 0; - let record = record.into_owned().into_iter().map(|(col, val)| { + let record = record.into_iter().map(|(col, val)| { let col = if let Some(col) = columns.get(&col) { renamed += 1; col.clone() @@ -194,7 +193,7 @@ fn rename( } } None => Ok(record - .into_owned().into_iter() + .into_iter() .enumerate() .map(|(i, (col, val))| { (columns.get(i).cloned().unwrap_or(col), val) diff --git a/crates/nu-command/src/filters/sort.rs b/crates/nu-command/src/filters/sort.rs index 451f4bdcef..8e9ee3f4f2 100644 --- a/crates/nu-command/src/filters/sort.rs +++ b/crates/nu-command/src/filters/sort.rs @@ -144,14 +144,7 @@ impl Command for Sort { // Records have two sorting methods, toggled by presence or absence of -v PipelineData::Value(Value::Record { val, .. }, ..) => { let sort_by_value = call.has_flag(engine_state, stack, "values")?; - let record = sort_record( - val.into_owned(), - span, - sort_by_value, - reverse, - insensitive, - natural, - ); + let record = sort_record(val, span, sort_by_value, reverse, insensitive, natural); Ok(record.into_pipeline_data()) } // Other values are sorted here diff --git a/crates/nu-command/src/filters/split_by.rs b/crates/nu-command/src/filters/split_by.rs index 349c7ec49b..6ff55145a0 100644 --- a/crates/nu-command/src/filters/split_by.rs +++ b/crates/nu-command/src/filters/split_by.rs @@ -187,11 +187,11 @@ pub fn data_split( let span = v.span(); match v { Value::Record { val: grouped, .. } => { - for (outer_key, list) in grouped.into_owned() { + for (outer_key, list) in grouped { match data_group(&list, splitter, span) { Ok(grouped_vals) => { if let Value::Record { val: sub, .. } = grouped_vals { - for (inner_key, subset) in sub.into_owned() { + for (inner_key, subset) in sub { let s: &mut IndexMap = splits.entry(inner_key).or_default(); diff --git a/crates/nu-command/src/filters/uniq.rs b/crates/nu-command/src/filters/uniq.rs index 7d71d868f0..0a58a829d7 100644 --- a/crates/nu-command/src/filters/uniq.rs +++ b/crates/nu-command/src/filters/uniq.rs @@ -194,7 +194,6 @@ fn sort_attributes(val: Value) -> Value { Value::Record { val, .. } => { // TODO: sort inplace let sorted = val - .into_owned() .into_iter() .sorted_by(|a, b| a.0.cmp(&b.0)) .collect_vec(); diff --git a/crates/nu-command/src/filters/values.rs b/crates/nu-command/src/filters/values.rs index 691e260163..1803f01bac 100644 --- a/crates/nu-command/src/filters/values.rs +++ b/crates/nu-command/src/filters/values.rs @@ -106,7 +106,7 @@ pub fn get_values<'a>( for item in input { match item { Value::Record { val, .. } => { - for (k, v) in &**val { + for (k, v) in val { if let Some(vec) = output.get_mut(k) { vec.push(v.clone()); } else { @@ -171,7 +171,6 @@ fn values( })?, }; Ok(record - .into_owned() .into_values() .into_pipeline_data_with_metadata(metadata, ctrlc)) } diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index c48daad085..820761ee09 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -130,7 +130,7 @@ pub fn value_to_json_value(v: &Value) -> Result { } Value::Record { val, .. } => { let mut m = nu_json::Map::new(); - for (k, v) in &**val { + for (k, v) in val { m.insert(k.clone(), value_to_json_value(v)?); } nu_json::Value::Object(m) diff --git a/crates/nu-command/src/formats/to/text.rs b/crates/nu-command/src/formats/to/text.rs index 362786f1c0..bfa12a128c 100644 --- a/crates/nu-command/src/formats/to/text.rs +++ b/crates/nu-command/src/formats/to/text.rs @@ -125,7 +125,6 @@ fn local_into_string(value: Value, separator: &str, config: &Config) -> String { .collect::>() .join(separator), Value::Record { val, .. } => val - .into_owned() .into_iter() .map(|(x, y)| format!("{}: {}", x, local_into_string(y, ", ", config))) .collect::>() diff --git a/crates/nu-command/src/formats/to/toml.rs b/crates/nu-command/src/formats/to/toml.rs index 497297885d..23973d08de 100644 --- a/crates/nu-command/src/formats/to/toml.rs +++ b/crates/nu-command/src/formats/to/toml.rs @@ -57,7 +57,7 @@ fn helper(engine_state: &EngineState, v: &Value) -> Result toml::Value::String(val.clone()), Value::Record { val, .. } => { let mut m = toml::map::Map::new(); - for (k, v) in &**val { + for (k, v) in val { m.insert(k.clone(), helper(engine_state, v)?); } toml::Value::Table(m) diff --git a/crates/nu-command/src/formats/to/xml.rs b/crates/nu-command/src/formats/to/xml.rs index f93bc94d28..32e9ef4732 100644 --- a/crates/nu-command/src/formats/to/xml.rs +++ b/crates/nu-command/src/formats/to/xml.rs @@ -325,7 +325,7 @@ impl Job { // alternatives like {tag: a attributes: {} content: []}, {tag: a attribbutes: null // content: null}, {tag: a}. See to_xml_entry for more let attrs = match attrs { - Value::Record { val, .. } => val.into_owned(), + Value::Record { val, .. } => val, Value::Nothing { .. } => Record::new(), _ => { return Err(ShellError::CantConvert { diff --git a/crates/nu-command/src/formats/to/yaml.rs b/crates/nu-command/src/formats/to/yaml.rs index d8cdaac725..b9a7368722 100644 --- a/crates/nu-command/src/formats/to/yaml.rs +++ b/crates/nu-command/src/formats/to/yaml.rs @@ -54,7 +54,7 @@ pub fn value_to_yaml_value(v: &Value) -> Result { } Value::Record { val, .. } => { let mut m = serde_yaml::Mapping::new(); - for (k, v) in &**val { + for (k, v) in val { m.insert( serde_yaml::Value::String(k.clone()), value_to_yaml_value(v)?, diff --git a/crates/nu-command/src/generators/generate.rs b/crates/nu-command/src/generators/generate.rs index 96343fd093..aecf807f43 100644 --- a/crates/nu-command/src/generators/generate.rs +++ b/crates/nu-command/src/generators/generate.rs @@ -112,7 +112,7 @@ used as the next argument to the closure, otherwise generation stops. match value { // {out: ..., next: ...} -> output and continue Value::Record { val, .. } => { - let iter = val.into_owned().into_iter(); + let iter = val.into_iter(); let mut out = None; let mut next = None; let mut err = None; diff --git a/crates/nu-command/src/help/help_.rs b/crates/nu-command/src/help/help_.rs index 730afae267..13d3bb04cb 100644 --- a/crates/nu-command/src/help/help_.rs +++ b/crates/nu-command/src/help/help_.rs @@ -152,7 +152,7 @@ pub fn highlight_search_in_table( }); }; - let has_match = record.to_mut().iter_mut().try_fold( + let has_match = record.iter_mut().try_fold( false, |acc: bool, (col, val)| -> Result { if !searched_cols.contains(&col.as_str()) { diff --git a/crates/nu-command/src/math/utils.rs b/crates/nu-command/src/math/utils.rs index 9abcce06e9..8a19a96fc6 100644 --- a/crates/nu-command/src/math/utils.rs +++ b/crates/nu-command/src/math/utils.rs @@ -27,7 +27,7 @@ fn helper_for_tables( for val in values { match val { Value::Record { val, .. } => { - for (key, value) in &**val { + for (key, value) in val { column_values .entry(key.clone()) .and_modify(|v: &mut Vec| v.push(value.clone())) @@ -80,15 +80,13 @@ pub fn calculate( ), _ => mf(vals, span, name), }, - PipelineData::Value(Value::Record { val, .. }, ..) => { - let mut record = val.into_owned(); - record - .iter_mut() + PipelineData::Value(Value::Record { mut val, .. }, ..) => { + val.iter_mut() .try_for_each(|(_, val)| -> Result<(), ShellError> { *val = mf(slice::from_ref(val), span, name)?; Ok(()) })?; - Ok(Value::record(record, span)) + Ok(Value::record(val, span)) } PipelineData::Value(Value::Range { val, .. }, ..) => { let new_vals: Result, ShellError> = val diff --git a/crates/nu-command/src/network/http/client.rs b/crates/nu-command/src/network/http/client.rs index dc5adbe0cd..91c8e947eb 100644 --- a/crates/nu-command/src/network/http/client.rs +++ b/crates/nu-command/src/network/http/client.rs @@ -222,7 +222,7 @@ pub fn send_request( Value::Record { val, .. } if body_type == BodyType::Form => { let mut data: Vec<(String, String)> = Vec::with_capacity(val.len()); - for (col, val) in val.into_owned() { + for (col, val) in val { data.push((col, val.coerce_into_string()?)) } @@ -336,7 +336,7 @@ pub fn request_add_custom_headers( match &headers { Value::Record { val, .. } => { - for (k, v) in &**val { + for (k, v) in val { custom_headers.insert(k.to_string(), v.clone()); } } @@ -346,7 +346,7 @@ pub fn request_add_custom_headers( // single row([key1 key2]; [val1 val2]) match &table[0] { Value::Record { val, .. } => { - for (k, v) in &**val { + for (k, v) in val { custom_headers.insert(k.to_string(), v.clone()); } } diff --git a/crates/nu-command/src/network/url/build_query.rs b/crates/nu-command/src/network/url/build_query.rs index 92b5057b60..27be1b2748 100644 --- a/crates/nu-command/src/network/url/build_query.rs +++ b/crates/nu-command/src/network/url/build_query.rs @@ -65,7 +65,7 @@ fn to_url(input: PipelineData, head: Span) -> Result { match value { Value::Record { ref val, .. } => { let mut row_vec = vec![]; - for (k, v) in &**val { + for (k, v) in val { match v.coerce_string() { Ok(s) => { row_vec.push((k.clone(), s)); diff --git a/crates/nu-command/src/network/url/join.rs b/crates/nu-command/src/network/url/join.rs index eaa157ff2e..4d73bcb00f 100644 --- a/crates/nu-command/src/network/url/join.rs +++ b/crates/nu-command/src/network/url/join.rs @@ -92,7 +92,6 @@ impl Command for SubCommand { match value { Value::Record { val, .. } => { let url_components = val - .into_owned() .into_iter() .try_fold(UrlComponents::new(), |url, (k, v)| { url.add_component(k, v, span, engine_state) @@ -180,7 +179,6 @@ impl UrlComponents { return match value { Value::Record { val, .. } => { let mut qs = val - .into_owned() .into_iter() .map(|(k, v)| match v.coerce_into_string() { Ok(val) => Ok(format!("{k}={val}")), diff --git a/crates/nu-command/src/viewers/griddle.rs b/crates/nu-command/src/viewers/griddle.rs index afeb6ee0c4..be4f4be49f 100644 --- a/crates/nu-command/src/viewers/griddle.rs +++ b/crates/nu-command/src/viewers/griddle.rs @@ -108,7 +108,7 @@ prints out the list properly."# // dbg!("value::record"); let mut items = vec![]; - for (i, (c, v)) in val.into_owned().into_iter().enumerate() { + for (i, (c, v)) in val.into_iter().enumerate() { items.push((i, c, v.to_expanded_string(", ", config))) } diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index b032637275..83dd912d64 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -392,7 +392,7 @@ fn handle_table_command( } PipelineData::Value(Value::Record { val, .. }, ..) => { input.data = PipelineData::Empty; - handle_record(input, cfg, val.into_owned()) + handle_record(input, cfg, val) } PipelineData::Value(Value::LazyRecord { val, .. }, ..) => { input.data = val.collect()?.into_pipeline_data(); @@ -557,7 +557,7 @@ fn handle_row_stream( stream.map(move |mut x| match &mut x { Value::Record { val: record, .. } => { // Only the name column gets special colors, for now - if let Some(value) = record.to_mut().get_mut("name") { + if let Some(value) = record.get_mut("name") { let span = value.span(); if let Value::String { val, .. } = value { if let Some(val) = render_path_name(val, &config, &ls_colors, span) @@ -583,7 +583,7 @@ fn handle_row_stream( ListStream::from_stream( stream.map(move |mut x| match &mut x { Value::Record { val: record, .. } => { - for (rec_col, rec_val) in record.to_mut().iter_mut() { + for (rec_col, rec_val) in record.iter_mut() { // Every column in the HTML theme table except 'name' is colored if rec_col != "name" { continue; diff --git a/crates/nu-engine/src/documentation.rs b/crates/nu-engine/src/documentation.rs index 463f8f10e7..8f8ef8f0e3 100644 --- a/crates/nu-engine/src/documentation.rs +++ b/crates/nu-engine/src/documentation.rs @@ -376,7 +376,7 @@ fn get_argument_for_color_value( ) -> Option { match color { Value::Record { val, .. } => { - let record_exp: Vec = (**val) + let record_exp: Vec = val .iter() .map(|(k, v)| { RecordItem::Pair( diff --git a/crates/nu-explore/src/nu_common/value.rs b/crates/nu-explore/src/nu_common/value.rs index 5c63c9e780..5f25a1131e 100644 --- a/crates/nu-explore/src/nu_common/value.rs +++ b/crates/nu-explore/src/nu_common/value.rs @@ -87,7 +87,7 @@ pub fn collect_input(value: Value) -> (Vec, Vec>) { let span = value.span(); match value { Value::Record { val: record, .. } => { - let (key, val) = record.into_owned().into_iter().unzip(); + let (key, val) = record.into_iter().unzip(); (key, vec![val]) } Value::List { vals, .. } => { diff --git a/crates/nu-explore/src/pager/mod.rs b/crates/nu-explore/src/pager/mod.rs index 67aac1f312..5e78dba14a 100644 --- a/crates/nu-explore/src/pager/mod.rs +++ b/crates/nu-explore/src/pager/mod.rs @@ -1038,7 +1038,7 @@ fn set_config(hm: &mut HashMap, path: &[&str], value: Value) -> b if path.len() == 2 { let key = path[1]; - record.to_mut().insert(key, value); + record.insert(key, value); } else { let mut hm2: HashMap = HashMap::new(); for (k, v) in record.iter() { diff --git a/crates/nu-plugin-test-support/src/plugin_test.rs b/crates/nu-plugin-test-support/src/plugin_test.rs index cc4650b4ae..3f9326a33b 100644 --- a/crates/nu-plugin-test-support/src/plugin_test.rs +++ b/crates/nu-plugin-test-support/src/plugin_test.rs @@ -319,8 +319,8 @@ impl PluginTest { // reorder cols and vals to make more logically compare. // more general, if two record have same col and values, // the order of cols shouldn't affect the equal property. - let mut a_rec = a_rec.clone().into_owned(); - let mut b_rec = b_rec.clone().into_owned(); + let mut a_rec = a_rec.clone(); + let mut b_rec = b_rec.clone(); a_rec.sort_cols(); b_rec.sort_cols(); diff --git a/crates/nu-protocol/src/config/hooks.rs b/crates/nu-protocol/src/config/hooks.rs index 88f5f4abf1..cabd0cb154 100644 --- a/crates/nu-protocol/src/config/hooks.rs +++ b/crates/nu-protocol/src/config/hooks.rs @@ -39,7 +39,7 @@ pub(super) fn create_hooks(value: &Value) -> Result { Value::Record { val, .. } => { let mut hooks = Hooks::new(); - for (col, val) in &**val { + for (col, val) in val { match col.as_str() { "pre_prompt" => hooks.pre_prompt = Some(val.clone()), "pre_execution" => hooks.pre_execution = Some(val.clone()), diff --git a/crates/nu-protocol/src/config/mod.rs b/crates/nu-protocol/src/config/mod.rs index 312676038c..37e77fea6a 100644 --- a/crates/nu-protocol/src/config/mod.rs +++ b/crates/nu-protocol/src/config/mod.rs @@ -202,13 +202,13 @@ impl Value { // the `2`. if let Value::Record { val, .. } = self { - val.to_mut().retain_mut(|key, value| { + val.retain_mut(|key, value| { let span = value.span(); match key { // Grouped options "ls" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "use_ls_colors" => { @@ -237,7 +237,7 @@ impl Value { } "rm" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "always_trash" => { @@ -264,7 +264,7 @@ impl Value { "history" => { let history = &mut config.history; if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "isolation" => { @@ -306,7 +306,7 @@ impl Value { } "completions" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "quick" => { @@ -327,7 +327,7 @@ impl Value { } "external" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key3, value| + val.retain_mut(|key3, value| { let span = value.span(); match key3 { @@ -394,7 +394,7 @@ impl Value { } "cursor_shape" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); let config_point = match key2 { "vi_insert" => &mut config.cursor_shape_vi_insert, @@ -427,7 +427,7 @@ impl Value { } "table" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "mode" => { @@ -452,7 +452,7 @@ impl Value { } Value::Record { val, .. } => { let mut invalid = false; - val.to_mut().retain(|key3, value| { + val.retain(|key3, value| { match key3 { "left" => { match value.as_int() { @@ -547,7 +547,7 @@ impl Value { } "filesize" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "metric" => { @@ -720,7 +720,7 @@ impl Value { }, "datetime_format" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| + val.retain_mut(|key2, value| { let span = value.span(); match key2 { diff --git a/crates/nu-protocol/src/config/plugin_gc.rs b/crates/nu-protocol/src/config/plugin_gc.rs index 70beeb6ae3..4d859299d2 100644 --- a/crates/nu-protocol/src/config/plugin_gc.rs +++ b/crates/nu-protocol/src/config/plugin_gc.rs @@ -39,7 +39,7 @@ impl PluginGcConfigs { self.plugins = HashMap::new(); } - val.to_mut().retain_mut(|key, value| { + val.retain_mut(|key, value| { let span = value.span(); match key { "default" => { @@ -88,7 +88,7 @@ fn process_plugins( // Remove any plugin configs that aren't in the value plugins.retain(|key, _| val.contains(key)); - val.to_mut().retain_mut(|key, value| { + val.retain_mut(|key, value| { if matches!(value, Value::Record { .. }) { plugins.entry(key.to_owned()).or_default().process( &join_path(path, &[key]), @@ -150,7 +150,7 @@ impl PluginGcConfig { self.stop_after = PluginGcConfig::default().stop_after; } - val.to_mut().retain_mut(|key, value| { + val.retain_mut(|key, value| { let span = value.span(); match key { "enabled" => process_bool_config(value, errors, &mut self.enabled), diff --git a/crates/nu-protocol/src/engine/pattern_match.rs b/crates/nu-protocol/src/engine/pattern_match.rs index e29779b633..8c1266c1b5 100644 --- a/crates/nu-protocol/src/engine/pattern_match.rs +++ b/crates/nu-protocol/src/engine/pattern_match.rs @@ -23,7 +23,7 @@ impl Matcher for Pattern { Pattern::Record(field_patterns) => match value { Value::Record { val, .. } => { 'top: for field_pattern in field_patterns { - for (col, val) in &**val { + for (col, val) in val { if col == &field_pattern.0 { // We have found the field let result = field_pattern.1.match_value(val, matches); diff --git a/crates/nu-protocol/src/eval_base.rs b/crates/nu-protocol/src/eval_base.rs index 9a11f0d537..d5c09b4112 100644 --- a/crates/nu-protocol/src/eval_base.rs +++ b/crates/nu-protocol/src/eval_base.rs @@ -75,7 +75,7 @@ pub trait Eval { RecordItem::Spread(_, inner) => { match Self::eval::(state, mut_state, inner)? { Value::Record { val: inner_val, .. } => { - for (col_name, val) in inner_val.into_owned() { + for (col_name, val) in inner_val { if let Some(orig_span) = col_names.get(&col_name) { return Err(ShellError::ColumnDefinedTwice { col_name, diff --git a/crates/nu-protocol/src/value/from_value.rs b/crates/nu-protocol/src/value/from_value.rs index 9fc9d4c8b6..f2f669fa4c 100644 --- a/crates/nu-protocol/src/value/from_value.rs +++ b/crates/nu-protocol/src/value/from_value.rs @@ -538,7 +538,7 @@ impl FromValue for Vec { impl FromValue for Record { fn from_value(v: Value) -> Result { match v { - Value::Record { val, .. } => Ok(val.into_owned()), + Value::Record { val, .. } => Ok(val), v => Err(ShellError::CantConvert { to_type: "Record".into(), from_type: v.get_type().to_string(), diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index cf142856ba..c345886b60 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -29,7 +29,7 @@ use fancy_regex::Regex; use nu_utils::{ contains_emoji, locale::{get_system_locale_string, LOCALE_OVERRIDE_ENV_VAR}, - IgnoreCaseExt, SharedCow, + IgnoreCaseExt, }; use serde::{Deserialize, Serialize}; use std::{ @@ -527,7 +527,7 @@ impl Value { /// Unwraps the inner [`Record`] value or returns an error if this `Value` is not a record pub fn into_record(self) -> Result { if let Value::Record { val, .. } = self { - Ok(val.into_owned()) + Ok(val) } else { self.cant_convert_to("record") } @@ -1112,7 +1112,7 @@ impl Value { match current { Value::Record { mut val, .. } => { // Make reverse iterate to avoid duplicate column leads to first value, actually last value is expected. - if let Some(found) = val.to_mut().iter_mut().rev().find(|x| { + if let Some(found) = val.iter_mut().rev().find(|x| { if insensitive { x.0.eq_ignore_case(column_name) } else { @@ -1173,15 +1173,13 @@ impl Value { let val_span = val.span(); match val { Value::Record { mut val, .. } => { - if let Some(found) = - val.to_mut().iter_mut().rev().find(|x| { - if insensitive { - x.0.eq_ignore_case(column_name) - } else { - x.0 == column_name - } - }) - { + if let Some(found) = val.iter_mut().rev().find(|x| { + if insensitive { + x.0.eq_ignore_case(column_name) + } else { + x.0 == column_name + } + }) { Ok(std::mem::take(found.1)) } else if *optional { Ok(Value::nothing(*origin_span)) @@ -1287,7 +1285,7 @@ impl Value { for val in vals.iter_mut() { match val { Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { val.upsert_data_at_cell_path(path, new_val.clone())?; } else { let new_col = if path.is_empty() { @@ -1299,7 +1297,7 @@ impl Value { .upsert_data_at_cell_path(path, new_val.clone())?; new_col }; - record.to_mut().push(col_name, new_col); + record.push(col_name, new_col); } } Value::Error { error, .. } => return Err(*error.clone()), @@ -1314,7 +1312,7 @@ impl Value { } } Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { val.upsert_data_at_cell_path(path, new_val)?; } else { let new_col = if path.is_empty() { @@ -1324,7 +1322,7 @@ impl Value { new_col.upsert_data_at_cell_path(path, new_val)?; new_col }; - record.to_mut().push(col_name, new_col); + record.push(col_name, new_col); } } Value::LazyRecord { val, .. } => { @@ -1411,7 +1409,7 @@ impl Value { let v_span = val.span(); match val { Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { val.update_data_at_cell_path(path, new_val.clone())?; } else { return Err(ShellError::CantFindColumn { @@ -1433,7 +1431,7 @@ impl Value { } } Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { val.update_data_at_cell_path(path, new_val)?; } else { return Err(ShellError::CantFindColumn { @@ -1503,7 +1501,7 @@ impl Value { let v_span = val.span(); match val { Value::Record { val: record, .. } => { - if record.to_mut().remove(col_name).is_none() && !optional { + if record.remove(col_name).is_none() && !optional { return Err(ShellError::CantFindColumn { col_name: col_name.clone(), span: *span, @@ -1523,7 +1521,7 @@ impl Value { Ok(()) } Value::Record { val: record, .. } => { - if record.to_mut().remove(col_name).is_none() && !optional { + if record.remove(col_name).is_none() && !optional { return Err(ShellError::CantFindColumn { col_name: col_name.clone(), span: *span, @@ -1583,7 +1581,7 @@ impl Value { let v_span = val.span(); match val { Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { val.remove_data_at_cell_path(path)?; } else if !optional { return Err(ShellError::CantFindColumn { @@ -1605,7 +1603,7 @@ impl Value { Ok(()) } Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { val.remove_data_at_cell_path(path)?; } else if !optional { return Err(ShellError::CantFindColumn { @@ -1675,7 +1673,7 @@ impl Value { let v_span = val.span(); match val { Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { if path.is_empty() { return Err(ShellError::ColumnAlreadyExists { col_name: col_name.clone(), @@ -1702,7 +1700,7 @@ impl Value { )?; new_col }; - record.to_mut().push(col_name, new_col); + record.push(col_name, new_col); } } Value::Error { error, .. } => return Err(*error.clone()), @@ -1718,7 +1716,7 @@ impl Value { } } Value::Record { val: record, .. } => { - if let Some(val) = record.to_mut().get_mut(col_name) { + if let Some(val) = record.get_mut(col_name) { if path.is_empty() { return Err(ShellError::ColumnAlreadyExists { col_name: col_name.clone(), @@ -1736,7 +1734,7 @@ impl Value { new_col.insert_data_at_cell_path(path, new_val, head_span)?; new_col }; - record.to_mut().push(col_name, new_col); + record.push(col_name, new_col); } } Value::LazyRecord { val, .. } => { @@ -1809,7 +1807,6 @@ impl Value { // Check for contained values match self { Value::Record { ref mut val, .. } => val - .to_mut() .iter_mut() .try_for_each(|(_, rec_value)| rec_value.recurse_mut(f)), Value::List { ref mut vals, .. } => vals @@ -1944,7 +1941,7 @@ impl Value { pub fn record(val: Record, span: Span) -> Value { Value::Record { - val: SharedCow::new(val), + val, internal_span: span, } } @@ -2364,8 +2361,8 @@ impl PartialOrd for Value { // reorder cols and vals to make more logically compare. // more general, if two record have same col and values, // the order of cols shouldn't affect the equal property. - let mut lhs = lhs.clone().into_owned(); - let mut rhs = rhs.clone().into_owned(); + let mut lhs = lhs.clone(); + let mut rhs = rhs.clone(); lhs.sort_cols(); rhs.sort_cols(); diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index 0f8aedbf9d..8e372fd480 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -98,6 +98,7 @@ impl Record { pub fn get_mut(&mut self, col: impl AsRef) -> Option<&mut Value> { self.inner + .make_mut() .iter_mut() .find_map(|(k, v)| if k == col.as_ref() { Some(v) } else { None }) } @@ -288,7 +289,7 @@ impl Record { /// ); /// ``` pub fn sort_cols(&mut self) { - self.inner.sort_by(|(k1, _), (k2, _)| k1.cmp(k2)) + self.inner.make_mut().sort_by(|(k1, _), (k2, _)| k1.cmp(k2)) } } @@ -503,7 +504,7 @@ impl<'a> IntoIterator for &'a mut Record { fn into_iter(self) -> Self::IntoIter { IterMut { - iter: self.inner.iter_mut(), + iter: self.inner.make_mut().iter_mut(), } } } diff --git a/crates/nu-table/src/types/collapse.rs b/crates/nu-table/src/types/collapse.rs index e25b7f1e79..d5bbf5f3bf 100644 --- a/crates/nu-table/src/types/collapse.rs +++ b/crates/nu-table/src/types/collapse.rs @@ -3,8 +3,7 @@ use crate::{ StringResult, TableOpts, UnstructuredTable, }; use nu_color_config::StyleComputer; -use nu_protocol::{Config, Record, TableMode, Value}; -use nu_utils::SharedCow; +use nu_protocol::{Config, TableMode, Value}; pub struct CollapsedTable; @@ -49,20 +48,17 @@ fn colorize_value(value: &mut Value, config: &Config, style_computer: &StyleComp // Take ownership of the record and reassign to &mut // We do this to have owned keys through `.into_iter` let record = std::mem::take(val); - *val = SharedCow::new( - record - .into_owned() - .into_iter() - .map(|(mut header, mut val)| { - colorize_value(&mut val, config, style_computer); + *val = record + .into_iter() + .map(|(mut header, mut val)| { + colorize_value(&mut val, config, style_computer); - if let Some(color) = style.color_style { - header = color.paint(header).to_string(); - } - (header, val) - }) - .collect::(), - ); + if let Some(color) = style.color_style { + header = color.paint(header).to_string(); + } + (header, val) + }) + .collect(); } Value::List { vals, .. } => { for val in vals { diff --git a/crates/nu-table/src/unstructured_table.rs b/crates/nu-table/src/unstructured_table.rs index 5ab0bec3f6..21753f795a 100644 --- a/crates/nu-table/src/unstructured_table.rs +++ b/crates/nu-table/src/unstructured_table.rs @@ -89,7 +89,7 @@ fn build_table( fn convert_nu_value_to_table_value(value: Value, config: &Config) -> TableValue { match value { - Value::Record { val, .. } => build_vertical_map(val.into_owned(), config), + Value::Record { val, .. } => build_vertical_map(val, config), Value::List { vals, .. } => { let rebuild_array_as_map = is_valid_record(&vals) && count_columns_in_record(&vals) > 0; if rebuild_array_as_map { @@ -195,8 +195,7 @@ fn build_map_from_record(vals: Vec, config: &Config) -> TableValue { for val in vals { match val { Value::Record { val, .. } => { - for (i, (_key, val)) in val.into_owned().into_iter().take(count_columns).enumerate() - { + for (i, (_key, val)) in val.into_iter().take(count_columns).enumerate() { let cell = convert_nu_value_to_table_value(val, config); list[i].push(cell); } diff --git a/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/mod.rs b/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/mod.rs index 5c08b67bbb..4aa996ab47 100644 --- a/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/mod.rs +++ b/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/mod.rs @@ -177,11 +177,9 @@ impl NuDataFrame { conversion::insert_record(&mut column_values, record, &maybe_schema)? } - Value::Record { val: record, .. } => conversion::insert_record( - &mut column_values, - record.into_owned(), - &maybe_schema, - )?, + Value::Record { val: record, .. } => { + conversion::insert_record(&mut column_values, record, &maybe_schema)? + } _ => { let key = "0".to_string(); conversion::insert_value(value, key, &mut column_values, &maybe_schema)? diff --git a/crates/nuon/src/to.rs b/crates/nuon/src/to.rs index 8e9ce71f58..1023a9b653 100644 --- a/crates/nuon/src/to.rs +++ b/crates/nuon/src/to.rs @@ -201,7 +201,7 @@ fn value_to_string( }, Value::Record { val, .. } => { let mut collection = vec![]; - for (col, val) in &**val { + for (col, val) in val { collection.push(if needs_quotes(col) { format!( "{idt_po}\"{}\": {}", From 50313b89c194b42726518351f57e00498028284d Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 18:03:55 -0400 Subject: [PATCH 03/12] Add `Record::drain` implementation --- crates/nu-protocol/src/value/record.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index 8e372fd480..a204e5d78b 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -260,10 +260,9 @@ impl Record { where R: RangeBounds + Clone, { - todo!() - // Drain { - // iter: self.inner.drain(range), - // } + Drain { + iter: self.inner[(range.start_bound().cloned(), range.end_bound().cloned())].iter(), + } } /// Sort the record by its columns. @@ -630,14 +629,16 @@ impl ExactSizeIterator for IntoValues { impl FusedIterator for IntoValues {} pub struct Drain<'a> { - iter: std::vec::Drain<'a, (String, Value)>, + iter: std::slice::Iter<'a, (String, Value)>, } impl Iterator for Drain<'_> { type Item = (String, Value); fn next(&mut self) -> Option { - self.iter.next() + self.iter + .next() + .map(|(col, val)| (col.clone(), val.clone())) } fn size_hint(&self) -> (usize, Option) { @@ -647,7 +648,9 @@ impl Iterator for Drain<'_> { impl DoubleEndedIterator for Drain<'_> { fn next_back(&mut self) -> Option { - self.iter.next_back() + self.iter + .next_back() + .map(|(col, val)| (col.clone(), val.clone())) } } From 84ba4bfa9498d0822617394c900d5cdd71f0fcd2 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 18:06:08 -0400 Subject: [PATCH 04/12] Add `Record::retain_mut` implementation --- crates/nu-protocol/src/value/record.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index a204e5d78b..6f69ab1b5d 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -183,8 +183,10 @@ impl Record { where F: FnMut(&str, &mut Value) -> bool, { - todo!() - // self.inner.retain_mut(|(col, val)| keep(col, val)); + self.inner = std::mem::take(&mut self.inner) + .into_iter() + .filter_map(|(col, mut val)| keep(&col, &mut val).then_some((col, val))) + .collect(); } /// Truncate record to the first `len` elements. From 361e4797d5a873afe4629f5f6b336c1b5a368eb0 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 18:52:23 -0400 Subject: [PATCH 05/12] Add `Value` byte size assertion --- crates/nu-protocol/src/value/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index c345886b60..6c68639b4c 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -247,6 +247,11 @@ impl Clone for Value { } } +// This is to document/enforce the size of `Value` in bytes. +// We should try to avoid increasing the size of `Value`, +// and PRs that do so will have to change the number below so that it's noted in review. +const _: () = assert!(std::mem::size_of::() <= 56); + impl Value { fn cant_convert_to(&self, typ: &str) -> Result { Err(ShellError::CantConvert { From ec43f449fb6ee257277132823efaf0179deb89d0 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 19:44:48 -0400 Subject: [PATCH 06/12] Fix dataframes --- .../src/dataframe/values/nu_dataframe/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs index 8b828aee50..9327c3bbc6 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs @@ -179,11 +179,9 @@ impl NuDataFrame { conversion::insert_record(&mut column_values, record, &maybe_schema)? } - Value::Record { val: record, .. } => conversion::insert_record( - &mut column_values, - record.into_owned(), - &maybe_schema, - )?, + Value::Record { val, .. } => { + conversion::insert_record(&mut column_values, val, &maybe_schema)? + } _ => { let key = "0".to_string(); conversion::insert_value(value, key, &mut column_values, &maybe_schema)? From a01097b11b9ef15d6f5757ffb4e307503a32b800 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 19:52:52 -0400 Subject: [PATCH 07/12] Remove `Record::drain` --- crates/nu-command/src/filters/drop/column.rs | 4 +- crates/nu-protocol/src/value/record.rs | 72 ++++++++++---------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/crates/nu-command/src/filters/drop/column.rs b/crates/nu-command/src/filters/drop/column.rs index 80f55bbe13..e1009d1cf7 100644 --- a/crates/nu-command/src/filters/drop/column.rs +++ b/crates/nu-command/src/filters/drop/column.rs @@ -144,7 +144,9 @@ fn drop_cols( fn drop_cols_set(val: &mut Value, head: Span, drop: usize) -> Result, ShellError> { if let Value::Record { val: record, .. } = val { let len = record.len().saturating_sub(drop); - Ok(record.drain(len..).map(|(col, _)| col).collect()) + let set = record.columns().skip(len).cloned().collect(); + record.truncate(len); + Ok(set) } else { Err(unsupported_value_error(val, head)) } diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index 6f69ab1b5d..8a0ed62099 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -1,7 +1,7 @@ use crate::{ShellError, Span, Value}; use ecow::EcoVec; use serde::{de::Visitor, ser::SerializeMap, Deserialize, Serialize}; -use std::{iter::FusedIterator, ops::RangeBounds}; +use std::iter::FusedIterator; #[derive(Debug, Clone, Default)] pub struct Record { @@ -258,14 +258,14 @@ impl Record { /// assert_eq!(rec_iter.next(), Some(("a".into(), Value::test_nothing()))); /// assert_eq!(rec_iter.next(), None); /// ``` - pub fn drain(&mut self, range: R) -> Drain - where - R: RangeBounds + Clone, - { - Drain { - iter: self.inner[(range.start_bound().cloned(), range.end_bound().cloned())].iter(), - } - } + // pub fn drain(&mut self, range: R) -> Drain + // where + // R: RangeBounds + Clone, + // { + // Drain { + // iter: self.inner.drain(range) + // } + // } /// Sort the record by its columns. /// @@ -630,39 +630,39 @@ impl ExactSizeIterator for IntoValues { impl FusedIterator for IntoValues {} -pub struct Drain<'a> { - iter: std::slice::Iter<'a, (String, Value)>, -} +// pub struct Drain<'a> { +// iter: std::slice::Iter<'a, (String, Value)>, +// } -impl Iterator for Drain<'_> { - type Item = (String, Value); +// impl Iterator for Drain<'_> { +// type Item = (String, Value); - fn next(&mut self) -> Option { - self.iter - .next() - .map(|(col, val)| (col.clone(), val.clone())) - } +// fn next(&mut self) -> Option { +// self.iter +// .next() +// .map(|(col, val)| (col.clone(), val.clone())) +// } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} +// fn size_hint(&self) -> (usize, Option) { +// self.iter.size_hint() +// } +// } -impl DoubleEndedIterator for Drain<'_> { - fn next_back(&mut self) -> Option { - self.iter - .next_back() - .map(|(col, val)| (col.clone(), val.clone())) - } -} +// impl DoubleEndedIterator for Drain<'_> { +// fn next_back(&mut self) -> Option { +// self.iter +// .next_back() +// .map(|(col, val)| (col.clone(), val.clone())) +// } +// } -impl ExactSizeIterator for Drain<'_> { - fn len(&self) -> usize { - self.iter.len() - } -} +// impl ExactSizeIterator for Drain<'_> { +// fn len(&self) -> usize { +// self.iter.len() +// } +// } -impl FusedIterator for Drain<'_> {} +// impl FusedIterator for Drain<'_> {} #[macro_export] macro_rules! record { From 747142a0fd69fc871a6d3dfe85df945ff11eb226 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Mon, 22 Apr 2024 19:56:40 -0400 Subject: [PATCH 08/12] Fix doc tests --- crates/nu-protocol/src/value/record.rs | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index 8a0ed62099..bcbbef3387 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -151,7 +151,7 @@ impl Record { /// /// fn remove_foo_recursively(val: &mut Value) { /// if let Value::Record {val, ..} = val { - /// val.to_mut().retain_mut(keep_non_foo); + /// val.retain_mut(keep_non_foo); /// } /// } /// @@ -237,27 +237,27 @@ impl Record { } } - /// Obtain an iterator to remove elements in `range` - /// - /// Elements not consumed from the iterator will be dropped - /// - /// ```rust - /// use nu_protocol::{record, Value}; - /// - /// let mut rec = record!( - /// "a" => Value::test_nothing(), - /// "b" => Value::test_int(42), - /// "c" => Value::test_string("foo"), - /// ); - /// { - /// let mut drainer = rec.drain(1..); - /// assert_eq!(drainer.next(), Some(("b".into(), Value::test_int(42)))); - /// // Dropping the `Drain` - /// } - /// let mut rec_iter = rec.into_iter(); - /// assert_eq!(rec_iter.next(), Some(("a".into(), Value::test_nothing()))); - /// assert_eq!(rec_iter.next(), None); - /// ``` + // /// Obtain an iterator to remove elements in `range` + // /// + // /// Elements not consumed from the iterator will be dropped + // /// + // /// ```rust + // /// use nu_protocol::{record, Value}; + // /// + // /// let mut rec = record!( + // /// "a" => Value::test_nothing(), + // /// "b" => Value::test_int(42), + // /// "c" => Value::test_string("foo"), + // /// ); + // /// { + // /// let mut drainer = rec.drain(1..); + // /// assert_eq!(drainer.next(), Some(("b".into(), Value::test_int(42)))); + // /// // Dropping the `Drain` + // /// } + // /// let mut rec_iter = rec.into_iter(); + // /// assert_eq!(rec_iter.next(), Some(("a".into(), Value::test_nothing()))); + // /// assert_eq!(rec_iter.next(), None); + // /// ``` // pub fn drain(&mut self, range: R) -> Drain // where // R: RangeBounds + Clone, From 0efeaee6b1b3b2f8fcea42536113b53d43d1a10a Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Fri, 3 May 2024 18:52:11 -0400 Subject: [PATCH 09/12] Fix merge --- crates/nu-protocol/src/config/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/nu-protocol/src/config/mod.rs b/crates/nu-protocol/src/config/mod.rs index 35c5ddd482..09ee797bd0 100644 --- a/crates/nu-protocol/src/config/mod.rs +++ b/crates/nu-protocol/src/config/mod.rs @@ -655,7 +655,7 @@ impl Value { } "shell_integration" => { if let Value::Record { val, .. } = value { - val.to_mut().retain_mut(|key2, value| { + val.retain_mut(|key2, value| { let span = value.span(); match key2 { "osc2" => { From c403581c0f73a0663e8faa11c9f524529193cf33 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Sun, 5 May 2024 11:26:30 -0400 Subject: [PATCH 10/12] Simplify `retain` and `retain_mut` --- crates/nu-protocol/src/value/record.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index bcbbef3387..dffbd56448 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -139,7 +139,7 @@ impl Record { where F: FnMut(&str, &Value) -> bool, { - self.inner.retain(|(k, v)| keep(k, v)) + self.retain_mut(|k, v| keep(k, v)); } /// Remove elements in-place that do not satisfy `keep` while allowing mutation of the value. @@ -183,10 +183,7 @@ impl Record { where F: FnMut(&str, &mut Value) -> bool, { - self.inner = std::mem::take(&mut self.inner) - .into_iter() - .filter_map(|(col, mut val)| keep(&col, &mut val).then_some((col, val))) - .collect(); + self.inner.retain(|(k, v)| keep(k, v)); } /// Truncate record to the first `len` elements. From e61ffb68e818657d287b905b9bbe4cdfb0ab33d7 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Sat, 22 Feb 2025 16:30:30 -0800 Subject: [PATCH 11/12] Update changes --- .../src/commands/history/history_import.rs | 2 +- .../nu-command/src/conversions/into/record.rs | 2 +- crates/nu-command/src/filters/default.rs | 1 - crates/nu-command/src/filters/flatten.rs | 2 +- crates/nu-command/src/filters/merge/common.rs | 4 ++-- crates/nu-command/src/filters/sort.rs | 8 +------ crates/nu-command/src/formats/to/json.rs | 2 +- crates/nu-command/src/formats/to/toml.rs | 2 +- crates/nu-command/src/generators/generate.rs | 3 +-- crates/nu-command/src/network/http/client.rs | 4 ++-- crates/nu-command/src/stor/insert.rs | 2 +- crates/nu-command/src/stor/update.rs | 2 +- crates/nu-command/src/viewers/table.rs | 2 +- crates/nu-explore/src/nu_common/value.rs | 2 +- crates/nu-protocol/src/value/mod.rs | 6 +----- crates/nu-protocol/src/value/record.rs | 4 +--- crates/nu-table/src/types/collapse.rs | 21 +++++++------------ crates/nu-table/src/unstructured_table.rs | 4 ++-- 18 files changed, 27 insertions(+), 46 deletions(-) diff --git a/crates/nu-cli/src/commands/history/history_import.rs b/crates/nu-cli/src/commands/history/history_import.rs index 80237acb87..0b2c555fed 100644 --- a/crates/nu-cli/src/commands/history/history_import.rs +++ b/crates/nu-cli/src/commands/history/history_import.rs @@ -170,7 +170,7 @@ fn error_from_reedline(e: ReedlineError) -> ShellError { fn item_from_value(v: Value) -> Result { let span = v.span(); match v { - Value::Record { val, .. } => item_from_record(val.into_owned(), span), + Value::Record { val, .. } => item_from_record(val, span), Value::String { val, .. } => Ok(HistoryItem { command_line: val, id: None, diff --git a/crates/nu-command/src/conversions/into/record.rs b/crates/nu-command/src/conversions/into/record.rs index fea5fe1e4e..8d29d0faa3 100644 --- a/crates/nu-command/src/conversions/into/record.rs +++ b/crates/nu-command/src/conversions/into/record.rs @@ -134,7 +134,7 @@ fn into_record(call: &Call, input: PipelineData) -> Result { // Don't use .extend() unless that gets changed to check for duplicate keys - for (key, val) in val.into_owned() { + for (key, val) in val { record.insert(key, val); } expected_type = Some(ExpectedType::Record); diff --git a/crates/nu-command/src/filters/default.rs b/crates/nu-command/src/filters/default.rs index 6e5610f1be..d608d4a868 100644 --- a/crates/nu-command/src/filters/default.rs +++ b/crates/nu-command/src/filters/default.rs @@ -102,7 +102,6 @@ fn default( val: ref mut record, .. } => { - let record = record.to_mut(); if let Some(val) = record.get_mut(&column.item) { if matches!(val, Value::Nothing { .. }) { *val = value.clone(); diff --git a/crates/nu-command/src/filters/flatten.rs b/crates/nu-command/src/filters/flatten.rs index 29f8b67553..014febf723 100644 --- a/crates/nu-command/src/filters/flatten.rs +++ b/crates/nu-command/src/filters/flatten.rs @@ -156,7 +156,7 @@ fn flat_value(columns: &[CellPath], item: Value, all: bool) -> Vec { let mut out = IndexMap::::new(); let mut inner_table = None; - for (column_index, (column, value)) in val.into_owned().into_iter().enumerate() { + for (column_index, (column, value)) in val.into_iter().enumerate() { let column_requested = columns.iter().find(|c| c.to_column_name() == column); let need_flatten = { columns.is_empty() || column_requested.is_some() }; let span = value.span(); diff --git a/crates/nu-command/src/filters/merge/common.rs b/crates/nu-command/src/filters/merge/common.rs index 219250d113..20469f8e91 100644 --- a/crates/nu-command/src/filters/merge/common.rs +++ b/crates/nu-command/src/filters/merge/common.rs @@ -65,7 +65,7 @@ pub(crate) fn do_merge( Value::Record { val: lhs, .. }, Value::Record { val: rhs, .. }, ) => Ok(Value::record( - merge_records(lhs.into_owned(), rhs.into_owned(), strategy, span)?, + merge_records(lhs, rhs, strategy, span)?, span, )), // Deep merge records @@ -74,7 +74,7 @@ pub(crate) fn do_merge( Value::Record { val: lhs, .. }, Value::Record { val: rhs, .. }, ) => Ok(Value::record( - merge_records(lhs.into_owned(), rhs.into_owned(), strategy, span)?, + merge_records(lhs, rhs, strategy, span)?, span, )), // Merge lists by appending diff --git a/crates/nu-command/src/filters/sort.rs b/crates/nu-command/src/filters/sort.rs index 8b8c2e6d60..ccb3a8e3a9 100644 --- a/crates/nu-command/src/filters/sort.rs +++ b/crates/nu-command/src/filters/sort.rs @@ -146,13 +146,7 @@ impl Command for Sort { let sorted: Value = match value { Value::Record { val, .. } => { // Records have two sorting methods, toggled by presence or absence of -v - let record = crate::sort_record( - val.into_owned(), - sort_by_value, - reverse, - insensitive, - natural, - )?; + let record = crate::sort_record(val, sort_by_value, reverse, insensitive, natural)?; Value::record(record, span) } value @ Value::List { .. } => { diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 0ba5427038..c795ff9e05 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -164,7 +164,7 @@ pub fn value_to_json_value( } Value::Record { val, .. } => { let mut m = nu_json::Map::new(); - for (k, v) in &**val { + for (k, v) in val { m.insert( k.clone(), value_to_json_value(engine_state, v, serialize_types)?, diff --git a/crates/nu-command/src/formats/to/toml.rs b/crates/nu-command/src/formats/to/toml.rs index 11630e4522..84c2a01371 100644 --- a/crates/nu-command/src/formats/to/toml.rs +++ b/crates/nu-command/src/formats/to/toml.rs @@ -65,7 +65,7 @@ fn helper( Value::String { val, .. } | Value::Glob { val, .. } => toml::Value::String(val.clone()), Value::Record { val, .. } => { let mut m = toml::map::Map::new(); - for (k, v) in &**val { + for (k, v) in val { m.insert(k.clone(), helper(engine_state, v, serialize_types)?); } toml::Value::Table(m) diff --git a/crates/nu-command/src/generators/generate.rs b/crates/nu-command/src/generators/generate.rs index 05a34dcbeb..f08fc2953b 100644 --- a/crates/nu-command/src/generators/generate.rs +++ b/crates/nu-command/src/generators/generate.rs @@ -202,12 +202,11 @@ fn parse_closure_result( match value { // {out: ..., next: ...} -> output and continue Value::Record { val, .. } => { - let iter = val.into_owned().into_iter(); let mut out = None; let mut next = None; let mut err = None; - for (k, v) in iter { + for (k, v) in val { if k.eq_ignore_ascii_case("out") { out = Some(v); } else if k.eq_ignore_ascii_case("next") { diff --git a/crates/nu-command/src/network/http/client.rs b/crates/nu-command/src/network/http/client.rs index fa9727ae4e..047f8f2d39 100644 --- a/crates/nu-command/src/network/http/client.rs +++ b/crates/nu-command/src/network/http/client.rs @@ -347,7 +347,7 @@ fn send_form_request( Value::Record { val, .. } => { let mut data: Vec<(String, String)> = Vec::with_capacity(val.len()); - for (col, val) in val.into_owned() { + for (col, val) in val { data.push((col, val.coerce_into_string()?)) } @@ -380,7 +380,7 @@ fn send_multipart_request( ) }; - for (col, val) in val.into_owned() { + for (col, val) in val { if let Value::Binary { val, .. } = val { let headers = [ "Content-Type: application/octet-stream".to_string(), diff --git a/crates/nu-command/src/stor/insert.rs b/crates/nu-command/src/stor/insert.rs index 1d0f5ae6c0..5457c3a0a9 100644 --- a/crates/nu-command/src/stor/insert.rs +++ b/crates/nu-command/src/stor/insert.rs @@ -138,7 +138,7 @@ fn handle( values .into_iter() .map(|val| match val { - Value::Record { val, .. } => Ok(val.into_owned()), + Value::Record { val, .. } => Ok(val), other => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "record".into(), wrong_type: other.get_type().to_string(), diff --git a/crates/nu-command/src/stor/update.rs b/crates/nu-command/src/stor/update.rs index 98652bae2a..40fc193806 100644 --- a/crates/nu-command/src/stor/update.rs +++ b/crates/nu-command/src/stor/update.rs @@ -120,7 +120,7 @@ fn handle( }); } match value { - Value::Record { val, .. } => Ok(val.into_owned()), + Value::Record { val, .. } => Ok(val), val => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "record".into(), wrong_type: val.get_type().to_string(), diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index b1d8a16d02..923c24d7bd 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -450,7 +450,7 @@ fn handle_table_command(mut input: CmdInput<'_>) -> ShellResult { } PipelineData::Value(Value::Record { val, .. }, ..) => { input.data = PipelineData::Empty; - handle_record(input, val.into_owned()) + handle_record(input, val) } PipelineData::Value(Value::Error { error, .. }, ..) => { // Propagate this error outward, so that it goes to stderr diff --git a/crates/nu-explore/src/nu_common/value.rs b/crates/nu-explore/src/nu_common/value.rs index 3b5751c11a..e6a38b826d 100644 --- a/crates/nu-explore/src/nu_common/value.rs +++ b/crates/nu-explore/src/nu_common/value.rs @@ -92,7 +92,7 @@ pub fn collect_input(value: Value) -> Result<(Vec, Vec>)> { let span = value.span(); match value { Value::Record { val: record, .. } => { - let (key, val): (_, Vec) = record.into_owned().into_iter().unzip(); + let (key, val): (_, Vec) = record.into_iter().unzip(); Ok(( key, diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 70fa87d864..9f84a13847 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -112,7 +112,7 @@ pub enum Value { internal_span: Span, }, Record { - val: SharedCow, + val: Record, /// note: spans are being refactored out of Value /// please use .span() instead of matching this span value #[serde(rename = "span")] @@ -1332,7 +1332,6 @@ impl Value { for val in vals.iter_mut() { match val { Value::Record { val: record, .. } => { - let record = record.to_mut(); if let Some(val) = record.get_mut(col_name) { val.upsert_data_at_cell_path(path, new_val.clone())?; } else { @@ -1360,7 +1359,6 @@ impl Value { } } Value::Record { val: record, .. } => { - let record = record.to_mut(); if let Some(val) = record.get_mut(col_name) { val.upsert_data_at_cell_path(path, new_val)?; } else { @@ -1702,7 +1700,6 @@ impl Value { let v_span = val.span(); match val { Value::Record { val: record, .. } => { - let record = record.to_mut(); if let Some(val) = record.get_mut(col_name) { if path.is_empty() { return Err(ShellError::ColumnAlreadyExists { @@ -1746,7 +1743,6 @@ impl Value { } } Value::Record { val: record, .. } => { - let record = record.to_mut(); if let Some(val) = record.get_mut(col_name) { if path.is_empty() { return Err(ShellError::ColumnAlreadyExists { diff --git a/crates/nu-protocol/src/value/record.rs b/crates/nu-protocol/src/value/record.rs index a5434f76c3..96d45ee71a 100644 --- a/crates/nu-protocol/src/value/record.rs +++ b/crates/nu-protocol/src/value/record.rs @@ -1,6 +1,4 @@ //! Our insertion ordered map-type [`Record`] -use std::{iter::FusedIterator, ops::RangeBounds}; - use crate::{ShellError, Span, Value}; use ecow::EcoVec; use serde::{de::Visitor, ser::SerializeMap, Deserialize, Serialize}; @@ -107,7 +105,7 @@ impl Record { } pub fn get_index(&self, idx: usize) -> Option<(&String, &Value)> { - self.inner.get(idx).map(|(col, val): &(_, _)| (col, val)) + self.inner.get(idx).map(|(col, val)| (col, val)) } /// Remove single value by key diff --git a/crates/nu-table/src/types/collapse.rs b/crates/nu-table/src/types/collapse.rs index 4b4ebed172..c30777961e 100644 --- a/crates/nu-table/src/types/collapse.rs +++ b/crates/nu-table/src/types/collapse.rs @@ -1,7 +1,6 @@ use nu_ansi_term::Style; use nu_color_config::StyleComputer; use nu_protocol::{Config, Value}; -use nu_utils::SharedCow; use crate::{ common::{get_index_style, load_theme, nu_value_to_string_clean}, @@ -41,18 +40,14 @@ fn colorize_value(value: &mut Value, config: &Config, style_computer: &StyleComp // Take ownership of the record and reassign to &mut // We do this to have owned keys through `.into_iter` let record = std::mem::take(val); - *val = SharedCow::new( - record - .into_owned() - .into_iter() - .map(|(mut header, mut val)| { - colorize_value(&mut val, config, style_computer); - header = colorize_text(&header, style.color_style).unwrap_or(header); - - (header, val) - }) - .collect(), - ); + *val = record + .into_iter() + .map(|(header, mut val)| { + colorize_value(&mut val, config, style_computer); + let header = colorize_text(&header, style.color_style).unwrap_or(header); + (header, val) + }) + .collect(); } Value::List { vals, .. } => { for val in vals { diff --git a/crates/nu-table/src/unstructured_table.rs b/crates/nu-table/src/unstructured_table.rs index 8464bb667c..d81d0564dc 100644 --- a/crates/nu-table/src/unstructured_table.rs +++ b/crates/nu-table/src/unstructured_table.rs @@ -174,7 +174,7 @@ fn build_map_from_record(vals: Vec, config: &Config) -> TableValue { for val in vals { let val = get_as_record(val); - for (i, (_, val)) in val.into_owned().into_iter().enumerate() { + for (i, (_, val)) in val.into_iter().enumerate() { let value = convert_nu_value_to_table_value(val, config); let list = get_table_value_column_mut(&mut list[i]); @@ -194,7 +194,7 @@ fn get_table_value_column_mut(val: &mut TableValue) -> &mut Vec { } } -fn get_as_record(val: Value) -> nu_utils::SharedCow { +fn get_as_record(val: Value) -> Record { match val { Value::Record { val, .. } => val, _ => unreachable!(), From 1d713be69da47609579bb1bfe614a448a45ad394 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Sat, 22 Feb 2025 16:39:34 -0800 Subject: [PATCH 12/12] Shrink `Value` size assertion --- crates/nu-protocol/src/value/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 9f84a13847..38e0dd3c24 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -244,7 +244,7 @@ impl Clone for Value { // This is to document/enforce the size of `Value` in bytes. // We should try to avoid increasing the size of `Value`, // and PRs that do so will have to change the number below so that it's noted in review. -const _: () = assert!(std::mem::size_of::() <= 56); +const _: () = assert!(std::mem::size_of::() <= 48); impl Value { fn cant_convert_to(&self, typ: &str) -> Result {