@@ -1348,6 +1348,32 @@ impl<'r, T: Buffer> Iterator for Chars<'r, T> {
1348
1348
}
1349
1349
}
1350
1350
1351
+ /// Makes the possibility of `read_until` returning a sequence with a delimiter explicit
1352
+ /// Use `without_delimiter` if you always want the same type of result
1353
+ pub enum ReadUntilHelper {
1354
+ /// If you run `read_until` again after receiving `WithoutDelimiter`, you will get an EOF
1355
+ /// Does not contain the delimiter.
1356
+ WithoutDelimiter ( Vec < u8 > ) ,
1357
+ /// Always contains the delimiter. If the delimiter was just before the end of the Buffer,
1358
+ /// the next call to `read_until` will also give you an EOF.
1359
+ WithDelimiter ( Vec < u8 > ) ,
1360
+ }
1361
+
1362
+ impl ReadUntilHelper {
1363
+ /// Destructures the ReadUntilHelper by either removing the delimiter (if present) or
1364
+ /// directly returning the read block (if no delimiter was present)
1365
+ pub fn without_delimiter ( self ) -> Vec < u8 > {
1366
+ match self {
1367
+ ReadUntilHelper :: WithoutDelimiter ( x) => x,
1368
+ ReadUntilHelper :: WithDelimiter ( mut x) => {
1369
+ let len = x. len ( ) - 1 ;
1370
+ x. truncate ( len) ;
1371
+ x
1372
+ } ,
1373
+ }
1374
+ }
1375
+ }
1376
+
1351
1377
/// A Buffer is a type of reader which has some form of internal buffering to
1352
1378
/// allow certain kinds of reading operations to be more optimized than others.
1353
1379
/// This type extends the `Reader` trait with a few methods that are not
@@ -1374,15 +1400,15 @@ pub trait Buffer: Reader {
1374
1400
1375
1401
/// Reads the next line of input, interpreted as a sequence of UTF-8
1376
1402
/// encoded Unicode codepoints. If a newline is encountered, then the
1377
- /// newline is contained in the returned string.
1403
+ /// newline is NOT contained in the returned string.
1378
1404
///
1379
1405
/// # Example
1380
1406
///
1381
1407
/// ```rust
1382
1408
/// use std::io::BufReader;
1383
1409
///
1384
1410
/// let mut reader = BufReader::new(b"hello\nworld");
1385
- /// assert_eq!("hello\n ", &*reader.read_line().unwrap());
1411
+ /// assert_eq!("hello", &*reader.read_line().unwrap());
1386
1412
/// ```
1387
1413
///
1388
1414
/// # Error
@@ -1392,13 +1418,11 @@ pub trait Buffer: Reader {
1392
1418
/// * All non-EOF errors will be returned immediately
1393
1419
/// * If an error is returned previously consumed bytes are lost
1394
1420
/// * EOF is only returned if no bytes have been read
1395
- /// * Reach EOF may mean that the delimiter is not present in the return
1396
- /// value
1397
1421
///
1398
1422
/// Additionally, this function can fail if the line of input read is not a
1399
1423
/// valid UTF-8 sequence of bytes.
1400
1424
fn read_line ( & mut self ) -> IoResult < String > {
1401
- self . read_until ( b'\n' ) . and_then ( |line|
1425
+ self . read_until ( b'\n' ) . and_then ( |ruh| Ok ( ruh . without_delimiter ( ) ) ) . and_then ( | line|
1402
1426
match String :: from_utf8 ( line) {
1403
1427
Ok ( s) => Ok ( s) ,
1404
1428
Err ( _) => Err ( standard_error ( InvalidInput ) ) ,
@@ -1421,15 +1445,15 @@ pub trait Buffer: Reader {
1421
1445
/// have been read, otherwise the pending byte buffer is returned. This
1422
1446
/// is the reason that the byte buffer returned may not always contain the
1423
1447
/// delimiter.
1424
- fn read_until ( & mut self , byte : u8 ) -> IoResult < Vec < u8 > > {
1448
+ fn read_until ( & mut self , byte : u8 ) -> IoResult < ReadUntilHelper > {
1425
1449
let mut res = Vec :: new ( ) ;
1426
1450
1427
1451
loop {
1428
1452
let ( done, used) = {
1429
1453
let available = match self . fill_buf ( ) {
1430
1454
Ok ( n) => n,
1431
1455
Err ( ref e) if res. len ( ) > 0 && e. kind == EndOfFile => {
1432
- return Ok ( res) ;
1456
+ return Ok ( ReadUntilHelper :: WithoutDelimiter ( res) ) ;
1433
1457
}
1434
1458
Err ( e) => return Err ( e)
1435
1459
} ;
@@ -1446,7 +1470,7 @@ pub trait Buffer: Reader {
1446
1470
} ;
1447
1471
self . consume ( used) ;
1448
1472
if done {
1449
- return Ok ( res) ;
1473
+ return Ok ( ReadUntilHelper :: WithDelimiter ( res) ) ;
1450
1474
}
1451
1475
}
1452
1476
}
0 commit comments