diff --git a/crates/nu-command/src/experimental/job_recv.rs b/crates/nu-command/src/experimental/job_recv.rs index a3a250b275..aa13700780 100644 --- a/crates/nu-command/src/experimental/job_recv.rs +++ b/crates/nu-command/src/experimental/job_recv.rs @@ -78,9 +78,7 @@ in no particular order, regardless of the specified timeout parameter. let tag = tag_arg.map(|it| it.item as FilterTag); - let duration: Option = call.get_flag(engine_state, stack, "timeout")?; - - let timeout = duration.map(|it| Duration::from_nanos(it as u64)); + let timeout: Option = call.get_flag(engine_state, stack, "timeout")?; let mut mailbox = engine_state .current_job diff --git a/crates/nu-command/src/filesystem/watch.rs b/crates/nu-command/src/filesystem/watch.rs index 9dc759ea21..5599c39c51 100644 --- a/crates/nu-command/src/filesystem/watch.rs +++ b/crates/nu-command/src/filesystem/watch.rs @@ -119,42 +119,11 @@ impl Command for Watch { let debounce_duration_flag_ms: Option> = call.get_flag(engine_state, stack, "debounce-ms")?; - let debounce_duration_flag: Option> = + let debounce_duration_flag: Option> = call.get_flag(engine_state, stack, "debounce")?; - let debounce_duration: Duration = match (debounce_duration_flag, debounce_duration_flag_ms) - { - (None, None) => DEFAULT_WATCH_DEBOUNCE_DURATION, - (Some(l), Some(r)) => { - return Err(ShellError::IncompatibleParameters { - left_message: "Here".to_string(), - left_span: l.span, - right_message: "and here".to_string(), - right_span: r.span, - }); - } - (None, Some(val)) => match u64::try_from(val.item) { - Ok(v) => Duration::from_millis(v), - Err(_) => { - return Err(ShellError::TypeMismatch { - err_message: "Debounce duration is invalid".to_string(), - span: val.span, - }); - } - }, - (Some(v), None) => { - let Value::Duration { val, .. } = v.item else { - return Err(ShellError::TypeMismatch { - err_message: "Debounce duration must be a duration".to_string(), - span: v.item.span(), - }); - }; - Duration::from_nanos(u64::try_from(val).map_err(|_| ShellError::TypeMismatch { - err_message: "Debounce duration is invalid".to_string(), - span: v.item.span(), - })?) - } - }; + let debounce_duration: Duration = + resolve_duration_arguments(debounce_duration_flag_ms, debounce_duration_flag)?; let glob_flag: Option> = call.get_flag(engine_state, stack, "glob")?; let glob_pattern = match glob_flag { @@ -353,3 +322,26 @@ impl Command for Watch { ] } } + +fn resolve_duration_arguments( + debounce_duration_flag_ms: Option>, + debounce_duration_flag: Option>, +) -> Result { + match (debounce_duration_flag, debounce_duration_flag_ms) { + (None, None) => Ok(DEFAULT_WATCH_DEBOUNCE_DURATION), + (Some(l), Some(r)) => Err(ShellError::IncompatibleParameters { + left_message: "Here".to_string(), + left_span: l.span, + right_message: "and here".to_string(), + right_span: r.span, + }), + (None, Some(val)) => match u64::try_from(val.item) { + Ok(v) => Ok(Duration::from_millis(v)), + Err(_) => Err(ShellError::TypeMismatch { + err_message: "Debounce duration is invalid".to_string(), + span: val.span, + }), + }, + (Some(v), None) => Ok(v.item), + } +} diff --git a/crates/nu-protocol/src/value/from_value.rs b/crates/nu-protocol/src/value/from_value.rs index 708f1f69c5..1822abbcda 100644 --- a/crates/nu-protocol/src/value/from_value.rs +++ b/crates/nu-protocol/src/value/from_value.rs @@ -275,6 +275,29 @@ impl FromValue for i64 { } } +/// This implementation supports **positive** durations only. +impl FromValue for std::time::Duration { + fn from_value(v: Value) -> Result { + match v { + Value::Duration { val, .. } => { + let nanos = u64::try_from(val) + .map_err(|_| ShellError::NeedsPositiveValue { span: v.span() })?; + Ok(Self::from_nanos(nanos)) + } + v => Err(ShellError::CantConvert { + to_type: Self::expected_type().to_string(), + from_type: v.get_type().to_string(), + span: v.span(), + help: None, + }), + } + } + + fn expected_type() -> Type { + Type::Duration + } +} + // // We can not use impl FromValue for NonZero as NonZero requires an unstable trait // As a result, we use this macro to implement FromValue for each NonZero type.