Skip to content

Commit a218f27

Browse files
committed
Move Read::utf8_chars and utf8_chars_lossy to BufRead
per discussion after #27802 (comment)
1 parent f81aee4 commit a218f27

File tree

1 file changed

+107
-104
lines changed

1 file changed

+107
-104
lines changed

src/libstd/io/mod.rs

Lines changed: 107 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -703,88 +703,11 @@ pub trait Read {
703703
Bytes { inner: self }
704704
}
705705

706-
/// Transforms this `Read` instance to an `Iterator` over `char`s.
707-
///
708-
/// This adaptor will attempt to interpret this reader as a UTF-8 encoded
709-
/// sequence of characters. The returned iterator will return `None` once
710-
/// EOF is reached for this reader. Otherwise each element yielded will be a
711-
/// `Result<char, E>` where `E` may contain information about what I/O error
712-
/// occurred or where decoding failed.
713-
///
714-
/// # Examples
715-
///
716-
/// [`File`][file]s implement `Read`:
717-
///
718-
/// [file]: ../fs/struct.File.html
719-
///
720-
/// ```
721-
/// #![feature(io)]
722-
/// use std::io;
723-
/// use std::io::prelude::*;
724-
/// use std::fs::File;
725-
///
726-
/// # fn foo() -> io::Result<()> {
727-
/// let mut f = try!(File::open("foo.txt"));
728-
///
729-
/// for c in f.utf8_chars() {
730-
/// println!("{}", c.unwrap());
731-
/// }
732-
/// # Ok(())
733-
/// # }
734-
/// ```
735-
#[unstable(feature = "io", reason = "the semantics of a partial read/write \
736-
of where errors happen is currently \
737-
unclear and may change",
738-
issue = "27802")]
739-
fn utf8_chars(self) -> Utf8Chars<Self> where Self: Sized {
740-
Utf8Chars { inner: self, buffer: None }
741-
}
742-
743-
/// Former name of the `utf8_chars` method.
706+
/// Replaced with `BufRead::utf8_chars` and `BufRead::utf8_chars_lossy`.
744707
#[rustc_deprecated(since = "1.10.0", reason = "renamed to `utf8_chars`")]
745708
#[unstable(feature = "io", reason = "renamed while unstable", issue = "27802")]
746-
fn chars(self) -> Utf8Chars<Self> where Self: Sized {
747-
self.utf8_chars()
748-
}
749-
750-
/// Transforms this `Read` instance to an `Iterator` over `char`s.
751-
///
752-
/// This adaptor will attempt to interpret this reader as a UTF-8 encoded
753-
/// sequence of characters. The returned iterator will return `None` once
754-
/// EOF is reached for this reader. Otherwise each element yielded will be a
755-
/// `Result<char, E>` where `E` may contain information about what I/O error
756-
/// occurred.
757-
///
758-
/// Compared to `utf8_chars`, byte sequences invalid in UTF-8 are replaced
759-
/// with U+FFFD replacement characters instead of being a variant of error.
760-
///
761-
/// # Examples
762-
///
763-
/// [`File`][file]s implement `Read`:
764-
///
765-
/// [file]: ../fs/struct.File.html
766-
///
767-
/// ```
768-
/// #![feature(io)]
769-
/// use std::io;
770-
/// use std::io::prelude::*;
771-
/// use std::fs::File;
772-
///
773-
/// # fn foo() -> io::Result<()> {
774-
/// let mut f = try!(File::open("foo.txt"));
775-
///
776-
/// for c in f.utf8_chars_lossy() {
777-
/// println!("{}", c.unwrap());
778-
/// }
779-
/// # Ok(())
780-
/// # }
781-
/// ```
782-
#[unstable(feature = "io", reason = "the semantics of a partial read/write \
783-
of where errors happen is currently \
784-
unclear and may change",
785-
issue = "27802")]
786-
fn utf8_chars_lossy(self) -> Utf8CharsLossy<Self> where Self: Sized {
787-
Utf8CharsLossy { inner: self.utf8_chars() }
709+
fn chars(self) -> Utf8Chars<BufReader<Self>> where Self: Sized {
710+
BufReader::with_capacity(1, self).utf8_chars()
788711
}
789712

790713
/// Creates an adaptor which will chain this stream with another.
@@ -1353,6 +1276,83 @@ pub trait BufRead: Read {
13531276
read_until(self, byte, buf)
13541277
}
13551278

1279+
1280+
/// Transforms this `BufRead` instance to an `Iterator` over `char`s.
1281+
///
1282+
/// This adaptor will attempt to interpret this reader as a UTF-8 encoded
1283+
/// sequence of characters. The returned iterator will return `None` once
1284+
/// EOF is reached for this reader. Otherwise each element yielded will be a
1285+
/// `Result<char, E>` where `E` may contain information about what I/O error
1286+
/// occurred or where decoding failed.
1287+
///
1288+
/// # Examples
1289+
///
1290+
/// [`File`][file]s implement `Read`:
1291+
///
1292+
/// [file]: ../fs/struct.File.html
1293+
///
1294+
/// ```
1295+
/// #![feature(io)]
1296+
/// use std::io;
1297+
/// use std::io::prelude::*;
1298+
/// use std::fs::File;
1299+
///
1300+
/// # fn foo() -> io::Result<()> {
1301+
/// let mut f = io::BufReader::new(try!(File::open("foo.txt")));
1302+
///
1303+
/// for c in f.utf8_chars() {
1304+
/// println!("{}", c.unwrap());
1305+
/// }
1306+
/// # Ok(())
1307+
/// # }
1308+
/// ```
1309+
#[unstable(feature = "io", reason = "the semantics of a partial read/write \
1310+
of where errors happen is currently \
1311+
unclear and may change",
1312+
issue = "27802")]
1313+
fn utf8_chars(self) -> Utf8Chars<Self> where Self: Sized {
1314+
Utf8Chars { inner: self }
1315+
}
1316+
1317+
/// Transforms this `BufRead` instance to an `Iterator` over `char`s.
1318+
///
1319+
/// This adaptor will attempt to interpret this reader as a UTF-8 encoded
1320+
/// sequence of characters. The returned iterator will return `None` once
1321+
/// EOF is reached for this reader. Otherwise each element yielded will be a
1322+
/// `Result<char, E>` where `E` may contain information about what I/O error
1323+
/// occurred.
1324+
///
1325+
/// Compared to `utf8_chars`, byte sequences invalid in UTF-8 are replaced
1326+
/// with U+FFFD replacement characters instead of being a variant of error.
1327+
///
1328+
/// # Examples
1329+
///
1330+
/// [`File`][file]s implement `Read`:
1331+
///
1332+
/// [file]: ../fs/struct.File.html
1333+
///
1334+
/// ```
1335+
/// #![feature(io)]
1336+
/// use std::io;
1337+
/// use std::io::prelude::*;
1338+
/// use std::fs::File;
1339+
///
1340+
/// # fn foo() -> io::Result<()> {
1341+
/// let mut f = io::BufReader::new(try!(File::open("foo.txt")));
1342+
///
1343+
/// for c in f.utf8_chars_lossy() {
1344+
/// println!("{}", c.unwrap());
1345+
/// }
1346+
/// # Ok(())
1347+
/// # }
1348+
/// ```
1349+
#[unstable(feature = "io", reason = "the semantics of a partial read/write \
1350+
of where errors happen is currently \
1351+
unclear and may change",
1352+
issue = "27802")]
1353+
fn utf8_chars_lossy(self) -> Utf8CharsLossy<Self> where Self: Sized {
1354+
Utf8CharsLossy { inner: self.utf8_chars() }
1355+
}
13561356
/// Read all bytes until a newline (the 0xA byte) is reached, and append
13571357
/// them to the provided buffer.
13581358
///
@@ -1597,18 +1597,17 @@ impl<R: Read> Iterator for Bytes<R> {
15971597
/// This struct is generally created by calling [`utf8_chars()`][utf8_chars] on a reader.
15981598
/// Please see the documentation of `utf8_chars()` for more details.
15991599
///
1600-
/// [utf8_chars]: trait.Read.html#method.utf8_chars
1601-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars",
1600+
/// [utf8_chars]: trait.BufRead.html#method.utf8_chars
1601+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars",
16021602
issue = "27802")]
16031603
pub struct Utf8Chars<R> {
16041604
inner: R,
1605-
buffer: Option<u8>,
16061605
}
16071606

