mirror of
https://github.com/nushell/nushell.git
synced 2024-11-24 17:34:00 +01:00
Fix tests and add some more From
conversions
This commit is contained in:
parent
7708dac4ab
commit
6c7a76b15c
@ -1,5 +1,5 @@
|
|||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
|
use nu_protocol::format_filesize_from_conf;
|
||||||
use rand::{thread_rng, RngCore};
|
use rand::{thread_rng, RngCore};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -37,7 +37,27 @@ impl Command for SubCommand {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let length = call.req(engine_state, stack, 0)?;
|
let length_val = call.req(engine_state, stack, 0)?;
|
||||||
|
let length = match length_val {
|
||||||
|
Value::Int { val, .. } => usize::try_from(val).map_err(|_| ShellError::InvalidValue {
|
||||||
|
valid: "a non-negative int or filesize".into(),
|
||||||
|
actual: val.to_string(),
|
||||||
|
span: length_val.span(),
|
||||||
|
}),
|
||||||
|
Value::Filesize { val, .. } => {
|
||||||
|
usize::try_from(val).map_err(|_| ShellError::InvalidValue {
|
||||||
|
valid: "a non-negative int or filesize".into(),
|
||||||
|
actual: format_filesize_from_conf(val, engine_state.get_config()),
|
||||||
|
span: length_val.span(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
val => Err(ShellError::RuntimeTypeMismatch {
|
||||||
|
expected: Type::custom("int or filesize"),
|
||||||
|
actual: val.get_type(),
|
||||||
|
span: val.span(),
|
||||||
|
}),
|
||||||
|
}?;
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
let mut out = vec![0u8; length];
|
let mut out = vec![0u8; length];
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
|
use nu_protocol::format_filesize_from_conf;
|
||||||
use rand::{
|
use rand::{
|
||||||
distributions::{Alphanumeric, Distribution},
|
distributions::{Alphanumeric, Distribution},
|
||||||
thread_rng,
|
thread_rng,
|
||||||
@ -73,14 +73,36 @@ fn chars(
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let span = call.head;
|
||||||
let length: Option<usize> = call.get_flag(engine_state, stack, "length")?;
|
let length: Option<Value> = call.get_flag(engine_state, stack, "length")?;
|
||||||
|
let length = if let Some(length_val) = length {
|
||||||
|
match length_val {
|
||||||
|
Value::Int { val, .. } => usize::try_from(val).map_err(|_| ShellError::InvalidValue {
|
||||||
|
valid: "a non-negative int or filesize".into(),
|
||||||
|
actual: val.to_string(),
|
||||||
|
span: length_val.span(),
|
||||||
|
}),
|
||||||
|
Value::Filesize { val, .. } => {
|
||||||
|
usize::try_from(val).map_err(|_| ShellError::InvalidValue {
|
||||||
|
valid: "a non-negative int or filesize".into(),
|
||||||
|
actual: format_filesize_from_conf(val, engine_state.get_config()),
|
||||||
|
span: length_val.span(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
val => Err(ShellError::RuntimeTypeMismatch {
|
||||||
|
expected: Type::custom("int or filesize"),
|
||||||
|
actual: val.get_type(),
|
||||||
|
span: val.span(),
|
||||||
|
}),
|
||||||
|
}?
|
||||||
|
} else {
|
||||||
|
DEFAULT_CHARS_LENGTH
|
||||||
|
};
|
||||||
|
|
||||||
let chars_length = length.unwrap_or(DEFAULT_CHARS_LENGTH);
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
|
|
||||||
let random_string = Alphanumeric
|
let random_string = Alphanumeric
|
||||||
.sample_iter(&mut rng)
|
.sample_iter(&mut rng)
|
||||||
.take(chars_length)
|
.take(length)
|
||||||
.map(char::from)
|
.map(char::from)
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ fn reject_rows_with_list_spread() {
|
|||||||
let actual = nu!("let arg = [2 0]; [[name type size];[Cargo.toml file 10mb] [Cargo.lock file 10mb] [src dir 100mb]] | reject ...$arg | to nuon");
|
let actual = nu!("let arg = [2 0]; [[name type size];[Cargo.toml file 10mb] [Cargo.lock file 10mb] [src dir 100mb]] | reject ...$arg | to nuon");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual.out,
|
actual.out,
|
||||||
r#"[[name, type, size]; ["Cargo.lock", file, 10000000b]]"#
|
r#"[[name, type, size]; ["Cargo.lock", file, 10000000B]]"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ fn reject_mixed_with_list_spread() {
|
|||||||
let actual = nu!("let arg = [type 2]; [[name type size];[Cargp.toml file 10mb] [ Cargo.lock file 10mb] [src dir 100mb]] | reject ...$arg | to nuon");
|
let actual = nu!("let arg = [type 2]; [[name type size];[Cargp.toml file 10mb] [ Cargo.lock file 10mb] [src dir 100mb]] | reject ...$arg | to nuon");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual.out,
|
actual.out,
|
||||||
r#"[[name, size]; ["Cargp.toml", 10000000b], ["Cargo.lock", 10000000b]]"#
|
r#"[[name, size]; ["Cargp.toml", 10000000B], ["Cargo.lock", 10000000B]]"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ fn to_nuon_correct_compaction() {
|
|||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
cwd: "tests/fixtures/formats", pipeline(
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
r#"
|
r#"
|
||||||
open appveyor.yml
|
open appveyor.yml
|
||||||
| to nuon
|
| to nuon
|
||||||
| str length
|
| str length
|
||||||
| $in > 500
|
| $in > 500
|
||||||
"#
|
"#
|
||||||
));
|
));
|
||||||
@ -211,7 +211,7 @@ fn to_nuon_filesize() {
|
|||||||
"#
|
"#
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(actual.out, "1024b");
|
assert_eq!(actual.out, "1024B");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -86,56 +86,6 @@ impl From<Filesize> for i64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u64> for Filesize {
|
|
||||||
type Error = <u64 as TryInto<i64>>::Error;
|
|
||||||
|
|
||||||
fn try_from(value: u64) -> Result<Self, Self::Error> {
|
|
||||||
value.try_into().map(Self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Filesize> for u64 {
|
|
||||||
type Error = <i64 as TryInto<u64>>::Error;
|
|
||||||
|
|
||||||
fn try_from(filesize: Filesize) -> Result<Self, Self::Error> {
|
|
||||||
filesize.0.try_into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The error type returned when a checked conversion from a floating point type fails.
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
|
|
||||||
pub struct TryFromFloatError(());
|
|
||||||
|
|
||||||
impl fmt::Display for TryFromFloatError {
|
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(fmt, "out of range float type conversion attempted")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<f64> for Filesize {
|
|
||||||
type Error = TryFromFloatError;
|
|
||||||
|
|
||||||
fn try_from(value: f64) -> Result<Self, Self::Error> {
|
|
||||||
if i64::MIN as f64 <= value && value <= i64::MAX as f64 {
|
|
||||||
Ok(Self(value as i64))
|
|
||||||
} else {
|
|
||||||
Err(TryFromFloatError(()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<f32> for Filesize {
|
|
||||||
type Error = TryFromFloatError;
|
|
||||||
|
|
||||||
fn try_from(value: f32) -> Result<Self, Self::Error> {
|
|
||||||
if i64::MIN as f32 <= value && value <= i64::MAX as f32 {
|
|
||||||
Ok(Self(value as i64))
|
|
||||||
} else {
|
|
||||||
Err(TryFromFloatError(()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_from {
|
macro_rules! impl_from {
|
||||||
($($ty:ty),* $(,)?) => {
|
($($ty:ty),* $(,)?) => {
|
||||||
$(
|
$(
|
||||||
@ -160,6 +110,68 @@ macro_rules! impl_from {
|
|||||||
|
|
||||||
impl_from!(u8, i8, u16, i16, u32, i32);
|
impl_from!(u8, i8, u16, i16, u32, i32);
|
||||||
|
|
||||||
|
macro_rules! impl_try_from {
|
||||||
|
($($ty:ty),* $(,)?) => {
|
||||||
|
$(
|
||||||
|
impl TryFrom<$ty> for Filesize {
|
||||||
|
type Error = <$ty as TryInto<i64>>::Error;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_from(value: $ty) -> Result<Self, Self::Error> {
|
||||||
|
value.try_into().map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Filesize> for $ty {
|
||||||
|
type Error = <i64 as TryInto<$ty>>::Error;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_from(filesize: Filesize) -> Result<Self, Self::Error> {
|
||||||
|
filesize.0.try_into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_try_from!(u64, usize, isize);
|
||||||
|
|
||||||
|
/// The error type returned when a checked conversion from a floating point type fails.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Error)]
|
||||||
|
pub struct TryFromFloatError(());
|
||||||
|
|
||||||
|
impl fmt::Display for TryFromFloatError {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(fmt, "out of range float type conversion attempted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<f64> for Filesize {
|
||||||
|
type Error = TryFromFloatError;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_from(value: f64) -> Result<Self, Self::Error> {
|
||||||
|
if i64::MIN as f64 <= value && value <= i64::MAX as f64 {
|
||||||
|
Ok(Self(value as i64))
|
||||||
|
} else {
|
||||||
|
Err(TryFromFloatError(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<f32> for Filesize {
|
||||||
|
type Error = TryFromFloatError;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn try_from(value: f32) -> Result<Self, Self::Error> {
|
||||||
|
if i64::MIN as f32 <= value && value <= i64::MAX as f32 {
|
||||||
|
Ok(Self(value as i64))
|
||||||
|
} else {
|
||||||
|
Err(TryFromFloatError(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromValue for Filesize {
|
impl FromValue for Filesize {
|
||||||
fn from_value(value: Value) -> Result<Self, ShellError> {
|
fn from_value(value: Value) -> Result<Self, ShellError> {
|
||||||
value.as_filesize()
|
value.as_filesize()
|
||||||
@ -260,7 +272,7 @@ impl fmt::Display for Filesize {
|
|||||||
|
|
||||||
/// All the possible filesize units for a [`Filesize`].
|
/// All the possible filesize units for a [`Filesize`].
|
||||||
///
|
///
|
||||||
/// This type contains both units with metric (SI) decimal prefixes which are powers of 10 (e.g., KB = 1000 bytes)
|
/// This type contains both units with metric (SI) decimal prefixes which are powers of 10 (e.g., kB = 1000 bytes)
|
||||||
/// and units with binary prefixes which are powers of 2 (e.g., KiB = 1024 bytes).
|
/// and units with binary prefixes which are powers of 2 (e.g., KiB = 1024 bytes).
|
||||||
///
|
///
|
||||||
/// The number of bytes in a [`FilesizeUnit`] can be obtained using
|
/// The number of bytes in a [`FilesizeUnit`] can be obtained using
|
||||||
@ -330,13 +342,13 @@ impl FilesizeUnit {
|
|||||||
/// ```
|
/// ```
|
||||||
/// # use nu_protocol::FilesizeUnit;
|
/// # use nu_protocol::FilesizeUnit;
|
||||||
/// assert_eq!(FilesizeUnit::B.as_str(), "B");
|
/// assert_eq!(FilesizeUnit::B.as_str(), "B");
|
||||||
/// assert_eq!(FilesizeUnit::KB.as_str(), "KB");
|
/// assert_eq!(FilesizeUnit::KB.as_str(), "kB");
|
||||||
/// assert_eq!(FilesizeUnit::KiB.as_str(), "KiB");
|
/// assert_eq!(FilesizeUnit::KiB.as_str(), "KiB");
|
||||||
/// ```
|
/// ```
|
||||||
pub const fn as_str(&self) -> &'static str {
|
pub const fn as_str(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::B => "B",
|
Self::B => "B",
|
||||||
Self::KB => "KB",
|
Self::KB => "kB",
|
||||||
Self::MB => "MB",
|
Self::MB => "MB",
|
||||||
Self::GB => "GB",
|
Self::GB => "GB",
|
||||||
Self::TB => "TB",
|
Self::TB => "TB",
|
||||||
@ -397,7 +409,7 @@ impl FromStr for FilesizeUnit {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
Ok(match s {
|
Ok(match s {
|
||||||
"B" => Self::B,
|
"B" => Self::B,
|
||||||
"KB" => Self::KB,
|
"kB" => Self::KB,
|
||||||
"MB" => Self::MB,
|
"MB" => Self::MB,
|
||||||
"GB" => Self::GB,
|
"GB" => Self::GB,
|
||||||
"TB" => Self::TB,
|
"TB" => Self::TB,
|
||||||
|
@ -154,8 +154,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn filesize() {
|
fn filesize() {
|
||||||
nuon_end_to_end("1024b", Some(Value::test_filesize(1024)));
|
nuon_end_to_end("1024B", Some(Value::test_filesize(1024)));
|
||||||
assert_eq!(from_nuon("1kib", None).unwrap(), Value::test_filesize(1024),);
|
assert_eq!(from_nuon("1kib", None).unwrap(), Value::test_filesize(1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -39,7 +39,7 @@ pub enum ToStyle {
|
|||||||
///
|
///
|
||||||
// WARNING: please leave the following two trailing spaces, they matter for the documentation
|
// WARNING: please leave the following two trailing spaces, they matter for the documentation
|
||||||
// formatting
|
// formatting
|
||||||
/// > **Note**
|
/// > **Note**
|
||||||
/// > a [`Span`] can be passed to [`to_nuon`] if there is context available to the caller, e.g. when
|
/// > a [`Span`] can be passed to [`to_nuon`] if there is context available to the caller, e.g. when
|
||||||
/// > using this function in a command implementation such as [`to nuon`](https://www.nushell.sh/commands/docs/to_nuon.html).
|
/// > using this function in a command implementation such as [`to nuon`](https://www.nushell.sh/commands/docs/to_nuon.html).
|
||||||
///
|
///
|
||||||
@ -110,7 +110,7 @@ fn value_to_string(
|
|||||||
// Propagate existing errors
|
// Propagate existing errors
|
||||||
Value::Error { error, .. } => Err(*error.clone()),
|
Value::Error { error, .. } => Err(*error.clone()),
|
||||||
// FIXME: make filesizes use the shortest lossless representation.
|
// FIXME: make filesizes use the shortest lossless representation.
|
||||||
Value::Filesize { val, .. } => Ok(format!("{}b", *val)),
|
Value::Filesize { val, .. } => Ok(format!("{}B", val.get())),
|
||||||
Value::Float { val, .. } => {
|
Value::Float { val, .. } => {
|
||||||
// This serialises these as 'nan', 'inf' and '-inf', respectively.
|
// This serialises these as 'nan', 'inf' and '-inf', respectively.
|
||||||
if &val.round() == val && val.is_finite() {
|
if &val.round() == val && val.is_finite() {
|
||||||
|
Loading…
Reference in New Issue
Block a user