mirror of
https://github.com/nushell/nushell.git
synced 2025-07-01 07:00:37 +02:00
fix(random dice): gracefully handle --sides 0 using NonZeroUsize (#16001)
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::ListStream;
|
use nu_protocol::ListStream;
|
||||||
use rand::random_range;
|
use rand::random_range;
|
||||||
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RandomDice;
|
pub struct RandomDice;
|
||||||
@ -70,8 +71,16 @@ fn dice(
|
|||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
|
|
||||||
let dice: usize = call.get_flag(engine_state, stack, "dice")?.unwrap_or(1);
|
let sides: NonZeroUsize = call
|
||||||
let sides: usize = call.get_flag(engine_state, stack, "sides")?.unwrap_or(6);
|
.get_flag(engine_state, stack, "sides")?
|
||||||
|
.unwrap_or_else(|| NonZeroUsize::new(6).expect("default sides must be non-zero"));
|
||||||
|
|
||||||
|
let dice: NonZeroUsize = call
|
||||||
|
.get_flag(engine_state, stack, "dice")?
|
||||||
|
.unwrap_or_else(|| NonZeroUsize::new(1).expect("default dice count must be non-zero"));
|
||||||
|
|
||||||
|
let sides = sides.get();
|
||||||
|
let dice = dice.get();
|
||||||
|
|
||||||
let iter = (0..dice).map(move |_| Value::int(random_range(1..sides + 1) as i64, span));
|
let iter = (0..dice).map(move |_| Value::int(random_range(1..sides + 1) as i64, span));
|
||||||
|
|
||||||
|
@ -10,6 +10,10 @@ use std::{
|
|||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
fmt,
|
fmt,
|
||||||
|
num::{
|
||||||
|
NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroIsize, NonZeroU16, NonZeroU32,
|
||||||
|
NonZeroU64, NonZeroUsize,
|
||||||
|
},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
@ -270,6 +274,42 @@ impl FromValue for i64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// We can not use impl<T: FromValue> FromValue for NonZero<T> as NonZero requires an unstable trait
|
||||||
|
// As a result, we use this macro to implement FromValue for each NonZero type.
|
||||||
|
//
|
||||||
|
|
||||||
|
macro_rules! impl_from_value_for_nonzero {
|
||||||
|
($nonzero:ty, $base:ty) => {
|
||||||
|
impl FromValue for $nonzero {
|
||||||
|
fn from_value(v: Value) -> Result<Self, ShellError> {
|
||||||
|
let span = v.span();
|
||||||
|
let val = <$base>::from_value(v)?;
|
||||||
|
<$nonzero>::new(val).ok_or_else(|| ShellError::IncorrectValue {
|
||||||
|
msg: "use a value other than 0".into(),
|
||||||
|
val_span: span,
|
||||||
|
call_span: span,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expected_type() -> Type {
|
||||||
|
Type::Int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_from_value_for_nonzero!(NonZeroU16, u16);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroU32, u32);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroU64, u64);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroUsize, usize);
|
||||||
|
|
||||||
|
impl_from_value_for_nonzero!(NonZeroI8, i8);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroI16, i16);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroI32, i32);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroI64, i64);
|
||||||
|
impl_from_value_for_nonzero!(NonZeroIsize, isize);
|
||||||
|
|
||||||
macro_rules! impl_from_value_for_int {
|
macro_rules! impl_from_value_for_int {
|
||||||
($type:ty) => {
|
($type:ty) => {
|
||||||
impl FromValue for $type {
|
impl FromValue for $type {
|
||||||
|
Reference in New Issue
Block a user