Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 50 additions & 24 deletions library/alloc/src/io/buf_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ use crate::vec::Vec;
/// A locked standard input implements `BufRead`:
///
/// ```no_run
/// use std::io;
/// use std::io::prelude::*;
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// # use alloc::vec::Vec;
/// # use alloc::string::String;
/// use std::io::{self, BufRead};
///
/// let stdin = io::stdin();
/// for line in stdin.lock().lines() {
/// println!("{}", line?);
/// }
/// # std::io::Result::Ok(())
/// let data = "Hello\nWorld!";
/// let cursor = io::Cursor::new(data);
///
/// let lines = cursor.lines().collect::<io::Result<Vec<String>>>()?;
///
/// assert_eq!(&lines[0], "Hello");
/// assert_eq!(&lines[1], "World!");
/// # io::Result::Ok(())
/// ```
///
/// If you have something that implements [`Read`], you can use the `BufReader`
Expand All @@ -36,21 +42,20 @@ use crate::vec::Vec;
/// [`lines`]: BufRead::lines
///
/// ```no_run
/// use std::io::{self, BufReader};
/// use std::io::prelude::*;
/// use std::fs::File;
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// # use alloc::vec::Vec;
/// # use alloc::string::String;
/// use std::io::{self, BufRead, BufReader};
///
/// fn main() -> io::Result<()> {
/// let f = File::open("foo.txt")?;
/// let f = BufReader::new(f);
/// let mut data = b"Hello\nWorld!" as &[u8];
/// let buffer = BufReader::new(&mut data);
///
/// for line in f.lines() {
/// let line = line?;
/// println!("{line}");
/// }
/// let lines = buffer.lines().collect::<io::Result<Vec<String>>>()?;
///
/// Ok(())
/// }
/// assert_eq!(&lines[0], "Hello");
/// assert_eq!(&lines[1], "World!");
/// # io::Result::Ok(())
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "IoBufRead")]
Expand All @@ -73,10 +78,15 @@ pub trait BufRead: Read {
/// A locked standard input implements `BufRead`:
///
/// ```no_run
/// use std::io;
/// # #![feature(alloc_io)]
/// # #![allow(unused_must_use)]
/// # use alloc as std;
/// # use alloc::format as println;
/// use std::io::prelude::*;
///
/// let stdin = io::stdin();
/// # struct StdinMock;
/// # impl StdinMock { fn lock(&self) -> impl BufRead { alloc::io::BufReader::new(&[0u8; 8][..]) } }
/// # let stdin = StdinMock;
/// let mut stdin = stdin.lock();
///
/// let buffer = stdin.fill_buf()?;
Expand Down Expand Up @@ -124,12 +134,17 @@ pub trait BufRead: Read {
///
/// Examples
///
/// ```
/// ```no_run
/// # #![feature(alloc_io)]
/// # #![allow(unused_must_use)]
/// #![feature(buf_read_has_data_left)]
/// use std::io;
/// # use alloc as std;
/// # use alloc::format as println;
/// use std::io::prelude::*;
///
/// let stdin = io::stdin();
/// # struct StdinMock;
/// # impl StdinMock { fn lock(&self) -> impl BufRead { alloc::io::BufReader::new(&[0u8; 8][..]) } }
/// # let stdin = StdinMock;
/// let mut stdin = stdin.lock();
///
/// while stdin.has_data_left()? {
Expand Down Expand Up @@ -176,6 +191,8 @@ pub trait BufRead: Read {
/// [`Cursor`]: crate::io::Cursor
///
/// ```
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::{self, BufRead};
///
/// let mut cursor = io::Cursor::new(b"lorem-ipsum");
Expand Down Expand Up @@ -240,6 +257,9 @@ pub trait BufRead: Read {
/// [`Cursor`]: crate::io::Cursor
///
/// ```
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// # use alloc::vec::Vec;
/// use std::io::{self, BufRead};
///
/// let mut cursor = io::Cursor::new(b"Ferris\0Likes long walks on the beach\0Crustacean\0!");
Expand Down Expand Up @@ -313,6 +333,8 @@ pub trait BufRead: Read {
/// [`Cursor`]: crate::io::Cursor
///
/// ```
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::{self, BufRead};
///
/// let mut cursor = io::Cursor::new(b"foo\nbar");
Expand Down Expand Up @@ -368,6 +390,8 @@ pub trait BufRead: Read {
/// [`Cursor`]: crate::io::Cursor
///
/// ```
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::{self, BufRead};
///
/// let cursor = io::Cursor::new(b"lorem-ipsum-dolor");
Expand Down Expand Up @@ -403,6 +427,8 @@ pub trait BufRead: Read {
/// [`Cursor`]: crate::io::Cursor
///
/// ```
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::{self, BufRead};
///
/// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor");
Expand Down
59 changes: 38 additions & 21 deletions library/alloc/src/io/buffered/bufreader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ use crate::vec::Vec;
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # #![allow(unused_must_use)]
/// # use alloc as std;
/// # use alloc::format as println;
/// # use alloc::string::String;
/// use std::io::prelude::*;
/// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f = File::open("log.txt")?;
/// let f = b"Hello\nWorld!" as &[u8];
/// let mut reader = BufReader::new(f);
///
/// let mut line = String::new();
Expand All @@ -64,11 +68,12 @@ impl<R: Read> BufReader<R> {
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f = File::open("log.txt")?;
/// let f = b"Hello\nWorld!" as &[u8];
/// let reader = BufReader::new(f);
/// Ok(())
/// }
Expand Down Expand Up @@ -97,11 +102,12 @@ impl<R: Read> BufReader<R> {
/// Creating a buffer with ten bytes of capacity:
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f = File::open("log.txt")?;
/// let f = b"Hello\nWorld!" as &[u8];
/// let reader = BufReader::with_capacity(10, f);
/// Ok(())
/// }
Expand All @@ -128,7 +134,9 @@ impl<R: Read + ?Sized> BufReader<R> {
/// ## Examples
///
/// ```rust
/// # #![feature(alloc_io)]
/// #![feature(bufreader_peek)]
/// # use alloc as std;
/// use std::io::{Read, BufReader};
///
/// let mut bytes = &b"oh, hello there"[..];
Expand Down Expand Up @@ -169,11 +177,12 @@ impl<R: ?Sized> BufReader<R> {
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f1 = File::open("log.txt")?;
/// let f1 = b"Hello\nWorld!" as &[u8];
/// let reader = BufReader::new(f1);
///
/// let f2 = reader.get_ref();
Expand All @@ -192,11 +201,12 @@ impl<R: ?Sized> BufReader<R> {
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f1 = File::open("log.txt")?;
/// let f1 = b"Hello\nWorld!" as &[u8];

@bjorn3 bjorn3 Aug 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is reasonable to keep the old code. It better explains what kind of use cases BufReader is meant for (reads involving actual IO that is cheaper when batched).

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think the old examples are generally better, but I'm not sure if there's any issues with having examples in alloc which require std? If it's acceptable to have example code in alloc and core which requires std I'm happy to revert those changes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually yeah, based on the existing documentation for something like core::borrow, it looks like it's expected that std be available for example snippets. Tomorrow morning I'll close this PR in favor of just the prelude and a handful of other minor changes. Thanks for your help!

/// let mut reader = BufReader::new(f1);
///
/// let f2 = reader.get_mut();
Expand All @@ -217,11 +227,12 @@ impl<R: ?Sized> BufReader<R> {
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::{BufReader, BufRead};
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f = File::open("log.txt")?;
/// let f = b"Hello\nWorld!" as &[u8];
/// let mut reader = BufReader::new(f);
/// assert!(reader.buffer().is_empty());
///
Expand All @@ -241,11 +252,12 @@ impl<R: ?Sized> BufReader<R> {
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::{BufReader, BufRead};
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f = File::open("log.txt")?;
/// let f = b"Hello\nWorld!" as &[u8];
/// let mut reader = BufReader::new(f);
///
/// let capacity = reader.capacity();
Expand All @@ -267,11 +279,12 @@ impl<R: ?Sized> BufReader<R> {
/// # Examples
///
/// ```no_run
/// # #![feature(alloc_io)]
/// # use alloc as std;
/// use std::io::BufReader;
/// use std::fs::File;
///
/// fn main() -> std::io::Result<()> {
/// let f1 = File::open("log.txt")?;
/// let f1 = b"Hello\nWorld!" as &[u8];
/// let reader = BufReader::new(f1);
///
/// let f2 = reader.into_inner();
Expand Down Expand Up @@ -575,13 +588,17 @@ impl<R: ?Sized + Seek> Seek for BufReader<R> {
/// # Example
///
/// ```no_run
/// use std::{
/// io::{self, BufRead, BufReader, Seek},
/// fs::File,
/// };
/// # #![feature(alloc_io)]
/// # #![allow(unused_must_use)]
/// # use alloc as std;
/// # use alloc::format as println;
/// # use alloc::string::String;
/// use std::io::{self, BufRead, BufReader, Seek};
///
/// fn main() -> io::Result<()> {
/// let mut f = BufReader::new(File::open("foo.txt")?);
/// let data = b"Hello\nWorld!" as &[u8];
/// let cursor = io::Cursor::new(data);
/// let mut f = BufReader::new(cursor);
///
/// let before = f.stream_position()?;
/// f.read_line(&mut String::new())?;
Expand Down
Loading
Loading