diff options
Diffstat (limited to 'library/std/src/io')
| -rw-r--r-- | library/std/src/io/buffered/linewritershim.rs | 9 | ||||
| -rw-r--r-- | library/std/src/io/buffered/tests.rs | 18 | ||||
| -rw-r--r-- | library/std/src/io/error.rs | 18 | ||||
| -rw-r--r-- | library/std/src/io/error/repr_bitpacked.rs | 2 | ||||
| -rw-r--r-- | library/std/src/io/mod.rs | 25 |
5 files changed, 46 insertions, 26 deletions
diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs index 3d04ccd1c7d..5ebeada59bb 100644 --- a/library/std/src/io/buffered/linewritershim.rs +++ b/library/std/src/io/buffered/linewritershim.rs @@ -119,7 +119,14 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { // the buffer? // - If not, scan for the last newline that *does* fit in the buffer let tail = if flushed >= newline_idx { - &buf[flushed..] + let tail = &buf[flushed..]; + // Avoid unnecessary short writes by not splitting the remaining + // bytes if they're larger than the buffer. + // They can be written in full by the next call to write. + if tail.len() >= self.buffer.capacity() { + return Ok(flushed); + } + tail } else if newline_idx - flushed <= self.buffer.capacity() { &buf[flushed..newline_idx] } else { diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index bff0f823c4b..17f6107aa03 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -847,8 +847,7 @@ fn long_line_flushed() { } /// Test that, given a very long partial line *after* successfully -/// flushing a complete line, the very long partial line is buffered -/// unconditionally, and no additional writes take place. This assures +/// flushing a complete line, no additional writes take place. This assures /// the property that `write` should make at-most-one attempt to write /// new data. #[test] @@ -856,13 +855,22 @@ fn line_long_tail_not_flushed() { let writer = ProgrammableSink::default(); let mut writer = LineWriter::with_capacity(5, writer); - // Assert that Line 1\n is flushed, and 01234 is buffered - assert_eq!(writer.write(b"Line 1\n0123456789").unwrap(), 12); + // Assert that Line 1\n is flushed and the long tail isn't. + let bytes = b"Line 1\n0123456789"; + writer.write(bytes).unwrap(); assert_eq!(&writer.get_ref().buffer, b"Line 1\n"); +} + +// Test that appending to a full buffer emits a single write, flushing the buffer. +#[test] +fn line_full_buffer_flushed() { + let writer = ProgrammableSink::default(); + let mut writer = LineWriter::with_capacity(5, writer); + assert_eq!(writer.write(b"01234").unwrap(), 5); // Because the buffer is full, this subsequent write will flush it assert_eq!(writer.write(b"5").unwrap(), 1); - assert_eq!(&writer.get_ref().buffer, b"Line 1\n01234"); + assert_eq!(&writer.get_ref().buffer, b"01234"); } /// Test that, if an attempt to pre-flush buffered data returns Ok(0), diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 03f38e220a5..476c403c21f 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -338,9 +338,9 @@ pub enum ErrorKind { /// example, on Unix, a named pipe opened with `File::open`. #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] NotSeekable, - /// Filesystem quota was exceeded. - #[unstable(feature = "io_error_more", issue = "86442")] - FilesystemQuotaExceeded, + /// Filesystem quota or some other kind of quota was exceeded. + #[stable(feature = "io_error_quota_exceeded", since = "CURRENT_RUSTC_VERSION")] + QuotaExceeded, /// File larger than allowed or supported. /// /// This might arise from a hard limit of the underlying filesystem or file access API, or from @@ -364,7 +364,7 @@ pub enum ErrorKind { #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] Deadlock, /// Cross-device or cross-filesystem (hard) link or rename. - #[unstable(feature = "io_error_more", issue = "86442")] + #[stable(feature = "io_error_crosses_devices", since = "CURRENT_RUSTC_VERSION")] CrossesDevices, /// Too many (hard) links to the same filesystem object. /// @@ -446,8 +446,8 @@ pub enum ErrorKind { impl ErrorKind { pub(crate) fn as_str(&self) -> &'static str { use ErrorKind::*; - // tidy-alphabetical-start match *self { + // tidy-alphabetical-start AddrInUse => "address in use", AddrNotAvailable => "address not available", AlreadyExists => "entity already exists", @@ -460,12 +460,11 @@ impl ErrorKind { Deadlock => "deadlock", DirectoryNotEmpty => "directory not empty", ExecutableFileBusy => "executable file busy", - FileTooLarge => "file too large", FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)", - FilesystemQuotaExceeded => "filesystem quota exceeded", + FileTooLarge => "file too large", HostUnreachable => "host unreachable", - Interrupted => "operation interrupted", InProgress => "in progress", + Interrupted => "operation interrupted", InvalidData => "invalid data", InvalidFilename => "invalid filename", InvalidInput => "invalid input parameter", @@ -479,6 +478,7 @@ impl ErrorKind { Other => "other error", OutOfMemory => "out of memory", PermissionDenied => "permission denied", + QuotaExceeded => "quota exceeded", ReadOnlyFilesystem => "read-only filesystem or storage medium", ResourceBusy => "resource busy", StaleNetworkFileHandle => "stale network file handle", @@ -490,8 +490,8 @@ impl ErrorKind { Unsupported => "unsupported", WouldBlock => "operation would block", WriteZero => "write zero", + // tidy-alphabetical-end } - // tidy-alphabetical-end } } diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index a839a2fbac1..f958a938646 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -335,7 +335,7 @@ fn kind_from_prim(ek: u32) -> Option<ErrorKind> { WriteZero, StorageFull, NotSeekable, - FilesystemQuotaExceeded, + QuotaExceeded, FileTooLarge, ResourceBusy, ExecutableFileBusy, diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 4ffb0463006..7912f969bbd 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1083,7 +1083,7 @@ pub trait Read { /// let f = BufReader::new(File::open("foo.txt")?); /// /// for byte in f.bytes() { - /// println!("{}", byte.unwrap()); + /// println!("{}", byte?); /// } /// Ok(()) /// } @@ -1995,15 +1995,16 @@ pub trait Seek { /// .write(true) /// .read(true) /// .create(true) - /// .open("foo.txt").unwrap(); + /// .open("foo.txt")?; /// /// let hello = "Hello!\n"; - /// write!(f, "{hello}").unwrap(); - /// f.rewind().unwrap(); + /// write!(f, "{hello}")?; + /// f.rewind()?; /// /// let mut buf = String::new(); - /// f.read_to_string(&mut buf).unwrap(); + /// f.read_to_string(&mut buf)?; /// assert_eq!(&buf, hello); + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "seek_rewind", since = "1.55.0")] fn rewind(&mut self) -> Result<()> { @@ -2212,8 +2213,9 @@ fn skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize> { /// /// let stdin = io::stdin(); /// for line in stdin.lock().lines() { -/// println!("{}", line.unwrap()); +/// println!("{}", line?); /// } +/// # std::io::Result::Ok(()) /// ``` /// /// If you have something that implements [`Read`], you can use the [`BufReader` @@ -2236,7 +2238,8 @@ fn skip_until<R: BufRead + ?Sized>(r: &mut R, delim: u8) -> Result<usize> { /// let f = BufReader::new(f); /// /// for line in f.lines() { -/// println!("{}", line.unwrap()); +/// let line = line?; +/// println!("{line}"); /// } /// /// Ok(()) @@ -2274,7 +2277,7 @@ pub trait BufRead: Read { /// let stdin = io::stdin(); /// let mut stdin = stdin.lock(); /// - /// let buffer = stdin.fill_buf().unwrap(); + /// let buffer = stdin.fill_buf()?; /// /// // work with buffer /// println!("{buffer:?}"); @@ -2282,6 +2285,7 @@ pub trait BufRead: Read { /// // ensure the bytes we worked with aren't returned again later /// let length = buffer.len(); /// stdin.consume(length); + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn fill_buf(&mut self) -> Result<&[u8]>; @@ -2327,12 +2331,13 @@ pub trait BufRead: Read { /// let stdin = io::stdin(); /// let mut stdin = stdin.lock(); /// - /// while stdin.has_data_left().unwrap() { + /// while stdin.has_data_left()? { /// let mut line = String::new(); - /// stdin.read_line(&mut line).unwrap(); + /// stdin.read_line(&mut line)?; /// // work with line /// println!("{line:?}"); /// } + /// # std::io::Result::Ok(()) /// ``` #[unstable(feature = "buf_read_has_data_left", reason = "recently added", issue = "86423")] fn has_data_left(&mut self) -> Result<bool> { |
