diff --git a/crates/nu-command/src/conversions/into/string.rs b/crates/nu-command/src/conversions/into/string.rs index c0731b2e20..7c7d69cf4e 100644 --- a/crates/nu-command/src/conversions/into/string.rs +++ b/crates/nu-command/src/conversions/into/string.rs @@ -160,7 +160,7 @@ fn string_helper( // Just set the type - that should be good enough. There is no guarantee that the data // within a string stream is actually valid UTF-8. But refuse to do it if it was already set // to binary - if stream.type_() != ByteStreamType::Binary { + if stream.type_().is_string_coercible() { Ok(PipelineData::ByteStream( stream.with_type(ByteStreamType::String), metadata, diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs index f625847a3f..97c5159b97 100644 --- a/crates/nu-command/src/filters/first.rs +++ b/crates/nu-command/src/filters/first.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use std::io::Read; #[derive(Clone)] pub struct First; @@ -171,10 +172,9 @@ fn first_helper( } } PipelineData::ByteStream(stream, metadata) => { - if stream.type_() == ByteStreamType::Binary { + if stream.type_().is_binary_coercible() { let span = stream.span(); if let Some(mut reader) = stream.reader() { - use std::io::Read; if return_single_element { // Take a single byte let mut byte = [0u8]; diff --git a/crates/nu-command/src/filters/last.rs b/crates/nu-command/src/filters/last.rs index 510e6457a8..efb300db01 100644 --- a/crates/nu-command/src/filters/last.rs +++ b/crates/nu-command/src/filters/last.rs @@ -1,6 +1,5 @@ use nu_engine::command_prelude::*; - -use std::collections::VecDeque; +use std::{collections::VecDeque, io::Read}; #[derive(Clone)] pub struct Last; @@ -161,10 +160,9 @@ impl Command for Last { } } PipelineData::ByteStream(stream, ..) => { - if stream.type_() == ByteStreamType::Binary { + if stream.type_().is_binary_coercible() { let span = stream.span(); if let Some(mut reader) = stream.reader() { - use std::io::Read; // Have to be a bit tricky here, but just consume into a VecDeque that we // shrink to fit each time const TAKE: u64 = 8192; diff --git a/crates/nu-command/src/filters/skip/skip_.rs b/crates/nu-command/src/filters/skip/skip_.rs index df53cfacba..d293a743da 100644 --- a/crates/nu-command/src/filters/skip/skip_.rs +++ b/crates/nu-command/src/filters/skip/skip_.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use std::io::{self, Read}; #[derive(Clone)] pub struct Skip; @@ -94,12 +95,11 @@ impl Command for Skip { let input_span = input.span().unwrap_or(call.head); match input { PipelineData::ByteStream(stream, metadata) => { - if stream.type_() == ByteStreamType::Binary { + if stream.type_().is_binary_coercible() { let span = stream.span(); if let Some(mut reader) = stream.reader() { - use std::io::Read; // Copy the number of skipped bytes into the sink before proceeding - std::io::copy(&mut (&mut reader).take(n as u64), &mut std::io::sink()) + io::copy(&mut (&mut reader).take(n as u64), &mut io::sink()) .err_span(span)?; Ok(PipelineData::ByteStream( ByteStream::read(reader, call.head, None, ByteStreamType::Binary), diff --git a/crates/nu-command/src/filters/take/take_.rs b/crates/nu-command/src/filters/take/take_.rs index d4bf455c4a..7ebe22f914 100644 --- a/crates/nu-command/src/filters/take/take_.rs +++ b/crates/nu-command/src/filters/take/take_.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use std::io::Read; #[derive(Clone)] pub struct Take; @@ -79,9 +80,8 @@ impl Command for Take { metadata, )), PipelineData::ByteStream(stream, metadata) => { - if stream.type_() == ByteStreamType::Binary { + if stream.type_().is_binary_coercible() { if let Some(reader) = stream.reader() { - use std::io::Read; // Just take 'rows' bytes off the stream, mimicking the binary behavior Ok(PipelineData::ByteStream( ByteStream::read( diff --git a/crates/nu-protocol/src/pipeline/byte_stream.rs b/crates/nu-protocol/src/pipeline/byte_stream.rs index 35ce39ed31..babd195a9e 100644 --- a/crates/nu-protocol/src/pipeline/byte_stream.rs +++ b/crates/nu-protocol/src/pipeline/byte_stream.rs @@ -114,6 +114,16 @@ impl ByteStreamType { ByteStreamType::Unknown => "byte stream", } } + + /// Returns true if the type is `Binary` or `Unknown` + pub fn is_binary_coercible(self) -> bool { + matches!(self, ByteStreamType::Binary | ByteStreamType::Unknown) + } + + /// Returns true if the type is `String` or `Unknown` + pub fn is_string_coercible(self) -> bool { + matches!(self, ByteStreamType::String | ByteStreamType::Unknown) + } } impl From for Type { @@ -483,7 +493,7 @@ impl ByteStream { /// data would have been valid UTF-8. pub fn into_string(self) -> Result { let span = self.span; - if self.type_ != ByteStreamType::Binary { + if self.type_.is_string_coercible() { let trim = self.stream.is_external(); let bytes = self.into_bytes()?; let mut string = String::from_utf8(bytes).map_err(|err| ShellError::NonUtf8Custom {