16081607
/// An enumeration of possible errors that can be generated from the `Utf8Chars`
16091608
/// adapter.
16101609
#[derive(Debug)]
1611-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars",
1610+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars",
16121611
issue = "27802")]
16131612
pub enum Utf8CharsError {
16141613
/// Variant representing that the underlying stream was read successfully
@@ -1623,43 +1622,47 @@ pub enum Utf8CharsError {
16231622
Io(Error),
16241623
}
16251624

1626-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars",
1625+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars",
16271626
issue = "27802")]
1628-
impl<R: Read> Iterator for Utf8Chars<R> {
1627+
impl<R: BufRead> Iterator for Utf8Chars<R> {
16291628
type Item = result::Result<char, Utf8CharsError>;
16301629

16311630
fn next(&mut self) -> Option<result::Result<char, Utf8CharsError>> {
1632-
let mut buf = [0];
16331631
macro_rules! read_byte {
16341632
(EOF => $on_eof: expr) => {
16351633
{
1634+
let byte;
16361635
loop {
1637-
match self.inner.read(&mut buf) {
1638-
Ok(0) => $on_eof,
1639-
Ok(..) => break,
1636+
match self.inner.fill_buf() {
1637+
Ok(buffer) => {
1638+
if let Some(&b) = buffer.first() {
1639+
byte = b;
1640+
break
1641+
} else {
1642+
$on_eof
1643+
}
1644+
}
16401645
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
16411646
Err(e) => return Some(Err(Utf8CharsError::Io(e))),
16421647
}
16431648
}
1644-
buf[0]
1649+
byte
16451650
}
16461651
}
16471652
}
16481653

1649-
let first = match self.buffer.take() {
1650-
Some(byte) => byte,
1651-
None => read_byte!(EOF => return None),
1652-
};
1654+
let first = read_byte!(EOF => return None);
1655+
self.inner.consume(1);
16531656

16541657
macro_rules! continuation_byte {
16551658
($range: pat) => {
16561659
{
16571660
match read_byte!(EOF => return Some(Err(Utf8CharsError::IncompleteUtf8))) {
1658-
byte @ $range => (byte & 0b0011_1111) as u32,
1659-
byte => {
1660-
self.buffer = Some(byte);
1661-
return Some(Err(Utf8CharsError::InvalidUtf8))
1661+
byte @ $range => {
1662+
self.inner.consume(1);
1663+
(byte & 0b0011_1111) as u32
16621664
}
1665+
_ => return Some(Err(Utf8CharsError::InvalidUtf8))
16631666
}
16641667
}
16651668
}
@@ -1702,7 +1705,7 @@ impl<R: Read> Iterator for Utf8Chars<R> {
17021705
}
17031706
}
17041707

1705-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars",
1708+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars",
17061709
issue = "27802")]
17071710
impl std_error::Error for Utf8CharsError {
17081711
fn description(&self) -> &str {
@@ -1722,7 +1725,7 @@ impl std_error::Error for Utf8CharsError {
17221725
}
17231726
}
17241727

1725-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars",
1728+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars",
17261729
issue = "27802")]
17271730
impl fmt::Display for Utf8CharsError {
17281731
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1744,15 +1747,15 @@ impl fmt::Display for Utf8CharsError {
17441747
/// Please see the documentation of `utf8_chars()` for more details.
17451748
///
17461749
/// [utf8_chars]: trait.Read.html#method.utf8_chars
1747-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars_lossy",
1750+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars_lossy",
17481751
issue = "27802")]
17491752
pub struct Utf8CharsLossy<R> {
17501753
inner: Utf8Chars<R>,
17511754
}
17521755

1753-
#[unstable(feature = "io", reason = "awaiting stability of Read::utf8_chars",
1756+
#[unstable(feature = "io", reason = "awaiting stability of BufRead::utf8_chars",
17541757
issue = "27802")]
1755-
impl<R: Read> Iterator for Utf8CharsLossy<R> {
1758+
impl<R: BufRead> Iterator for Utf8CharsLossy<R> {
17561759
type Item = result::Result<char, Error>;
17571760

17581761
fn next(&mut self) -> Option<result::Result<char, Error>> {

0 commit comments

Comments
 (0)