forked from extern/nushell
Begin migration away from arg serialization (#3281)
* initial implementation * Move a few commands over to new arg system * Fix char also
This commit is contained in:
@ -7,13 +7,6 @@ use nu_source::Tagged;
|
||||
|
||||
pub struct Command;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AnsiArgs {
|
||||
code: Value,
|
||||
escape: Option<Tagged<String>>,
|
||||
osc: Option<Tagged<String>>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for Command {
|
||||
fn name(&self) -> &str {
|
||||
"ansi"
|
||||
@ -120,9 +113,14 @@ Format: #
|
||||
}
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let (AnsiArgs { code, escape, osc }, _) = args.process()?;
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
let code: Option<Result<Tagged<String>, ShellError>> = args.opt(0);
|
||||
let escape: Option<Result<Tagged<String>, ShellError>> = args.get_flag("escape");
|
||||
let osc: Option<Result<Tagged<String>, ShellError>> = args.get_flag("osc");
|
||||
|
||||
if let Some(e) = escape {
|
||||
let e = e?;
|
||||
let esc_vec: Vec<char> = e.item.chars().collect();
|
||||
if esc_vec[0] == '\\' {
|
||||
return Err(ShellError::labeled_error(
|
||||
@ -138,6 +136,7 @@ Format: #
|
||||
}
|
||||
|
||||
if let Some(o) = osc {
|
||||
let o = o?;
|
||||
let osc_vec: Vec<char> = o.item.chars().collect();
|
||||
if osc_vec[0] == '\\' {
|
||||
return Err(ShellError::labeled_error(
|
||||
@ -155,25 +154,33 @@ Format: #
|
||||
)));
|
||||
}
|
||||
|
||||
let code_string = code.as_string()?;
|
||||
let ansi_code = str_to_ansi(code_string);
|
||||
if let Some(code) = code {
|
||||
let code = code?;
|
||||
let ansi_code = str_to_ansi(&code.item);
|
||||
|
||||
if let Some(output) = ansi_code {
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(output).into_value(code.tag()),
|
||||
)))
|
||||
if let Some(output) = ansi_code {
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(output).into_value(code.tag()),
|
||||
)))
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"Unknown ansi code",
|
||||
"unknown ansi code",
|
||||
code.tag(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"Unknown ansi code",
|
||||
"unknown ansi code",
|
||||
code.tag(),
|
||||
"Expected ansi code",
|
||||
"expect ansi code",
|
||||
args.call_info.name_tag.clone(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn str_to_ansi(s: String) -> Option<String> {
|
||||
match s.as_str() {
|
||||
pub fn str_to_ansi(s: &str) -> Option<String> {
|
||||
match s {
|
||||
"g" | "green" => Some(Color::Green.prefix().to_string()),
|
||||
"gb" | "green_bold" => Some(Color::Green.bold().prefix().to_string()),
|
||||
"gu" | "green_underline" => Some(Color::Green.underline().prefix().to_string()),
|
||||
|
@ -5,11 +5,6 @@ use nu_data::value::format_leaf;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct BuildStringArgs {
|
||||
rest: Vec<Value>,
|
||||
}
|
||||
|
||||
pub struct BuildString;
|
||||
|
||||
impl WholeStreamCommand for BuildString {
|
||||
@ -28,7 +23,8 @@ impl WholeStreamCommand for BuildString {
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (BuildStringArgs { rest }, _) = args.process()?;
|
||||
let args = args.evaluate_once()?;
|
||||
let rest: Vec<Value> = args.rest(0)?;
|
||||
|
||||
let mut output_string = String::new();
|
||||
|
||||
|
@ -75,7 +75,7 @@ pub fn cal(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut selected_year: i32 = current_year;
|
||||
let mut current_day_option: Option<u32> = Some(current_day);
|
||||
|
||||
let month_range = if let Some(full_year_value) = args.get("full-year") {
|
||||
let month_range = if let Some(full_year_value) = args.call_info.args.get("full-year") {
|
||||
if let Ok(year_u64) = full_year_value.as_u64() {
|
||||
selected_year = year_u64 as i32;
|
||||
|
||||
@ -209,7 +209,7 @@ fn add_month_to_table(
|
||||
|
||||
let month_helper = match month_helper_result {
|
||||
Ok(month_helper) => month_helper,
|
||||
Err(()) => match args.get("full-year") {
|
||||
Err(()) => match args.call_info.args.get("full-year") {
|
||||
Some(full_year_value) => {
|
||||
return Err(get_invalid_year_shell_error(&full_year_value.tag()))
|
||||
}
|
||||
@ -235,7 +235,7 @@ fn add_month_to_table(
|
||||
|
||||
let mut week_start_day = days_of_the_week[0].to_string();
|
||||
|
||||
if let Some(week_start_value) = args.get("week-start") {
|
||||
if let Some(week_start_value) = args.call_info.args.get("week-start") {
|
||||
if let Ok(day) = week_start_value.as_string() {
|
||||
if days_of_the_week.contains(&day.as_str()) {
|
||||
week_start_day = day;
|
||||
@ -264,10 +264,10 @@ fn add_month_to_table(
|
||||
let mut day_number: u32 = 1;
|
||||
let day_limit: u32 = total_start_offset + month_helper.number_of_days_in_month;
|
||||
|
||||
let should_show_year_column = args.has("year");
|
||||
let should_show_quarter_column = args.has("quarter");
|
||||
let should_show_month_column = args.has("month");
|
||||
let should_show_month_names = args.has("month-names");
|
||||
let should_show_year_column = args.has_flag("year");
|
||||
let should_show_quarter_column = args.has_flag("quarter");
|
||||
let should_show_month_column = args.has_flag("month");
|
||||
let should_show_month_names = args.has_flag("month-names");
|
||||
|
||||
while day_number <= day_limit {
|
||||
let mut indexmap = IndexMap::new();
|
||||
|
@ -1,18 +1,11 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_engine::{FromValue, WholeStreamCommand};
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct Char;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct CharArgs {
|
||||
name: Tagged<String>,
|
||||
rest: Vec<Tagged<String>>,
|
||||
unicode: bool,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for Char {
|
||||
fn name(&self) -> &str {
|
||||
"char"
|
||||
@ -65,14 +58,11 @@ impl WholeStreamCommand for Char {
|
||||
}
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let (
|
||||
CharArgs {
|
||||
name,
|
||||
rest,
|
||||
unicode,
|
||||
},
|
||||
_,
|
||||
) = args.process()?;
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
let name: Tagged<String> = args.req(0)?;
|
||||
let rest: Vec<Value> = args.rest(1)?;
|
||||
let unicode = args.has_flag("unicode");
|
||||
|
||||
if unicode {
|
||||
if !rest.is_empty() {
|
||||
@ -86,6 +76,7 @@ impl WholeStreamCommand for Char {
|
||||
}
|
||||
// Get the rest of the bytes
|
||||
for byte_part in rest {
|
||||
let byte_part: Tagged<String> = FromValue::from_value(&byte_part)?;
|
||||
let decoded_char = string_to_unicode_char(&byte_part, &byte_part.tag);
|
||||
match decoded_char {
|
||||
Ok(ch) => multi_byte.push(ch),
|
||||
|
@ -6,16 +6,9 @@ use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
hir::CapturedBlock, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct Each;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct EachArgs {
|
||||
block: CapturedBlock,
|
||||
numbered: Tagged<bool>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for Each {
|
||||
fn name(&self) -> &str {
|
||||
"each"
|
||||
@ -110,12 +103,16 @@ pub(crate) fn make_indexed_item(index: usize, item: Value) -> Value {
|
||||
|
||||
fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
let args = raw_args.evaluate_once()?;
|
||||
|
||||
let (each_args, input): (EachArgs, _) = raw_args.process()?;
|
||||
let block = Arc::new(Box::new(each_args.block));
|
||||
let block: CapturedBlock = args.req(0)?;
|
||||
let numbered: bool = args.has_flag("numbered");
|
||||
|
||||
if each_args.numbered.item {
|
||||
Ok(input
|
||||
let block = Arc::new(Box::new(block));
|
||||
|
||||
if numbered {
|
||||
Ok(args
|
||||
.input
|
||||
.enumerate()
|
||||
.map(move |input| {
|
||||
let block = block.clone();
|
||||
@ -130,7 +127,8 @@ fn each(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
.flatten()
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Ok(input
|
||||
Ok(args
|
||||
.input
|
||||
.map(move |input| {
|
||||
let block = block.clone();
|
||||
let context = context.clone();
|
||||
|
@ -8,11 +8,6 @@ use nu_protocol::{
|
||||
|
||||
pub struct Echo;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct EchoArgs {
|
||||
pub rest: Vec<Value>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for Echo {
|
||||
fn name(&self) -> &str {
|
||||
"echo"
|
||||
@ -47,9 +42,10 @@ impl WholeStreamCommand for Echo {
|
||||
}
|
||||
|
||||
fn echo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let (args, _): (EchoArgs, _) = args.process()?;
|
||||
let args = args.evaluate_once()?;
|
||||
let rest: Vec<Value> = args.rest(0)?;
|
||||
|
||||
let stream = args.rest.into_iter().map(|i| match i.as_string() {
|
||||
let stream = rest.into_iter().map(|i| match i.as_string() {
|
||||
Ok(s) => OutputStream::one(Ok(ReturnSuccess::Value(
|
||||
UntaggedValue::string(s).into_value(i.tag.clone()),
|
||||
))),
|
||||
|
@ -9,13 +9,6 @@ use nu_protocol::{
|
||||
|
||||
pub struct If;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IfArgs {
|
||||
condition: CapturedBlock,
|
||||
then_case: CapturedBlock,
|
||||
else_case: CapturedBlock,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for If {
|
||||
fn name(&self) -> &str {
|
||||
"if"
|
||||
@ -67,14 +60,12 @@ fn if_command(raw_args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = raw_args.call_info.name_tag.clone();
|
||||
let context = Arc::new(EvaluationContext::from_args(&raw_args));
|
||||
|
||||
let (
|
||||
IfArgs {
|
||||
condition,
|
||||
then_case,
|
||||
else_case,
|
||||
},
|
||||
input,
|
||||
) = raw_args.process()?;
|
||||
let args = raw_args.evaluate_once()?;
|
||||
let condition: CapturedBlock = args.req(0)?;
|
||||
let then_case: CapturedBlock = args.req(1)?;
|
||||
let else_case: CapturedBlock = args.req(2)?;
|
||||
let input = args.input;
|
||||
|
||||
let cond = {
|
||||
if condition.block.block.len() != 1 {
|
||||
return Err(ShellError::labeled_error(
|
||||
|
@ -7,13 +7,6 @@ use nu_source::Tagged;
|
||||
|
||||
pub struct Let;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct LetArgs {
|
||||
pub name: Tagged<String>,
|
||||
pub equals: Tagged<String>,
|
||||
pub rhs: CapturedBlock,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for Let {
|
||||
fn name(&self) -> &str {
|
||||
"let"
|
||||
@ -46,8 +39,11 @@ impl WholeStreamCommand for Let {
|
||||
pub fn letcmd(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let args = args.evaluate_once()?;
|
||||
|
||||
let (LetArgs { name, rhs, .. }, _) = args.process()?;
|
||||
//let (LetArgs { name, rhs, .. }, _) = args.process()?;
|
||||
let name: Tagged<String> = args.req(0)?;
|
||||
let rhs: CapturedBlock = args.req(2)?;
|
||||
|
||||
let (expr, captured) = {
|
||||
if rhs.block.block.len() != 1 {
|
||||
|
@ -111,99 +111,6 @@ impl Iterator for SleepIterator {
|
||||
}
|
||||
}
|
||||
|
||||
// struct SleepHandler {
|
||||
// shared_state: Arc<Mutex<SharedState>>,
|
||||
// }
|
||||
|
||||
// impl SleepHandler {
|
||||
// /// Create a new `SleepHandler` which will complete after the provided
|
||||
// /// timeout and check for Ctrl+C periodically.
|
||||
// pub fn new(duration: Duration, ctrl_c: Arc<AtomicBool>) -> Self {
|
||||
// let shared_state = Arc::new(Mutex::new(SharedState {
|
||||
// done: false,
|
||||
// waker: None,
|
||||
// }));
|
||||
|
||||
// // Spawn the main sleep thread
|
||||
// let thread_shared_state = shared_state.clone();
|
||||
// thread::spawn(move || {
|
||||
// thread::sleep(duration);
|
||||
// let mut shared_state = thread_shared_state.lock();
|
||||
// // Signal that the timer has completed and wake up the last
|
||||
// // task on which the future was polled, if one exists.
|
||||
// if !shared_state.done {
|
||||
// shared_state.done = true;
|
||||
// if let Some(waker) = shared_state.waker.take() {
|
||||
// waker.wake()
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// // Spawn the Ctrl+C-watching polling thread
|
||||
// let thread_shared_state = shared_state.clone();
|
||||
// thread::spawn(move || {
|
||||
// loop {
|
||||
// {
|
||||
// let mut shared_state = thread_shared_state.lock();
|
||||
// // exit if the main thread is done
|
||||
// if shared_state.done {
|
||||
// return;
|
||||
// }
|
||||
// // finish the future prematurely if Ctrl+C has been pressed
|
||||
// if ctrl_c.load(Ordering::SeqCst) {
|
||||
// shared_state.done = true;
|
||||
// if let Some(waker) = shared_state.waker.take() {
|
||||
// waker.wake()
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// // sleep for a short time
|
||||
// thread::sleep(CTRL_C_CHECK_INTERVAL);
|
||||
// }
|
||||
// });
|
||||
|
||||
// SleepHandler { shared_state }
|
||||
// }
|
||||
// }
|
||||
|
||||
// struct SharedState {
|
||||
// done: bool,
|
||||
// }
|
||||
|
||||
// impl Iterator for SleepHandler {
|
||||
// type Item = ();
|
||||
|
||||
// fn next(&mut self) -> Option<Self::Item> {
|
||||
// let mut shared_state = self.shared_state.lock();
|
||||
// loop {
|
||||
// if shared_state.done {
|
||||
// return None;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// impl Future for SleepHandler {
|
||||
// type Output = ();
|
||||
|
||||
// fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
|
||||
// // Look at the shared state to see if the timer has already completed.
|
||||
// Poll::Ready(())
|
||||
// } else {
|
||||
// // Set the waker if necessary
|
||||
// if shared_state
|
||||
// .waker
|
||||
// .as_ref()
|
||||
// .map(|waker| !waker.will_wake(&cx.waker()))
|
||||
// .unwrap_or(true)
|
||||
// {
|
||||
// shared_state.waker = Some(cx.waker().clone());
|
||||
// }
|
||||
// Poll::Pending
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Sleep;
|
||||
|
@ -6,11 +6,6 @@ use nu_source::Tagged;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct SubCommandArgs {
|
||||
separator: Option<Tagged<String>>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"str collect"
|
||||
@ -43,8 +38,15 @@ impl WholeStreamCommand for SubCommand {
|
||||
|
||||
pub fn collect(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (SubCommandArgs { separator }, input) = args.process()?;
|
||||
let separator = separator.map(|tagged| tagged.item).unwrap_or_default();
|
||||
//let (SubCommandArgs { separator }, input) = args.process()?;
|
||||
let args = args.evaluate_once()?;
|
||||
let separator: Option<Result<Tagged<String>, ShellError>> = args.opt(0);
|
||||
let input = args.input;
|
||||
let separator = if let Some(separator) = separator {
|
||||
separator?.item
|
||||
} else {
|
||||
"".into()
|
||||
};
|
||||
|
||||
let strings: Vec<Result<String, ShellError>> = input.map(|value| value.as_string()).collect();
|
||||
let strings: Result<Vec<_>, _> = strings.into_iter().collect::<Result<_, _>>();
|
||||
|
@ -4,7 +4,7 @@ use crate::primitive::get_color_config;
|
||||
use nu_data::value::{format_leaf, style_leaf};
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_table::{draw_table, Alignment, StyledString, TextStyle};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::Ordering;
|
||||
@ -169,22 +169,10 @@ fn table(configuration: TableConfiguration, args: CommandArgs) -> Result<OutputS
|
||||
// config.toml.... yet.
|
||||
let color_hm = get_color_config();
|
||||
|
||||
let mut start_number = match args.get("start_number") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::Int(i)),
|
||||
..
|
||||
}) => {
|
||||
if let Some(num) = i.to_usize() {
|
||||
num
|
||||
} else {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Expected a row number",
|
||||
"expected a row number",
|
||||
&args.args.call_info.name_tag,
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => 0,
|
||||
let mut start_number = if let Some(f) = args.get_flag("start_number") {
|
||||
f?
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let mut delay_slot = None;
|
||||
|
@ -55,7 +55,7 @@ impl WholeStreamCommand for Uniq {
|
||||
|
||||
fn uniq(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once()?;
|
||||
let should_show_count = args.has("count");
|
||||
let should_show_count = args.has_flag("count");
|
||||
let input = args.input;
|
||||
let uniq_values = {
|
||||
let mut counter = IndexMap::<nu_protocol::Value, usize>::new();
|
||||
|
Reference in New Issue
Block a user