mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 22:59:52 +02:00
WIP - types check
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::commands::{RawCommandArgs, StaticCommand};
|
||||
use crate::context::{SourceMap, SpanSource};
|
||||
use crate::errors::ShellError;
|
||||
use crate::format::GenericView;
|
||||
@@ -7,6 +7,9 @@ use std::path::Path;
|
||||
|
||||
pub struct Autoview;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AutoviewArgs {}
|
||||
|
||||
impl StaticCommand for Autoview {
|
||||
fn name(&self) -> &str {
|
||||
"autoview"
|
||||
@@ -17,37 +20,49 @@ impl StaticCommand for Autoview {
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, autoview)?.run()
|
||||
args.process_raw(registry, autoview)?.run()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("autoview").sink()
|
||||
Signature::build("autoview")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn autoview(args: (), context: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
if args.input.len() > 0 {
|
||||
if let Spanned {
|
||||
item: Value::Binary(_),
|
||||
..
|
||||
} = args.input[0]
|
||||
{
|
||||
args.ctx.get_sink("binaryview").run(args)?;
|
||||
} else if is_single_text_value(&args.input) {
|
||||
view_text_value(&args.input[0], &args.call_info.source_map);
|
||||
} else if equal_shapes(&args.input) {
|
||||
args.ctx.get_sink("table").run(args)?;
|
||||
} else {
|
||||
let mut host = args.ctx.host.lock().unwrap();
|
||||
for i in args.input.iter() {
|
||||
let view = GenericView::new(&i);
|
||||
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
||||
host.stdout("");
|
||||
pub fn autoview(
|
||||
AutoviewArgs {}: AutoviewArgs,
|
||||
mut context: RunnableContext,
|
||||
raw: RawCommandArgs,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let stream = async_stream_block! {
|
||||
let input = context.input.drain_vec().await;
|
||||
|
||||
if input.len() > 0 {
|
||||
if let Spanned {
|
||||
item: Value::Binary(_),
|
||||
..
|
||||
} = input[0]
|
||||
{
|
||||
let binary = context.expect_command("binaryview");
|
||||
binary.run(raw.with_input(input), &context.commands).await;
|
||||
} else if is_single_text_value(&input) {
|
||||
view_text_value(&input[0], &raw.call_info.source_map);
|
||||
} else if equal_shapes(&input) {
|
||||
let table = context.expect_command("table");
|
||||
table.run(raw.with_input(input), &context.commands).await;
|
||||
} else {
|
||||
println!("TODO!")
|
||||
// TODO
|
||||
// let mut host = context.host.lock().unwrap();
|
||||
// for i in input.iter() {
|
||||
// let view = GenericView::new(&i);
|
||||
// handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
||||
// host.stdout("");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(OutputStream::empty())
|
||||
Ok(OutputStream::new(stream))
|
||||
}
|
||||
|
||||
fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool {
|
||||
|
@@ -24,7 +24,7 @@ impl StaticCommand for Clip {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("clip").sink()
|
||||
Signature::build("clip")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -59,6 +59,25 @@ pub struct CommandArgs {
|
||||
pub input: InputStream,
|
||||
}
|
||||
|
||||
#[derive(Getters)]
|
||||
#[get = "crate"]
|
||||
pub struct RawCommandArgs {
|
||||
pub host: Arc<Mutex<dyn Host>>,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub call_info: UnevaluatedCallInfo,
|
||||
}
|
||||
|
||||
impl RawCommandArgs {
|
||||
pub fn with_input(self, input: Vec<Spanned<Value>>) -> CommandArgs {
|
||||
CommandArgs {
|
||||
host: self.host,
|
||||
env: self.env,
|
||||
call_info: self.call_info,
|
||||
input: input.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToDebug for CommandArgs {
|
||||
fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result {
|
||||
self.call_info.fmt_debug(f, source)
|
||||
@@ -88,6 +107,7 @@ impl CommandArgs {
|
||||
callback: fn(T, RunnableContext) -> Result<OutputStream, ShellError>,
|
||||
) -> Result<RunnableArgs<T>, ShellError> {
|
||||
let env = self.env.clone();
|
||||
let host = self.host.clone();
|
||||
let args = self.evaluate_once(registry)?;
|
||||
let (input, args) = args.split();
|
||||
let name_span = args.call_info.name_span;
|
||||
@@ -97,12 +117,46 @@ impl CommandArgs {
|
||||
args: T::deserialize(&mut deserializer)?,
|
||||
context: RunnableContext {
|
||||
input: input,
|
||||
commands: registry.clone(),
|
||||
env,
|
||||
name: name_span,
|
||||
host,
|
||||
},
|
||||
callback,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn process_raw<'de, T: Deserialize<'de>>(
|
||||
self,
|
||||
registry: &CommandRegistry,
|
||||
callback: fn(T, RunnableContext, RawCommandArgs) -> Result<OutputStream, ShellError>,
|
||||
) -> Result<RunnableRawArgs<T>, ShellError> {
|
||||
let raw_args = RawCommandArgs {
|
||||
host: self.host.clone(),
|
||||
env: self.env.clone(),
|
||||
call_info: self.call_info.clone(),
|
||||
};
|
||||
|
||||
let env = self.env.clone();
|
||||
let host = self.host.clone();
|
||||
let args = self.evaluate_once(registry)?;
|
||||
let (input, args) = args.split();
|
||||
let name_span = args.call_info.name_span;
|
||||
let mut deserializer = ConfigDeserializer::from_call_node(args);
|
||||
|
||||
Ok(RunnableRawArgs {
|
||||
args: T::deserialize(&mut deserializer)?,
|
||||
context: RunnableContext {
|
||||
input: input,
|
||||
commands: registry.clone(),
|
||||
env,
|
||||
name: name_span,
|
||||
host,
|
||||
},
|
||||
raw_args,
|
||||
callback,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SinkContext {
|
||||
@@ -120,6 +174,8 @@ pub struct SinkArgs<T> {
|
||||
pub struct RunnableContext {
|
||||
pub input: InputStream,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub host: Arc<Mutex<dyn Host>>,
|
||||
pub commands: CommandRegistry,
|
||||
pub name: Option<Span>,
|
||||
}
|
||||
|
||||
@@ -130,6 +186,12 @@ impl RunnableContext {
|
||||
|
||||
env.path.clone()
|
||||
}
|
||||
|
||||
pub fn expect_command(&self, name: &str) -> Arc<Command> {
|
||||
self.commands
|
||||
.get_command(name)
|
||||
.expect(&format!("Expected command {}", name))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RunnableArgs<T> {
|
||||
@@ -144,6 +206,19 @@ impl<T> RunnableArgs<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RunnableRawArgs<T> {
|
||||
args: T,
|
||||
raw_args: RawCommandArgs,
|
||||
context: RunnableContext,
|
||||
callback: fn(T, RunnableContext, RawCommandArgs) -> Result<OutputStream, ShellError>,
|
||||
}
|
||||
|
||||
impl<T> RunnableRawArgs<T> {
|
||||
pub fn run(self) -> Result<OutputStream, ShellError> {
|
||||
(self.callback)(self.args, self.context, self.raw_args)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EvaluatedStaticCommandArgs {
|
||||
pub args: EvaluatedCommandArgs,
|
||||
pub input: InputStream,
|
||||
|
@@ -30,7 +30,6 @@ impl StaticCommand for Config {
|
||||
.named("remove", SyntaxType::Any)
|
||||
.switch("clear")
|
||||
.switch("path")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
@@ -28,7 +28,6 @@ impl StaticCommand for Open {
|
||||
Signature::build(self.name())
|
||||
.required("path", SyntaxType::Block)
|
||||
.switch("raw")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
@@ -23,7 +23,6 @@ impl StaticCommand for Remove {
|
||||
Signature::build("rm")
|
||||
.required("path", SyntaxType::Path)
|
||||
.switch("recursive")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
@@ -7,13 +7,12 @@ use crate::errors::ShellError;
|
||||
use crate::object::{Primitive, Value};
|
||||
use crate::parser::Spanned;
|
||||
use crate::prelude::*;
|
||||
use futures_async_stream::async_stream_block;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub struct Save;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SaveArgs {
|
||||
pub struct SaveArgs {
|
||||
path: Spanned<PathBuf>,
|
||||
raw: bool,
|
||||
}
|
||||
@@ -27,7 +26,6 @@ impl StaticCommand for Save {
|
||||
Signature::build("save")
|
||||
.required("path", SyntaxType::Path)
|
||||
.switch("raw")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
@@ -55,7 +53,7 @@ pub fn save(
|
||||
let contents = match full_path.extension() {
|
||||
Some(x) if x == "csv" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
yield Err(ShellError::string(
|
||||
"saving to csv requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
@@ -63,7 +61,7 @@ pub fn save(
|
||||
}
|
||||
Some(x) if x == "toml" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
yield Err(ShellError::string(
|
||||
"saving to toml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
@@ -71,7 +69,7 @@ pub fn save(
|
||||
}
|
||||
Some(x) if x == "json" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
yield Err(ShellError::string(
|
||||
"saving to json requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
@@ -79,7 +77,7 @@ pub fn save(
|
||||
}
|
||||
Some(x) if x == "yml" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
yield Err(ShellError::string(
|
||||
"saving to yml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
@@ -87,7 +85,7 @@ pub fn save(
|
||||
}
|
||||
Some(x) if x == "yaml" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
yield Err(ShellError::string(
|
||||
"saving to yaml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
@@ -113,7 +111,5 @@ pub fn save(
|
||||
let _ = std::fs::write(full_path, contents);
|
||||
};
|
||||
|
||||
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
|
||||
|
||||
Ok(OutputStream::from(stream))
|
||||
Ok(OutputStream::new(stream))
|
||||
}
|
||||
|
@@ -1,15 +1,42 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::format::TableView;
|
||||
use crate::prelude::*;
|
||||
use futures_async_stream::async_stream_block;
|
||||
|
||||
pub fn table(args: CommandArgs, context: RunnableContext) -> Result<(), ShellError> {
|
||||
if args.input.len() > 0 {
|
||||
let mut host = args.ctx.host.lock().unwrap();
|
||||
let view = TableView::from_list(&args.input);
|
||||
if let Some(view) = view {
|
||||
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
||||
}
|
||||
pub struct Table;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct TableArgs {}
|
||||
|
||||
impl StaticCommand for Table {
|
||||
fn name(&self) -> &str {
|
||||
"table"
|
||||
}
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, table)?.run()
|
||||
}
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("table")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn table(_args: TableArgs, context: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
let stream = async_stream_block! {
|
||||
let input: Vec<Spanned<Value>> = context.input.into_vec().await;
|
||||
if input.len() > 0 {
|
||||
let mut host = context.host.lock().unwrap();
|
||||
let view = TableView::from_list(&input);
|
||||
println!("{:#?}", view);
|
||||
if let Some(view) = view {
|
||||
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(OutputStream::new(stream))
|
||||
}
|
||||
|
@@ -1,15 +1,41 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::format::VTableView;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn vtable(args: CommandArgs, context: RunnableContext) -> Result<(), ShellError> {
|
||||
if args.input.len() > 0 {
|
||||
let mut host = args.ctx.host.lock().unwrap();
|
||||
let view = VTableView::from_list(&args.input);
|
||||
if let Some(view) = view {
|
||||
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
||||
}
|
||||
}
|
||||
pub struct VTable;
|
||||
|
||||
Ok(())
|
||||
#[derive(Deserialize)]
|
||||
pub struct VTableArgs {}
|
||||
|
||||
impl StaticCommand for VTable {
|
||||
fn name(&self) -> &str {
|
||||
"vtable"
|
||||
}
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, vtable)?.run()
|
||||
}
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("vtable")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vtable(args: VTableArgs, context: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
let stream = async_stream_block! {
|
||||
let input = context.input.into_vec().await;
|
||||
|
||||
if input.len() > 0 {
|
||||
let mut host = context.host.lock().unwrap();
|
||||
let view = VTableView::from_list(&input);
|
||||
if let Some(view) = view {
|
||||
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(OutputStream::new(stream))
|
||||
}
|
||||
|
@@ -21,9 +21,7 @@ impl StaticCommand for Where {
|
||||
}
|
||||
|
||||
fn signature(&self) -> registry::Signature {
|
||||
Signature::build("where")
|
||||
.required("condition", SyntaxType::Block)
|
||||
.sink()
|
||||
Signature::build("where").required("condition", SyntaxType::Block)
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
Reference in New Issue
Block a user