diff --git a/Cargo.lock b/Cargo.lock index 137ea71f9..8d3466a97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1560,7 +1560,7 @@ dependencies = [ [[package]] name = "nom_locate" version = "0.3.1" -source = "git+https://github.com/wycats/nom_locate.git?branch=nom5#9383cc779b23a746ff68cc7094d9ed7baaa661b2" +source = "git+https://github.com/wycats/nom_locate.git?branch=nom5#5baeede19605e2049994eca8f7b366ddc85bb9cd" dependencies = [ "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/cli.rs b/src/cli.rs index 2263eb43f..f438f53b9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -232,7 +232,7 @@ async fn process_line(readline: Result, ctx: &mut Context debug!("=== Parsed ==="); debug!("{:#?}", result); - let mut pipeline = classify_pipeline(&result, ctx, &line)?; + let mut pipeline = classify_pipeline(&result, ctx, &Text::from(line))?; match pipeline.commands.last() { Some(ClassifiedCommand::Sink(_)) => {} @@ -350,13 +350,13 @@ async fn process_line(readline: Result, ctx: &mut Context fn classify_pipeline( pipeline: &TokenNode, context: &Context, - source: &str, + source: &Text, ) -> Result { let pipeline = pipeline.as_pipeline()?; let commands: Result, ShellError> = pipeline .iter() - .map(|item| classify_command(&item, context, source)) + .map(|item| classify_command(&item, context, &source)) .collect(); Ok(ClassifiedPipeline { @@ -367,7 +367,7 @@ fn classify_pipeline( fn classify_command( command: &PipelineElement, context: &Context, - source: &str, + source: &Text, ) -> Result { let call = command.call(); diff --git a/src/commands/cd.rs b/src/commands/cd.rs index 1ed46ab20..2cb2fc1b6 100644 --- a/src/commands/cd.rs +++ b/src/commands/cd.rs @@ -17,8 +17,8 @@ pub fn cd(args: CommandArgs) -> Result { _ => return Err(ShellError::string("Can not change to home directory")), }, Some(v) => { - let target = v.as_string()?.clone(); - match dunce::canonicalize(cwd.join(&target).as_path()) { + let target = v.as_string()?; + match dunce::canonicalize(cwd.join(target.as_ref()).as_path()) { Ok(p) => p, Err(_) => { return Err(ShellError::labeled_error( @@ -63,9 +63,9 @@ pub fn cd(args: CommandArgs) -> Result { cwd.pop(); } _ => match target.chars().nth(0) { - Some(x) if x == '/' => cwd = PathBuf::from(target), + Some(x) if x == '/' => cwd = PathBuf::from(target.as_ref()), _ => { - cwd.push(target); + cwd.push(target.as_ref()); } }, } diff --git a/src/commands/config.rs b/src/commands/config.rs index d18bc2f17..d2161dd62 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -46,7 +46,7 @@ pub fn config(args: CommandArgs) -> Result { if let Some(v) = args.get("get") { let key = v.as_string()?; let value = result - .get(&key) + .get(key.as_ref()) .ok_or_else(|| ShellError::string(&format!("Missing key {} in config", key)))?; return Ok( @@ -57,7 +57,7 @@ pub fn config(args: CommandArgs) -> Result { if let Some(v) = args.get("set") { if let Ok((key, value)) = v.as_pair() { - result.insert(key.as_string()?, value.clone()); + result.insert(key.as_string()?.as_ref().to_string(), value.clone()); config::write_config(&result)?; @@ -86,8 +86,8 @@ pub fn config(args: CommandArgs) -> Result { if let Some(v) = args.get("remove") { let key = v.as_string()?; - if result.contains_key(&key) { - result.remove(&key); + if result.contains_key(key.as_ref()) { + result.remove(key.as_ref()); } else { return Err(ShellError::string(&format!( "{} does not exist in config", diff --git a/src/commands/enter.rs b/src/commands/enter.rs index bd00ab2d9..d3f97512a 100644 --- a/src/commands/enter.rs +++ b/src/commands/enter.rs @@ -58,7 +58,7 @@ pub fn enter(args: CommandArgs) -> Result { } } } else { - full_path.push(Path::new(&s)); + full_path.push(Path::new(s)); match std::fs::read_to_string(&full_path) { Ok(s) => ( full_path diff --git a/src/commands/from_json.rs b/src/commands/from_json.rs index 1624d9c7e..5162632dd 100644 --- a/src/commands/from_json.rs +++ b/src/commands/from_json.rs @@ -4,12 +4,12 @@ use crate::prelude::*; fn convert_json_value_to_nu_value(v: &serde_hjson::Value) -> Value { match v { - serde_hjson::Value::Null => Value::Primitive(Primitive::String("".to_string())), + serde_hjson::Value::Null => Value::Primitive(Primitive::String(String::from(""))), serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)), serde_hjson::Value::F64(n) => Value::Primitive(Primitive::Float(OF64::from(*n))), serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)), serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)), - serde_hjson::Value::String(s) => Value::Primitive(Primitive::String(s.clone())), + serde_hjson::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))), serde_hjson::Value::Array(a) => Value::List( a.iter() .map(|x| convert_json_value_to_nu_value(x)) @@ -38,9 +38,9 @@ pub fn from_json(args: CommandArgs) -> Result { Ok(out .map(|a| match a { Value::Primitive(Primitive::String(s)) => { - ReturnValue::Value(from_json_string_to_value(s)) + ReturnValue::Value(from_json_string_to_value(s.to_string())) } - _ => ReturnValue::Value(Value::Primitive(Primitive::String("".to_string()))), + _ => ReturnValue::Value(Value::Primitive(Primitive::String(String::from("")))), }) .boxed()) } diff --git a/src/commands/from_toml.rs b/src/commands/from_toml.rs index 59610a8ff..59c7f39bf 100644 --- a/src/commands/from_toml.rs +++ b/src/commands/from_toml.rs @@ -1,5 +1,5 @@ -use crate::object::{Primitive, Value, Dictionary, DataDescriptor}; use crate::object::base::OF64; +use crate::object::{DataDescriptor, Dictionary, Primitive, Value}; use crate::prelude::*; fn convert_toml_value_to_nu_value(v: &toml::Value) -> Value { @@ -7,21 +7,28 @@ fn convert_toml_value_to_nu_value(v: &toml::Value) -> Value { toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)), toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)), toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))), - toml::Value::String(s) => Value::Primitive(Primitive::String(s.clone())), - toml::Value::Array(a) => Value::List(a.iter().map(|x| convert_toml_value_to_nu_value(x)).collect()), + toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))), + toml::Value::Array(a) => Value::List( + a.iter() + .map(|x| convert_toml_value_to_nu_value(x)) + .collect(), + ), toml::Value::Datetime(dt) => Value::Primitive(Primitive::String(dt.to_string())), toml::Value::Table(t) => { let mut collected = Dictionary::default(); for (k, v) in t.iter() { - collected.add(DataDescriptor::from(k.clone()), convert_toml_value_to_nu_value(v)); + collected.add( + DataDescriptor::from(k.clone()), + convert_toml_value_to_nu_value(v), + ); } Value::Object(collected) } } } -pub fn from_toml_string_to_value(s: String) -> Value { - let v: toml::Value = s.parse::().unwrap(); +pub fn from_toml_string_to_value(s: impl AsRef) -> Value { + let v: toml::Value = s.as_ref().parse::().unwrap(); convert_toml_value_to_nu_value(&v) } @@ -32,7 +39,7 @@ pub fn from_toml(args: CommandArgs) -> Result { Value::Primitive(Primitive::String(s)) => { ReturnValue::Value(from_toml_string_to_value(s)) } - _ => ReturnValue::Value(Value::Primitive(Primitive::String("".to_string()))), + _ => ReturnValue::Value(Value::Primitive(Primitive::String(String::from("")))), }) .boxed()) } diff --git a/src/commands/from_xml.rs b/src/commands/from_xml.rs index 83e964e09..8a28e9bee 100644 --- a/src/commands/from_xml.rs +++ b/src/commands/from_xml.rs @@ -15,7 +15,7 @@ fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>) -> Value { .filter(|x| match x { Value::Primitive(Primitive::String(f)) => { if f.trim() == "" { - false + false } else { true } @@ -32,13 +32,13 @@ fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>) -> Value { Value::Object(collected) } else if n.is_comment() { - Value::Primitive(Primitive::String("".to_string())) + Value::string("") } else if n.is_pi() { - Value::Primitive(Primitive::String("".to_string())) + Value::string("") } else if n.is_text() { - Value::Primitive(Primitive::String(n.text().unwrap().to_string())) + Value::string(n.text().unwrap()) } else { - Value::Primitive(Primitive::String("".to_string())) + Value::string("") } } @@ -46,8 +46,8 @@ fn from_document_to_value(d: &roxmltree::Document) -> Value { from_node_to_value(&d.root_element()) } -pub fn from_xml_string_to_value(s: String) -> Value { - match roxmltree::Document::parse(&s) { +pub fn from_xml_string_to_value(s: impl AsRef) -> Value { + match roxmltree::Document::parse(s.as_ref()) { Ok(doc) => from_document_to_value(&doc), Err(_) => Value::Error(Box::new(ShellError::string( "Can't convert string from xml".to_string(), @@ -59,7 +59,9 @@ pub fn from_xml(args: CommandArgs) -> Result { let out = args.input; Ok(out .map(|a| match a { - Value::Primitive(Primitive::String(s)) => ReturnValue::Value(from_xml_string_to_value(s)), + Value::Primitive(Primitive::String(s)) => { + ReturnValue::Value(from_xml_string_to_value(s)) + } _ => ReturnValue::Value(Value::Error(Box::new(ShellError::string( "Trying to convert XML from non-string".to_string(), )))), diff --git a/src/commands/from_yaml.rs b/src/commands/from_yaml.rs index 171ab3ae0..12340cd6d 100644 --- a/src/commands/from_yaml.rs +++ b/src/commands/from_yaml.rs @@ -11,7 +11,7 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value) -> Value { serde_yaml::Value::Number(n) if n.is_f64() => { Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))) } - serde_yaml::Value::String(s) => Value::Primitive(Primitive::String(s.clone())), + serde_yaml::Value::String(s) => Value::string(s), serde_yaml::Value::Sequence(a) => Value::List( a.iter() .map(|x| convert_yaml_value_to_nu_value(x)) @@ -36,8 +36,8 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value) -> Value { } } -pub fn from_yaml_string_to_value(s: String) -> Value { - let v: serde_yaml::Value = serde_yaml::from_str(&s).unwrap(); +pub fn from_yaml_string_to_value(s: impl AsRef) -> Value { + let v: serde_yaml::Value = serde_yaml::from_str(s.as_ref()).unwrap(); convert_yaml_value_to_nu_value(&v) } @@ -48,7 +48,7 @@ pub fn from_yaml(args: CommandArgs) -> Result { Value::Primitive(Primitive::String(s)) => { ReturnValue::Value(from_yaml_string_to_value(s)) } - _ => ReturnValue::Value(Value::Primitive(Primitive::String("".to_string()))), + _ => ReturnValue::Value(Value::Primitive(Primitive::String("".into()))), }) .boxed()) } diff --git a/src/commands/get.rs b/src/commands/get.rs index 37f83a695..5811d4156 100644 --- a/src/commands/get.rs +++ b/src/commands/get.rs @@ -1,6 +1,7 @@ use crate::errors::ShellError; use crate::object::Value; use crate::prelude::*; +use crate::Text; fn get_member(path: &str, obj: &Value) -> Option { let mut current = obj; @@ -44,13 +45,14 @@ pub fn get(args: CommandArgs) -> Result { .boxed()); } - let fields: Result, _> = args + let fields: Result, _> = args .args .positional .unwrap() .iter() .map(|a| a.as_string()) .collect(); + let fields = fields?; let stream = args diff --git a/src/commands/lines.rs b/src/commands/lines.rs index 420a1c017..7764927eb 100644 --- a/src/commands/lines.rs +++ b/src/commands/lines.rs @@ -19,7 +19,7 @@ pub fn lines(args: CommandArgs) -> Result { let mut result = VecDeque::new(); for s in split_result { result.push_back(ReturnValue::Value(Value::Primitive(Primitive::String( - s.to_string(), + s.into(), )))); } result diff --git a/src/commands/ls.rs b/src/commands/ls.rs index 405fa0fc3..9dc3c3354 100644 --- a/src/commands/ls.rs +++ b/src/commands/ls.rs @@ -14,7 +14,7 @@ pub fn ls(args: CommandArgs) -> Result { Some(Spanned { item: Value::Primitive(Primitive::String(s)), .. - }) => full_path.push(Path::new(s)), + }) => full_path.push(Path::new(&s)), _ => {} } diff --git a/src/commands/open.rs b/src/commands/open.rs index 414d0b586..527bdee04 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -80,7 +80,7 @@ fn open(args: CommandArgs) -> Result { } } } else { - full_path.push(Path::new(&s)); + full_path.push(Path::new(s)); match std::fs::read_to_string(&full_path) { Ok(s) => ( full_path @@ -138,9 +138,7 @@ fn open(args: CommandArgs) -> Result { )); } _ => { - stream.push_back(ReturnValue::Value(Value::Primitive(Primitive::String( - contents, - )))); + stream.push_back(ReturnValue::Value(Value::string(contents))); } } diff --git a/src/commands/pick.rs b/src/commands/pick.rs index b5a17e037..3d86fd72e 100644 --- a/src/commands/pick.rs +++ b/src/commands/pick.rs @@ -16,7 +16,7 @@ pub fn pick(args: CommandArgs) -> Result { } } - let fields: Result, _> = args.positional_iter().map(|a| a.as_string()).collect(); + let fields: Result, _> = args.positional_iter().map(|a| a.as_string()).collect(); let fields = fields?; let objects = args diff --git a/src/commands/reject.rs b/src/commands/reject.rs index 4a9f28a7e..b30036fcf 100644 --- a/src/commands/reject.rs +++ b/src/commands/reject.rs @@ -16,7 +16,7 @@ pub fn reject(args: CommandArgs) -> Result { } } - let fields: Result, _> = args.positional_iter().map(|a| a.as_string()).collect(); + let fields: Result, _> = args.positional_iter().map(|a| a.as_string()).collect(); let fields = fields?; let stream = args diff --git a/src/commands/size.rs b/src/commands/size.rs index 59df8165c..c99276375 100644 --- a/src/commands/size.rs +++ b/src/commands/size.rs @@ -23,7 +23,7 @@ pub fn size(args: CommandArgs) -> Result { let mut list = VecDeque::new(); for name in args.positional_iter() { let name = name.as_string()?; - let path = cwd.join(&name); + let path = cwd.join(name.as_ref()); let mut file = File::open(path)?; file.read_to_string(&mut contents)?; list.push_back(count(&name, &contents)); @@ -59,7 +59,7 @@ fn count(name: &str, contents: &str) -> ReturnValue { } let mut dict = Dictionary::default(); - dict.add("name", Value::string(name.to_owned())); + dict.add("name", Value::string(name)); dict.add("lines", Value::int(lines)); dict.add("words", Value::int(words)); dict.add("chars", Value::int(chars)); diff --git a/src/commands/split_column.rs b/src/commands/split_column.rs index b54695579..32f1f7594 100644 --- a/src/commands/split_column.rs +++ b/src/commands/split_column.rs @@ -39,19 +39,16 @@ pub fn split_column(args: CommandArgs) -> Result { } let mut dict = crate::object::Dictionary::default(); - for (k, v) in split_result.iter().zip(gen_columns.iter()) { - dict.add( - v.clone(), - Value::Primitive(Primitive::String(k.to_string())), - ); + for (&k, v) in split_result.iter().zip(gen_columns.iter()) { + dict.add(v.clone(), Value::Primitive(Primitive::String(k.into()))); } ReturnValue::Value(Value::Object(dict)) } else if split_result.len() == (positional.len() - 1) { let mut dict = crate::object::Dictionary::default(); - for (k, v) in split_result.iter().zip(positional.iter().skip(1)) { + for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) { dict.add( v.as_string().unwrap(), - Value::Primitive(Primitive::String(k.to_string())), + Value::Primitive(Primitive::String(k.into())), ); } ReturnValue::Value(Value::Object(dict)) @@ -60,7 +57,7 @@ pub fn split_column(args: CommandArgs) -> Result { for k in positional.iter().skip(1) { dict.add( k.as_string().unwrap().trim(), - Value::Primitive(Primitive::String("".to_string())), + Value::Primitive(Primitive::String("".into())), ); } ReturnValue::Value(Value::Object(dict)) diff --git a/src/commands/split_row.rs b/src/commands/split_row.rs index 80dbf29ad..1fb10e353 100644 --- a/src/commands/split_row.rs +++ b/src/commands/split_row.rs @@ -35,7 +35,7 @@ pub fn split_row(args: CommandArgs) -> Result { let mut result = VecDeque::new(); for s in split_result { result.push_back(ReturnValue::Value(Value::Primitive(Primitive::String( - s.to_string(), + s.into(), )))); } result diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index fa8aadd0a..eaae20308 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -4,6 +4,10 @@ use crate::prelude::*; pub fn to_json(args: CommandArgs) -> Result { let out = args.input; Ok(out - .map(|a| ReturnValue::Value(Value::Primitive(Primitive::String(serde_json::to_string(&a).unwrap())))) + .map(|a| { + ReturnValue::Value(Value::Primitive(Primitive::String( + serde_json::to_string(&a).unwrap().into(), + ))) + }) .boxed()) } diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index ac0fe05a6..a7727e727 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -4,6 +4,10 @@ use crate::prelude::*; pub fn to_toml(args: CommandArgs) -> Result { let out = args.input; Ok(out - .map(|a| ReturnValue::Value(Value::Primitive(Primitive::String(toml::to_string(&a).unwrap())))) + .map(|a| { + ReturnValue::Value(Value::Primitive(Primitive::String( + toml::to_string(&a).unwrap().into(), + ))) + }) .boxed()) } diff --git a/src/commands/trim.rs b/src/commands/trim.rs index 2974b4e65..0ef840fea 100644 --- a/src/commands/trim.rs +++ b/src/commands/trim.rs @@ -10,7 +10,7 @@ pub fn trim(args: CommandArgs) -> Result { Ok(input .map(move |v| match v { Value::Primitive(Primitive::String(s)) => { - ReturnValue::Value(Value::Primitive(Primitive::String(s.trim().to_string()))) + ReturnValue::Value(Value::Primitive(Primitive::String(s.trim().into()))) } x => ReturnValue::Value(x), }) diff --git a/src/commands/view.rs b/src/commands/view.rs index a24b28ff7..71c4cdec0 100644 --- a/src/commands/view.rs +++ b/src/commands/view.rs @@ -46,7 +46,7 @@ pub fn view(args: CommandArgs) -> Result { .build() .map_err(|e| ShellError::string(e))?; - let file = cwd.join(target); + let file = cwd.join(target.as_ref()); let _ = printer.file(file.display().to_string()); diff --git a/src/evaluate/evaluator.rs b/src/evaluate/evaluator.rs index 7163bf697..31958af78 100644 --- a/src/evaluate/evaluator.rs +++ b/src/evaluate/evaluator.rs @@ -27,7 +27,7 @@ crate fn evaluate_baseline_expr( expr: &Expression, registry: &dyn CommandRegistry, scope: &Scope, - source: &str, + source: &Text, ) -> Result, ShellError> { match &expr.item { RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_span(*literal), source)), @@ -45,7 +45,7 @@ crate fn evaluate_baseline_expr( } } RawExpression::Block(block) => Ok(Spanned::from_item( - Value::Block(Block::new(*block.clone(), Text::from(source))), // TODO: Pass Text around + Value::Block(Block::new(*block.clone(), source.clone())), block.span(), )), RawExpression::Path(path) => { @@ -67,7 +67,7 @@ crate fn evaluate_baseline_expr( } } -fn evaluate_literal(literal: Spanned, source: &str) -> Spanned { +fn evaluate_literal(literal: Spanned, source: &Text) -> Spanned { let result = match literal.item { hir::Literal::Integer(int) => Value::int(int), hir::Literal::Size(_int, _unit) => unimplemented!(), @@ -81,7 +81,7 @@ fn evaluate_literal(literal: Spanned, source: &str) -> Spanned Result, ShellError> { match name { hir::Variable::It(span) => Ok(Spanned::from_item(scope.it.copy(), span)), diff --git a/src/format/generic.rs b/src/format/generic.rs index 06032cf71..ba99123e8 100644 --- a/src/format/generic.rs +++ b/src/format/generic.rs @@ -31,7 +31,7 @@ impl RenderView for GenericView<'value> { b @ Value::Block(_) => { let printed = b.format_leaf(None); - let view = EntriesView::from_value(&Value::string(&printed)); + let view = EntriesView::from_value(&Value::string(printed)); view.render_view(host)?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 5d5aaba46..ac4f251c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,8 @@ use clap::{App, Arg}; use log::LevelFilter; use std::error::Error; +crate use parser::parse2::text::Text; + fn main() -> Result<(), Box> { let matches = App::new("nu shell") .version("0.5") diff --git a/src/object/base.rs b/src/object/base.rs index e5c9bdfd2..18229c68b 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -3,17 +3,16 @@ use crate::evaluate::{evaluate_baseline_expr, Scope}; use crate::object::DataDescriptor; use crate::parser::{hir, Operator, Spanned}; use crate::prelude::*; +use crate::Text; use ansi_term::Color; use chrono::{DateTime, Utc}; use chrono_humanize::Humanize; use derive_new::new; use ordered_float::OrderedFloat; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt; use std::time::SystemTime; -use crate::parser::Text; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - #[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, new)] pub struct OF64 { crate inner: OrderedFloat, @@ -141,7 +140,7 @@ impl Serialize for Block { where S: Serializer, { - serializer.serialize_str(&self.expression.source(self.source.as_ref())) + serializer.serialize_str(&self.expression.source(&self.source.clone())) } } @@ -162,7 +161,7 @@ impl Deserialize<'de> for Block { impl Block { pub fn invoke(&self, value: &Value) -> Result, ShellError> { let scope = Scope::new(value.copy()); - evaluate_baseline_expr(&self.expression, &(), &scope, self.source.as_ref()) + evaluate_baseline_expr(&self.expression, &(), &scope, &self.source) } } @@ -293,7 +292,7 @@ impl Value { crate fn format_leaf(&self, desc: Option<&DataDescriptor>) -> String { match self { Value::Primitive(p) => p.format(desc), - Value::Block(b) => b.expression.source(b.source.as_ref()).to_string(), + Value::Block(b) => b.expression.source(&b.source).to_string(), Value::Object(_) => format!("[object Object]"), Value::List(_) => format!("[list List]"), Value::Error(e) => format!("{}", e), @@ -346,9 +345,9 @@ impl Value { } } - crate fn as_string(&self) -> Result { + crate fn as_string(&self) -> Result { match self { - Value::Primitive(Primitive::String(s)) => Ok(s.clone()), + Value::Primitive(Primitive::String(s)) => Ok(Text::from(s.clone())), // TODO: this should definitely be more general with better errors other => Err(ShellError::string(format!( "Expected string, got {:?}", @@ -456,7 +455,7 @@ impl Value { } } -crate fn select_fields(obj: &Value, fields: &[String]) -> crate::object::Dictionary { +crate fn select_fields(obj: &Value, fields: &[Text]) -> crate::object::Dictionary { let mut out = crate::object::Dictionary::default(); let descs = obj.data_descriptors(); @@ -471,7 +470,7 @@ crate fn select_fields(obj: &Value, fields: &[String]) -> crate::object::Diction out } -crate fn reject_fields(obj: &Value, fields: &[String]) -> crate::object::Dictionary { +crate fn reject_fields(obj: &Value, fields: &[Text]) -> crate::object::Dictionary { let mut out = crate::object::Dictionary::default(); let descs = obj.data_descriptors(); diff --git a/src/object/desc.rs b/src/object/desc.rs index d69705b46..7a7e24c76 100644 --- a/src/object/desc.rs +++ b/src/object/desc.rs @@ -1,4 +1,5 @@ use crate::object::types::Type; +use crate::Text; use derive_new::new; use serde::{Deserialize, Serialize, Serializer}; @@ -90,9 +91,19 @@ impl From for DataDescriptor { } } +impl From for DataDescriptor { + fn from(input: Text) -> DataDescriptor { + DataDescriptor { + name: DescriptorName::String(input.to_string()), + readonly: true, + ty: Type::Any, + } + } +} + impl DescriptorName { - crate fn for_string_name(name: impl Into) -> DescriptorName { - DescriptorName::String(name.into()) + crate fn for_string_name(name: impl AsRef) -> DescriptorName { + DescriptorName::String(name.as_ref().into()) } } @@ -113,7 +124,7 @@ impl DataDescriptor { } } - crate fn for_string_name(name: impl Into) -> DataDescriptor { + crate fn for_string_name(name: impl AsRef) -> DataDescriptor { DataDescriptor::for_name(DescriptorName::for_string_name(name)) } diff --git a/src/parser/hir/baseline_parse.rs b/src/parser/hir/baseline_parse.rs index ae9240cd4..2661fb772 100644 --- a/src/parser/hir/baseline_parse.rs +++ b/src/parser/hir/baseline_parse.rs @@ -1,6 +1,7 @@ use crate::parser::{hir, RawToken, Token}; +use crate::Text; -pub fn baseline_parse_single_token(token: &Token, source: &str) -> hir::Expression { +pub fn baseline_parse_single_token(token: &Token, source: &Text) -> hir::Expression { match *token.item() { RawToken::Integer(int) => hir::Expression::int(int, token.span), RawToken::Size(int, unit) => hir::Expression::size(int, unit, token.span), diff --git a/src/parser/hir/baseline_parse_tokens.rs b/src/parser/hir/baseline_parse_tokens.rs index 39c1fcaee..95c26904d 100644 --- a/src/parser/hir/baseline_parse_tokens.rs +++ b/src/parser/hir/baseline_parse_tokens.rs @@ -1,11 +1,12 @@ use crate::errors::ShellError; use crate::parser::registry::CommandRegistry; use crate::parser::{hir, hir::baseline_parse_single_token, Span, Spanned, TokenNode}; +use crate::Text; pub fn baseline_parse_tokens( token_nodes: &[TokenNode], registry: &dyn CommandRegistry, - source: &str, + source: &Text, ) -> Result, ShellError> { let mut exprs: Vec = vec![]; let mut rest = token_nodes; @@ -36,14 +37,9 @@ pub enum ExpressionKindHint { pub fn baseline_parse_next_expr( token_nodes: &'nodes [TokenNode], _registry: &dyn CommandRegistry, - source: &str, + source: &Text, coerce_hint: Option, ) -> Result<(hir::Expression, &'nodes [TokenNode]), ShellError> { - println!( - "baseline_parse_next_expr {:?} - {:?}", - token_nodes, coerce_hint - ); - let mut tokens = token_nodes.iter().peekable(); let first = next_token(&mut tokens); @@ -131,7 +127,7 @@ pub fn baseline_parse_next_expr( pub fn baseline_parse_semantic_token( token: &TokenNode, - source: &str, + source: &Text, ) -> Result { match token { TokenNode::Token(token) => Ok(baseline_parse_single_token(token, source)), diff --git a/src/parser/parse2/span.rs b/src/parser/parse2/span.rs index 928352d69..e5905ea4d 100644 --- a/src/parser/parse2/span.rs +++ b/src/parser/parse2/span.rs @@ -1,3 +1,4 @@ +use crate::Text; use derive_new::new; use getset::Getters; @@ -40,8 +41,8 @@ impl Spanned { } } - pub fn source(&self, source: &'source str) -> &'source str { - self.span().slice(source) + pub fn source(&self, source: &Text) -> Text { + Text::from(self.span().slice(source)) } } @@ -95,7 +96,7 @@ impl From<&std::ops::Range> for Span { } impl Span { - pub fn slice(&self, source: &'source str) -> &'source str { + pub fn slice(&self, source: &'a str) -> &'a str { &source[self.start..self.end] } } diff --git a/src/parser/parse2/text.rs b/src/parser/parse2/text.rs index 724639228..60f014d9e 100644 --- a/src/parser/parse2/text.rs +++ b/src/parser/parse2/text.rs @@ -31,7 +31,7 @@ impl Text { /// Extract a new `Text` that is a subset of an old `Text` /// -- `text.extract(1..3)` is similar to `&foo[1..3]` except that /// it gives back an owned value instead of a borrowed value. - pub fn extract(&self, range: Range) -> Self { + pub fn slice(&self, range: Range) -> Self { let mut result = self.clone(); result.select(range); result diff --git a/src/parser/parse2/token_tree.rs b/src/parser/parse2/token_tree.rs index e618feaa9..098e024b6 100644 --- a/src/parser/parse2/token_tree.rs +++ b/src/parser/parse2/token_tree.rs @@ -1,5 +1,6 @@ use crate::errors::ShellError; use crate::parser::parse2::{call_node::*, flag::*, operator::*, span::*, tokens::*}; +use crate::Text; use derive_new::new; use enum_utils::FromStr; use getset::Getters; @@ -36,11 +37,11 @@ impl TokenNode { } } - pub fn as_external_arg(&self, source: &str) -> String { + pub fn as_external_arg(&self, source: &Text) -> String { self.span().slice(source).to_string() } - pub fn source(&self, source: &'source str) -> &'source str { + pub fn source(&self, source: &'a Text) -> &'a str { self.span().slice(source) } @@ -54,7 +55,7 @@ impl TokenNode { } } - crate fn as_flag(&self, value: &str, source: &str) -> Option> { + crate fn as_flag(&self, value: &str, source: &Text) -> Option> { match self { TokenNode::Flag( flag @ Spanned { diff --git a/src/parser/parse_command.rs b/src/parser/parse_command.rs index d3064cbae..c9c49b1b8 100644 --- a/src/parser/parse_command.rs +++ b/src/parser/parse_command.rs @@ -5,13 +5,14 @@ use crate::parser::{ hir::{self, NamedArguments}, Flag, RawToken, TokenNode, }; +use crate::Text; use log::trace; pub fn parse_command( config: &CommandConfig, registry: &dyn CommandRegistry, call: &Spanned, - source: &str, + source: &Text, ) -> Result { let Spanned { item: call, .. } = call; @@ -64,7 +65,7 @@ fn parse_command_tail( config: &CommandConfig, registry: &dyn CommandRegistry, tail: Option>, - source: &str, + source: &Text, ) -> Result>, Option)>, ShellError> { let mut tail = match tail { None => return Ok(None), @@ -176,7 +177,7 @@ fn parse_command_tail( fn extract_switch( name: &str, mut tokens: Vec, - source: &str, + source: &Text, ) -> (Vec, Option) { let pos = tokens .iter() @@ -196,7 +197,7 @@ fn extract_switch( fn extract_mandatory( name: &str, mut tokens: Vec, - source: &str, + source: &Text, ) -> Result<(Vec, usize, Flag), ShellError> { let pos = tokens .iter() @@ -225,7 +226,7 @@ fn extract_mandatory( fn extract_optional( name: &str, mut tokens: Vec, - source: &str, + source: &Text, ) -> Result<(Vec, Option<(usize, Flag)>), ShellError> { let pos = tokens .iter() diff --git a/src/parser/registry.rs b/src/parser/registry.rs index d50c67aa4..6f786616b 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -189,7 +189,7 @@ impl CommandConfig { call: &Spanned, registry: &dyn CommandRegistry, scope: &Scope, - source: &str, + source: &Text, ) -> Result { let args = parse_command(self, registry, call, source)?; @@ -282,7 +282,7 @@ fn evaluate_args( args: hir::Call, registry: &dyn CommandRegistry, scope: &Scope, - source: &str, + source: &Text, ) -> Result { let positional: Result>, _> = args .positional() diff --git a/src/prelude.rs b/src/prelude.rs index b9fec2540..241b8aad4 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -6,6 +6,7 @@ crate use crate::env::{Environment, Host}; crate use crate::errors::ShellError; crate use crate::object::Value; crate use crate::stream::{single_output, InputStream, OutputStream}; +crate use crate::Text; crate use futures::{FutureExt, StreamExt}; crate use std::collections::VecDeque; crate use std::pin::Pin; diff --git a/src/shell/helper.rs b/src/shell/helper.rs index 85ad50de6..c79b0cc89 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -70,7 +70,7 @@ impl Highlighter for Helper { match iter.next() { None => return Cow::Owned(out), - Some(v) => out.push_str(v.span().slice(line)), + Some(v) => out.push_str(v.span().slice(&Text::from(line))), }; loop {