mirror of
https://github.com/nushell/nushell
synced 2024-12-27 05:23:11 +00:00
WIP supporting from/to automatically
This commit is contained in:
parent
fcc41af899
commit
f730296e45
14 changed files with 90 additions and 170 deletions
|
@ -194,6 +194,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||
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),
|
||||
|
|
|
@ -80,6 +80,7 @@ crate use from_json::FromJSON;
|
|||
crate use from_toml::FromTOML;
|
||||
crate use from_xml::FromXML;
|
||||
crate use from_yaml::FromYAML;
|
||||
crate use from_yaml::FromYML;
|
||||
crate use get::Get;
|
||||
crate use last::Last;
|
||||
crate use lines::Lines;
|
||||
|
|
|
@ -162,7 +162,7 @@ impl InternalCommand {
|
|||
|
||||
let full_path = std::path::PathBuf::from(cwd);
|
||||
|
||||
let (file_extension, contents, contents_tag, span_source) =
|
||||
let (_file_extension, contents, contents_tag, span_source) =
|
||||
crate::commands::open::fetch(
|
||||
&full_path,
|
||||
&location,
|
||||
|
@ -175,23 +175,11 @@ impl InternalCommand {
|
|||
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(ValueShell::new(
|
||||
contents.tagged(contents_tag),
|
||||
)))
|
||||
}
|
||||
}
|
||||
CommandAction::PreviousShell => {
|
||||
|
|
|
@ -512,7 +512,7 @@ pub trait PerItemCommand: Send + Sync {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
registry: &CommandRegistry,
|
||||
shell_manager: &ShellManager,
|
||||
raw_args: &RawCommandArgs,
|
||||
input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError>;
|
||||
|
||||
|
@ -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)),
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ impl PerItemCommand for Cpy {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
_registry: &CommandRegistry,
|
||||
shell_manager: &ShellManager,
|
||||
raw_args: &RawCommandArgs,
|
||||
_input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
call_info.process(shell_manager, cp)?.run()
|
||||
call_info.process(&raw_args.shell_manager, cp)?.run()
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
|
|
|
@ -19,7 +19,7 @@ impl PerItemCommand for Enter {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
_registry: ®istry::CommandRegistry,
|
||||
_shell_manager: &ShellManager,
|
||||
_raw_args: &RawCommandArgs,
|
||||
_input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
match call_info.args.expect_nth(0)? {
|
||||
|
|
|
@ -23,6 +23,26 @@ impl WholeStreamCommand for FromYAML {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct FromYML;
|
||||
|
||||
impl WholeStreamCommand for FromYML {
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
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<Tag>) -> Tagged<Value> {
|
||||
let tag = tag.into();
|
||||
|
||||
|
|
|
@ -16,10 +16,10 @@ impl PerItemCommand for Mkdir {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
_registry: &CommandRegistry,
|
||||
shell_manager: &ShellManager,
|
||||
raw_args: &RawCommandArgs,
|
||||
_input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
call_info.process(shell_manager, mkdir)?.run()
|
||||
call_info.process(&raw_args.shell_manager, mkdir)?.run()
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
|
|
|
@ -29,10 +29,10 @@ impl PerItemCommand for Move {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
_registry: &CommandRegistry,
|
||||
shell_manager: &ShellManager,
|
||||
raw_args: &RawCommandArgs,
|
||||
_input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
call_info.process(shell_manager, mv)?.run()
|
||||
call_info.process(&raw_args.shell_manager, mv)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
run(call_info, shell_manager)
|
||||
run(call_info, registry, raw_args)
|
||||
}
|
||||
}
|
||||
|
||||
fn run(call_info: &CallInfo, shell_manager: &ShellManager) -> Result<OutputStream, ShellError> {
|
||||
fn run(
|
||||
call_info: &CallInfo,
|
||||
registry: &CommandRegistry,
|
||||
raw_args: &RawCommandArgs,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
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<OutputStrea
|
|||
let path_buf = path.as_path()?;
|
||||
let path_str = path_buf.display().to_string();
|
||||
let path_span = path.span();
|
||||
let name_span = call_info.name_span;
|
||||
let has_raw = call_info.args.has("raw");
|
||||
let registry = registry.clone();
|
||||
let raw_args = raw_args.clone();
|
||||
|
||||
let stream = async_stream_block! {
|
||||
|
||||
|
@ -65,7 +72,6 @@ fn run(call_info: &CallInfo, shell_manager: &ShellManager) -> Result<OutputStrea
|
|||
file_extension.or(path_str.split('.').last().map(String::from))
|
||||
};
|
||||
|
||||
|
||||
if let Some(uuid) = contents_tag.origin {
|
||||
// If we have loaded something, track its source
|
||||
yield ReturnSuccess::action(CommandAction::AddSpanSource(
|
||||
|
@ -74,39 +80,41 @@ fn run(call_info: &CallInfo, shell_manager: &ShellManager) -> Result<OutputStrea
|
|||
));
|
||||
}
|
||||
|
||||
match contents {
|
||||
Value::Primitive(Primitive::String(string)) => {
|
||||
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<ReturnSuccess, ShellError>> = result.drain_vec().await;
|
||||
for res in result_vec {
|
||||
match res {
|
||||
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,104 +427,3 @@ fn read_be_u16(input: &[u8]) -> Option<Vec<u16>> {
|
|||
Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_string_as_value(
|
||||
extension: Option<String>,
|
||||
contents: String,
|
||||
contents_tag: Tag,
|
||||
name_span: Span,
|
||||
) -> Result<Tagged<Value>, 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 == "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<String>,
|
||||
contents: Vec<u8>,
|
||||
contents_tag: Tag,
|
||||
name_span: Span,
|
||||
) -> Result<Tagged<Value>, 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,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
_ => Ok(Value::Binary(contents).tagged(contents_tag)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@ impl PerItemCommand for Remove {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
_registry: &CommandRegistry,
|
||||
shell_manager: &ShellManager,
|
||||
raw_args: &RawCommandArgs,
|
||||
_input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
call_info.process(shell_manager, rm)?.run()
|
||||
call_info.process(&raw_args.shell_manager, rm)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ impl PerItemCommand for Where {
|
|||
&self,
|
||||
call_info: &CallInfo,
|
||||
_registry: ®istry::CommandRegistry,
|
||||
_shell_manager: &ShellManager,
|
||||
_raw_args: &RawCommandArgs,
|
||||
input: Tagged<Value>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let input_clone = input.clone();
|
||||
|
|
|
@ -39,11 +39,11 @@ pub fn path(head: impl Into<Expression>, tail: Vec<Tagged<impl Into<String>>>) -
|
|||
#[derive(Debug, Clone, Eq, PartialEq, Getters, Serialize, Deserialize, new)]
|
||||
pub struct Call {
|
||||
#[get = "crate"]
|
||||
head: Box<Expression>,
|
||||
pub head: Box<Expression>,
|
||||
#[get = "crate"]
|
||||
positional: Option<Vec<Expression>>,
|
||||
pub positional: Option<Vec<Expression>>,
|
||||
#[get = "crate"]
|
||||
named: Option<NamedArguments>,
|
||||
pub named: Option<NamedArguments>,
|
||||
}
|
||||
|
||||
impl Call {
|
||||
|
|
|
@ -51,7 +51,7 @@ crate use crate::cli::MaybeOwned;
|
|||
crate use crate::commands::command::{
|
||||
CallInfo, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, RunnableContext,
|
||||
};
|
||||
crate use crate::commands::PerItemCommand;
|
||||
crate use crate::commands::{PerItemCommand, RawCommandArgs};
|
||||
crate use crate::context::CommandRegistry;
|
||||
crate use crate::context::{Context, SpanSource};
|
||||
crate use crate::env::host::handle_unexpected;
|
||||
|
|
Loading…
Reference in a new issue