diff --git a/src/cli.rs b/src/cli.rs index 9ffab09c..761da771 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -17,7 +17,7 @@ use crate::prelude::*; use log::{debug, trace}; use regex::Regex; use rustyline::error::ReadlineError; -use rustyline::{self, ColorMode, Config, Editor, config::Configurer, config::EditMode}; +use rustyline::{self, config::Configurer, config::EditMode, ColorMode, Config, Editor}; use std::env; use std::error::Error; use std::io::{BufRead, BufReader, Write}; @@ -180,6 +180,7 @@ pub async fn cli() -> Result<(), Box> { whole_stream_command(ToCSV), whole_stream_command(ToJSON), whole_stream_command(ToSQLite), + whole_stream_command(ToDB), whole_stream_command(ToTOML), whole_stream_command(ToTSV), whole_stream_command(ToYAML), @@ -194,10 +195,12 @@ pub async fn cli() -> Result<(), Box> { whole_stream_command(FromINI), whole_stream_command(FromBSON), whole_stream_command(FromJSON), + whole_stream_command(FromDB), whole_stream_command(FromSQLite), whole_stream_command(FromTOML), whole_stream_command(FromXML), whole_stream_command(FromYAML), + whole_stream_command(FromYML), whole_stream_command(Pick), whole_stream_command(Get), per_item_command(Remove), diff --git a/src/commands.rs b/src/commands.rs index 2f5d174f..253499a5 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -82,11 +82,13 @@ pub(crate) use from_bson::FromBSON; pub(crate) use from_csv::FromCSV; pub(crate) use from_ini::FromINI; pub(crate) use from_json::FromJSON; +pub(crate) use from_sqlite::FromDB; pub(crate) use from_sqlite::FromSQLite; pub(crate) use from_toml::FromTOML; pub(crate) use from_tsv::FromTSV; pub(crate) use from_xml::FromXML; pub(crate) use from_yaml::FromYAML; +pub(crate) use from_yaml::FromYML; pub(crate) use get::Get; pub(crate) use last::Last; pub(crate) use lines::Lines; @@ -115,6 +117,7 @@ pub(crate) use to_array::ToArray; pub(crate) use to_bson::ToBSON; pub(crate) use to_csv::ToCSV; pub(crate) use to_json::ToJSON; +pub(crate) use to_sqlite::ToDB; pub(crate) use to_sqlite::ToSQLite; pub(crate) use to_toml::ToTOML; pub(crate) use to_tsv::ToTSV; diff --git a/src/commands/classified.rs b/src/commands/classified.rs index c0b42d21..14307076 100644 --- a/src/commands/classified.rs +++ b/src/commands/classified.rs @@ -146,53 +146,9 @@ impl InternalCommand { .insert_at_current(Box::new(ValueShell::new(value))); } CommandAction::EnterShell(location) => { - let path = std::path::Path::new(&location); - - if path.is_dir() { - // If it's a directory, add a new filesystem shell - context.shell_manager.insert_at_current(Box::new( - FilesystemShell::with_location( - location, - context.registry().clone(), - )?, - )); - } else { - // If it's a file, attempt to open the file as a value and enter it - let cwd = context.shell_manager.path(); - - let full_path = std::path::PathBuf::from(cwd); - - let (file_extension, contents, contents_tag, span_source) = - crate::commands::open::fetch( - &full_path, - &location, - Span::unknown(), - ) - .await?; - - if let Some(uuid) = contents_tag.origin { - // If we have loaded something, track its source - context.add_span_source(uuid, span_source); - } - - match contents { - Value::Primitive(Primitive::String(string)) => { - let value = crate::commands::open::parse_string_as_value( - file_extension, - string, - contents_tag, - Span::unknown(), - )?; - - context - .shell_manager - .insert_at_current(Box::new(ValueShell::new(value))); - } - value => context.shell_manager.insert_at_current(Box::new( - ValueShell::new(value.tagged(contents_tag)), - )), - } - } + context.shell_manager.insert_at_current(Box::new( + FilesystemShell::with_location(location, context.registry().clone())?, + )); } CommandAction::PreviousShell => { context.shell_manager.prev(); diff --git a/src/commands/command.rs b/src/commands/command.rs index 9c8e786a..404d1d6b 100644 --- a/src/commands/command.rs +++ b/src/commands/command.rs @@ -512,7 +512,7 @@ pub trait PerItemCommand: Send + Sync { &self, call_info: &CallInfo, registry: &CommandRegistry, - shell_manager: &ShellManager, + raw_args: &RawCommandArgs, input: Tagged, ) -> Result; @@ -579,7 +579,7 @@ impl Command { .call_info .evaluate(®istry, &Scope::it_value(x.clone())) .unwrap(); - match command.run(&call_info, ®istry, &raw_args.shell_manager, x) { + match command.run(&call_info, ®istry, &raw_args, x) { Ok(o) => o, Err(e) => VecDeque::from(vec![ReturnValue::Err(e)]).to_output_stream(), } @@ -596,7 +596,10 @@ impl Command { .unwrap(); // We don't have an $it or block, so just execute what we have - match command.run(&call_info, ®istry, &raw_args.shell_manager, nothing) { + match command + .run(&call_info, ®istry, &raw_args, nothing) + .into() + { Ok(o) => o, Err(e) => OutputStream::one(Err(e)), } diff --git a/src/commands/cp.rs b/src/commands/cp.rs index 9ddbc8e4..ee1a289c 100644 --- a/src/commands/cp.rs +++ b/src/commands/cp.rs @@ -19,10 +19,10 @@ impl PerItemCommand for Cpy { &self, call_info: &CallInfo, _registry: &CommandRegistry, - shell_manager: &ShellManager, + raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - call_info.process(shell_manager, cp)?.run() + call_info.process(&raw_args.shell_manager, cp)?.run() } fn name(&self) -> &str { diff --git a/src/commands/enter.rs b/src/commands/enter.rs index 2e9d0fd0..63316b70 100644 --- a/src/commands/enter.rs +++ b/src/commands/enter.rs @@ -1,8 +1,10 @@ use crate::commands::command::CommandAction; use crate::commands::PerItemCommand; +use crate::commands::UnevaluatedCallInfo; use crate::errors::ShellError; use crate::parser::registry; use crate::prelude::*; +use std::path::PathBuf; pub struct Enter; @@ -18,18 +20,109 @@ impl PerItemCommand for Enter { fn run( &self, call_info: &CallInfo, - _registry: ®istry::CommandRegistry, - _shell_manager: &ShellManager, + registry: ®istry::CommandRegistry, + raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { + let registry = registry.clone(); + let raw_args = raw_args.clone(); match call_info.args.expect_nth(0)? { Tagged { item: Value::Primitive(Primitive::String(location)), .. - } => Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell( - location.to_string(), - )))] - .into()), + } => { + let location = location.to_string(); + let location_clone = location.to_string(); + if PathBuf::from(location).is_dir() { + Ok(vec![Ok(ReturnSuccess::Action(CommandAction::EnterShell( + location_clone, + )))] + .into()) + } else { + let stream = async_stream_block! { + // If it's a file, attempt to open the file as a value and enter it + let cwd = raw_args.shell_manager.path(); + + let full_path = std::path::PathBuf::from(cwd); + + let (file_extension, contents, contents_tag, span_source) = + crate::commands::open::fetch( + &full_path, + &location_clone, + Span::unknown(), + ) + .await.unwrap(); + + if let Some(uuid) = contents_tag.origin { + // If we have loaded something, track its source + yield ReturnSuccess::action(CommandAction::AddSpanSource( + uuid, + span_source, + )); + } + + + match contents { + Value::Primitive(Primitive::String(_)) => { + let tagged_contents = contents.tagged(contents_tag); + + if let Some(extension) = file_extension { + let command_name = format!("from-{}", extension); + if let Some(converter) = + registry.get_command(&command_name) + { + let new_args = RawCommandArgs { + host: raw_args.host, + shell_manager: raw_args.shell_manager, + call_info: UnevaluatedCallInfo { + args: crate::parser::hir::Call { + head: raw_args.call_info.args.head, + positional: None, + named: None, + }, + source: raw_args.call_info.source, + source_map: raw_args.call_info.source_map, + name_span: raw_args.call_info.name_span, + }, + }; + let mut result = converter.run( + new_args.with_input(vec![tagged_contents]), + ®istry, + ); + let result_vec: Vec> = + result.drain_vec().await; + for res in result_vec { + match res { + Ok(ReturnSuccess::Value(Tagged { + item, + .. + })) => { + yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell( + Tagged { + item: item, + tag: contents_tag, + }))); + } + x => yield x, + } + } + } else { + yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents))); + } + } else { + yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents))); + } + } + _ => { + let tagged_contents = contents.tagged(contents_tag); + + yield Ok(ReturnSuccess::Action(CommandAction::EnterValueShell(tagged_contents))); + } + } + }; + Ok(stream.to_output_stream()) + } + } x => Ok( vec![Ok(ReturnSuccess::Action(CommandAction::EnterValueShell( x.clone(), diff --git a/src/commands/from_sqlite.rs b/src/commands/from_sqlite.rs index 2ebf6769..0fab1158 100644 --- a/src/commands/from_sqlite.rs +++ b/src/commands/from_sqlite.rs @@ -27,6 +27,26 @@ impl WholeStreamCommand for FromSQLite { } } +pub struct FromDB; + +impl WholeStreamCommand for FromDB { + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + from_sqlite(args, registry) + } + + fn name(&self) -> &str { + "from-db" + } + + fn signature(&self) -> Signature { + Signature::build("from-db") + } +} + pub fn convert_sqlite_file_to_nu_value( path: &Path, tag: impl Into + Clone, diff --git a/src/commands/from_yaml.rs b/src/commands/from_yaml.rs index 349a6fae..2294a39e 100644 --- a/src/commands/from_yaml.rs +++ b/src/commands/from_yaml.rs @@ -23,6 +23,26 @@ impl WholeStreamCommand for FromYAML { } } +pub struct FromYML; + +impl WholeStreamCommand for FromYML { + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + from_yaml(args, registry) + } + + fn name(&self) -> &str { + "from-yml" + } + + fn signature(&self) -> Signature { + Signature::build("from-yml") + } +} + fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into) -> Tagged { let tag = tag.into(); diff --git a/src/commands/mkdir.rs b/src/commands/mkdir.rs index 5f92f117..96fd16af 100644 --- a/src/commands/mkdir.rs +++ b/src/commands/mkdir.rs @@ -16,10 +16,10 @@ impl PerItemCommand for Mkdir { &self, call_info: &CallInfo, _registry: &CommandRegistry, - shell_manager: &ShellManager, + raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - call_info.process(shell_manager, mkdir)?.run() + call_info.process(&raw_args.shell_manager, mkdir)?.run() } fn name(&self) -> &str { diff --git a/src/commands/mv.rs b/src/commands/mv.rs index 37384e6b..af93dde3 100644 --- a/src/commands/mv.rs +++ b/src/commands/mv.rs @@ -29,10 +29,10 @@ impl PerItemCommand for Move { &self, call_info: &CallInfo, _registry: &CommandRegistry, - shell_manager: &ShellManager, + raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - call_info.process(shell_manager, mv)?.run() + call_info.process(&raw_args.shell_manager, mv)?.run() } } diff --git a/src/commands/open.rs b/src/commands/open.rs index af43e698..a085862c 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -1,6 +1,7 @@ +use crate::commands::UnevaluatedCallInfo; use crate::context::SpanSource; use crate::errors::ShellError; -use crate::object::{Primitive, Value}; +use crate::object::Value; use crate::parser::hir::SyntaxType; use crate::parser::registry::Signature; use crate::prelude::*; @@ -25,15 +26,20 @@ impl PerItemCommand for Open { fn run( &self, call_info: &CallInfo, - _registry: &CommandRegistry, - shell_manager: &ShellManager, + registry: &CommandRegistry, + raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - run(call_info, shell_manager) + run(call_info, registry, raw_args) } } -fn run(call_info: &CallInfo, shell_manager: &ShellManager) -> Result { +fn run( + call_info: &CallInfo, + registry: &CommandRegistry, + raw_args: &RawCommandArgs, +) -> Result { + let shell_manager = &raw_args.shell_manager; let cwd = PathBuf::from(shell_manager.path()); let full_path = PathBuf::from(cwd); @@ -47,8 +53,9 @@ fn run(call_info: &CallInfo, shell_manager: &ShellManager) -> Result Result Result { - let value = parse_string_as_value(file_extension, string, contents_tag, name_span).unwrap(); + let tagged_contents = contents.tagged(contents_tag); - match value { - Tagged { - item: Value::List(list), - .. - } => { - for elem in list { - yield ReturnSuccess::value(elem); - } + if let Some(extension) = file_extension { + let command_name = format!("from-{}", extension); + if let Some(converter) = registry.get_command(&command_name) { + let new_args = RawCommandArgs { + host: raw_args.host, + shell_manager: raw_args.shell_manager, + call_info: UnevaluatedCallInfo { + args: crate::parser::hir::Call { + head: raw_args.call_info.args.head, + positional: None, + named: None + }, + source: raw_args.call_info.source, + source_map: raw_args.call_info.source_map, + name_span: raw_args.call_info.name_span, } - x => yield ReturnSuccess::value(x), - } - } - Value::Binary(binary) => { - let value = parse_binary_as_value(file_extension, binary, contents_tag, name_span).unwrap(); - - match value { - Tagged { - item: Value::List(list), - .. - } => { - for elem in list { - yield ReturnSuccess::value(elem); + }; + let mut result = converter.run(new_args.with_input(vec![tagged_contents]), ®istry); + let result_vec: Vec> = result.drain_vec().await; + for res in result_vec { + match res { + Ok(ReturnSuccess::Value(Tagged { item: Value::List(list), ..})) => { + for l in list { + yield Ok(ReturnSuccess::Value(l)); + } } + Ok(ReturnSuccess::Value(Tagged { item, .. })) => { + yield Ok(ReturnSuccess::Value(Tagged { item: item, tag: contents_tag })); + } + x => yield x, } - x => yield ReturnSuccess::value(x), } + } else { + yield ReturnSuccess::value(tagged_contents); } - other => yield ReturnSuccess::value(other.tagged(contents_tag)), - }; + } else { + yield ReturnSuccess::value(tagged_contents); + } }; Ok(stream.to_output_stream()) @@ -419,124 +432,3 @@ fn read_be_u16(input: &[u8]) -> Option> { Some(result) } } - -pub fn parse_string_as_value( - extension: Option, - contents: String, - contents_tag: Tag, - name_span: Span, -) -> Result, ShellError> { - match extension { - Some(ref x) if x == "csv" => { - crate::commands::from_csv::from_csv_string_to_value(contents, false, contents_tag) - .map_err(move |_| { - ShellError::labeled_error( - "Could not open as CSV", - "could not open as CSV", - name_span, - ) - }) - } - Some(ref x) if x == "tsv" => { - crate::commands::from_tsv::from_tsv_string_to_value(contents, false, contents_tag) - .map_err(move |_| { - ShellError::labeled_error( - "Could not open as TSV", - "could not open as TSV", - name_span, - ) - }) - } - Some(ref x) if x == "toml" => { - crate::commands::from_toml::from_toml_string_to_value(contents, contents_tag).map_err( - move |_| { - ShellError::labeled_error( - "Could not open as TOML", - "could not open as TOML", - name_span, - ) - }, - ) - } - Some(ref x) if x == "json" => { - crate::commands::from_json::from_json_string_to_value(contents, contents_tag).map_err( - move |_| { - ShellError::labeled_error( - "Could not open as JSON", - "could not open as JSON", - name_span, - ) - }, - ) - } - Some(ref x) if x == "ini" => crate::commands::from_ini::from_ini_string_to_value( - contents, - contents_tag, - ) - .map_err(move |_| { - ShellError::labeled_error("Could not open as INI", "could not open as INI", name_span) - }), - Some(ref x) if x == "xml" => crate::commands::from_xml::from_xml_string_to_value( - contents, - contents_tag, - ) - .map_err(move |_| { - ShellError::labeled_error("Could not open as XML", "could not open as XML", name_span) - }), - Some(ref x) if x == "yml" => { - crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_tag).map_err( - move |_| { - ShellError::labeled_error( - "Could not open as YAML", - "could not open as YAML", - name_span, - ) - }, - ) - } - Some(ref x) if x == "yaml" => { - crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_tag).map_err( - move |_| { - ShellError::labeled_error( - "Could not open as YAML", - "could not open as YAML", - name_span, - ) - }, - ) - } - _ => Ok(Value::string(contents).tagged(contents_tag)), - } -} - -pub fn parse_binary_as_value( - extension: Option, - contents: Vec, - contents_tag: Tag, - name_span: Span, -) -> Result, ShellError> { - match extension { - Some(ref x) if x == "bson" => { - crate::commands::from_bson::from_bson_bytes_to_value(contents, contents_tag).map_err( - move |_| { - ShellError::labeled_error( - "Could not open as BSON", - "could not open as BSON", - name_span, - ) - }, - ) - } - Some(ref x) if x == "db" => { - crate::commands::from_sqlite::from_sqlite_bytes_to_value(contents, contents_tag) - .map_err(move |_| { - ShellError::labeled_error( - "Could not open as SQLite", - "could not open as SQLite", - name_span, - ) - }) - } - _ => Ok(Value::Binary(contents).tagged(contents_tag)), - } -} diff --git a/src/commands/rm.rs b/src/commands/rm.rs index 9bbc3528..36f7aa6d 100644 --- a/src/commands/rm.rs +++ b/src/commands/rm.rs @@ -28,10 +28,10 @@ impl PerItemCommand for Remove { &self, call_info: &CallInfo, _registry: &CommandRegistry, - shell_manager: &ShellManager, + raw_args: &RawCommandArgs, _input: Tagged, ) -> Result { - call_info.process(shell_manager, rm)?.run() + call_info.process(&raw_args.shell_manager, rm)?.run() } } diff --git a/src/commands/save.rs b/src/commands/save.rs index 9a28931f..11b245ef 100644 --- a/src/commands/save.rs +++ b/src/commands/save.rs @@ -1,8 +1,4 @@ -use crate::commands::to_csv::{to_string as to_csv_to_string, value_to_csv_value}; -use crate::commands::to_tsv::{to_string as to_tsv_to_string, value_to_tsv_value}; -use crate::commands::to_json::value_to_json_value; -use crate::commands::to_toml::value_to_toml_value; -use crate::commands::to_yaml::value_to_yaml_value; +use crate::commands::UnevaluatedCallInfo; use crate::commands::WholeStreamCommand; use crate::errors::ShellError; use crate::object::Value; @@ -33,7 +29,7 @@ impl WholeStreamCommand for Save { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - args.process(registry, save)?.run() + Ok(args.process_raw(registry, save)?.run()) } } @@ -47,16 +43,19 @@ fn save( name, shell_manager, source_map, + host, + commands: registry, .. }: RunnableContext, + raw_args: RawCommandArgs, ) -> Result { let mut full_path = PathBuf::from(shell_manager.path()); let name_span = name; - if path.is_none() { - let source_map = source_map.clone(); - let stream = async_stream_block! { - let input: Vec> = input.values.collect().await; + let source_map = source_map.clone(); + let stream = async_stream_block! { + let input: Vec> = input.values.collect().await; + if path.is_none() { // If there is no filename, check the metadata for the origin filename if input.len() > 0 { let origin = input[0].origin(); @@ -88,50 +87,99 @@ fn save( name_span, )); } - - let content = if !save_raw { - to_string_for(full_path.extension(), &input) - } else { - string_from(&input) - }; - - match content { - Ok(save_data) => match std::fs::write(full_path, save_data) { - Ok(o) => o, - Err(e) => yield Err(ShellError::string(e.to_string())), - }, - Err(e) => yield Err(ShellError::string(e.to_string())), + } else { + if let Some(file) = path { + full_path.push(file.item()); } - - }; - - Ok(OutputStream::new(stream)) - } else { - if let Some(file) = path { - full_path.push(file.item()); } - let stream = async_stream_block! { - let input: Vec> = input.values.collect().await; - - let content = if !save_raw { - to_string_for(full_path.extension(), &input) + let content = if !save_raw { + if let Some(extension) = full_path.extension() { + let command_name = format!("to-{}", extension.to_str().unwrap()); + if let Some(converter) = registry.get_command(&command_name) { + let new_args = RawCommandArgs { + host: host, + shell_manager: shell_manager, + call_info: UnevaluatedCallInfo { + args: crate::parser::hir::Call { + head: raw_args.call_info.args.head, + positional: None, + named: None + }, + source: raw_args.call_info.source, + source_map: raw_args.call_info.source_map, + name_span: raw_args.call_info.name_span, + } + }; + let mut result = converter.run(new_args.with_input(input), ®istry); + let result_vec: Vec> = result.drain_vec().await; + let mut result_string = String::new(); + for res in result_vec { + match res { + Ok(ReturnSuccess::Value(Tagged { item: Value::Primitive(Primitive::String(s)), .. })) => { + result_string.push_str(&s); + } + _ => { + yield Err(ShellError::labeled_error( + "Save could not successfully save", + "unexpected data during saveS", + name_span, + )); + }, + } + } + Ok(result_string) + } else { + let mut result_string = String::new(); + for res in input { + match res { + Tagged { item: Value::Primitive(Primitive::String(s)), .. } => { + result_string.push_str(&s); + } + _ => { + yield Err(ShellError::labeled_error( + "Save could not successfully save", + "unexpected data during saveS", + name_span, + )); + }, + } + } + Ok(result_string) + } } else { - string_from(&input) - }; - - match content { - Ok(save_data) => match std::fs::write(full_path, save_data) { - Ok(o) => o, - Err(e) => yield Err(ShellError::string(e.to_string())), - }, - Err(e) => yield Err(ShellError::string(e.to_string())), + let mut result_string = String::new(); + for res in input { + match res { + Tagged { item: Value::Primitive(Primitive::String(s)), .. } => { + result_string.push_str(&s); + } + _ => { + yield Err(ShellError::labeled_error( + "Save could not successfully save", + "unexpected data during saveS", + name_span, + )); + }, + } + } + Ok(result_string) } - + } else { + string_from(&input) }; - Ok(OutputStream::new(stream)) - } + match content { + Ok(save_data) => match std::fs::write(full_path, save_data) { + Ok(o) => o, + Err(e) => yield Err(ShellError::string(e.to_string())), + }, + Err(e) => yield Err(ShellError::string(e.to_string())), + } + + }; + + Ok(OutputStream::new(stream)) } fn string_from(input: &Vec>) -> Result { @@ -153,66 +201,3 @@ fn string_from(input: &Vec>) -> Result { Ok(save_data) } - -fn to_string_for( - ext: Option<&std::ffi::OsStr>, - input: &Vec>, -) -> Result { - let contents = match ext { - Some(x) if x == "csv" => { - if input.len() != 1 { - return Err(ShellError::string( - "saving to csv requires a single object (or use --raw)", - )); - } - to_csv_to_string(&value_to_csv_value(&input[0]))? - } - Some(x) if x == "tsv" => { - if input.len() != 1 { - return Err(ShellError::string( - "saving to tsv requires a single object (or use --raw)", - )); - } - to_tsv_to_string(&value_to_tsv_value(&input[0]))? - } - Some(x) if x == "toml" => { - if input.len() != 1 { - return Err(ShellError::string( - "saving to toml requires a single object (or use --raw)", - )); - } - toml::to_string(&value_to_toml_value(&input[0]))? - } - Some(x) if x == "json" => { - if input.len() != 1 { - return Err(ShellError::string( - "saving to json requires a single object (or use --raw)", - )); - } - serde_json::to_string(&value_to_json_value(&input[0]))? - } - Some(x) if x == "yml" => { - if input.len() != 1 { - return Err(ShellError::string( - "saving to yml requires a single object (or use --raw)", - )); - } - serde_yaml::to_string(&value_to_yaml_value(&input[0]))? - } - Some(x) if x == "yaml" => { - if input.len() != 1 { - return Err(ShellError::string( - "saving to yaml requires a single object (or use --raw)", - )); - } - serde_yaml::to_string(&value_to_yaml_value(&input[0]))? - } - _ => { - return Err(ShellError::string( - "tried saving a single object with an unrecognized format.", - )) - } - }; - - Ok(contents) -} diff --git a/src/commands/to_sqlite.rs b/src/commands/to_sqlite.rs index 55e001b0..05a2e9c1 100644 --- a/src/commands/to_sqlite.rs +++ b/src/commands/to_sqlite.rs @@ -25,6 +25,26 @@ impl WholeStreamCommand for ToSQLite { } } +pub struct ToDB; + +impl WholeStreamCommand for ToDB { + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + to_sqlite(args, registry) + } + + fn name(&self) -> &str { + "to-db" + } + + fn signature(&self) -> Signature { + Signature::build("to-db") + } +} + fn comma_concat(acc: String, current: String) -> String { if acc == "" { current diff --git a/src/commands/where_.rs b/src/commands/where_.rs index 4be427a4..f1d9b200 100644 --- a/src/commands/where_.rs +++ b/src/commands/where_.rs @@ -19,7 +19,7 @@ impl PerItemCommand for Where { &self, call_info: &CallInfo, _registry: ®istry::CommandRegistry, - _shell_manager: &ShellManager, + _raw_args: &RawCommandArgs, input: Tagged, ) -> Result { let input_clone = input.clone(); diff --git a/src/parser/hir.rs b/src/parser/hir.rs index 6af67b27..5421d39c 100644 --- a/src/parser/hir.rs +++ b/src/parser/hir.rs @@ -39,11 +39,11 @@ pub fn path(head: impl Into, tail: Vec>>) - #[derive(Debug, Clone, Eq, PartialEq, Getters, Serialize, Deserialize, new)] pub struct Call { #[get = "crate"] - head: Box, + pub head: Box, #[get = "crate"] - positional: Option>, + pub positional: Option>, #[get = "crate"] - named: Option, + pub named: Option, } impl Call { diff --git a/src/prelude.rs b/src/prelude.rs index 49084355..2e4a9d34 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -52,6 +52,7 @@ pub(crate) use crate::commands::command::{ CallInfo, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, RunnableContext, }; pub(crate) use crate::commands::PerItemCommand; +pub(crate) use crate::commands::RawCommandArgs; pub(crate) use crate::context::CommandRegistry; pub(crate) use crate::context::{Context, SpanSource}; pub(crate) use crate::env::host::handle_unexpected;