From 1dc8f3300e3000b8687aca736598de4edcbd9383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20V=C3=ADt?= Date: Thu, 17 Sep 2020 01:34:37 +0200 Subject: [PATCH] Make the sleep command pass data through. (#2558) --- crates/nu-cli/src/commands/sleep.rs | 40 +++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/crates/nu-cli/src/commands/sleep.rs b/crates/nu-cli/src/commands/sleep.rs index bd9ba31d1f..1a5dab8a95 100644 --- a/crates/nu-cli/src/commands/sleep.rs +++ b/crates/nu-cli/src/commands/sleep.rs @@ -2,7 +2,7 @@ use crate::commands::WholeStreamCommand; use crate::context::CommandRegistry; use crate::prelude::*; use nu_errors::ShellError; -use nu_protocol::{Signature, SyntaxShape}; +use nu_protocol::{Signature, SyntaxShape, UntaggedValue}; use nu_source::Tagged; use parking_lot::Mutex; use std::{ @@ -20,7 +20,7 @@ pub struct Sleep; #[derive(Deserialize)] pub struct SleepArgs { - pub dur: Tagged, + pub duration: Tagged, pub rest: Vec>, } @@ -48,12 +48,23 @@ impl WholeStreamCommand for Sleep { let registry = registry.clone(); let ctrl_c = args.ctrl_c().clone(); - let (SleepArgs { dur, rest }, ..) = args.process(®istry).await?; + let (SleepArgs { duration, rest }, input) = args.process(®istry).await?; - let total_dur = dur.item + rest.iter().map(|val| val.item).sum::(); - let total_dur = Duration::from_nanos(total_dur); + let total_dur = Duration::from_nanos(duration.item) + + rest + .iter() + .map(|val| Duration::from_nanos(val.item)) + .sum::(); - SleepFuture::new(total_dur, ctrl_c).await + SleepFuture::new(total_dur, ctrl_c).await; + // this is necessary because the following 2 commands gave different results: + // `echo | sleep 1sec` - nothing + // `sleep 1sec` - table with 0 elements + if input.is_empty() { + Ok(OutputStream::empty()) + } else { + Ok(input.into()) + } } fn examples(&self) -> Vec { @@ -68,6 +79,14 @@ impl WholeStreamCommand for Sleep { example: "sleep 1sec 1sec 1sec", result: None, }, + Example { + description: "Delay the output of another command by 1sec", + example: "echo [55 120] | sleep 1sec", + result: Some(vec![ + UntaggedValue::int(55).into(), + UntaggedValue::int(120).into(), + ]), + }, ] } } @@ -134,13 +153,13 @@ struct SharedState { } impl Future for SleepFuture { - type Output = Result; + type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { // Look at the shared state to see if the timer has already completed. let mut shared_state = self.shared_state.lock(); if shared_state.done { - Poll::Ready(Ok(OutputStream::empty())) + Poll::Ready(()) } else { // Set the waker if necessary if shared_state @@ -162,7 +181,6 @@ mod tests { use std::time::Instant; #[test] - #[ignore] fn examples_work_as_expected() { use crate::examples::test as test_examples; @@ -170,6 +188,8 @@ mod tests { test_examples(Sleep {}); let elapsed = start.elapsed(); println!("{:?}", elapsed); - assert!(elapsed >= std::time::Duration::from_secs(4)); + // only examples with actual output are run + assert!(elapsed >= std::time::Duration::from_secs(1)); + assert!(elapsed < std::time::Duration::from_secs(2)); } }