pub struct Error { /* private fields */ }Expand description
The error type for operations of the BufRead trait and associated iterators.
It can be created from an io::Error or an ErrorKind.
Instances of this error may contain some bytes that would have been lost otherwise.
§Examples
use utf8_bufread::Error;
use std::io::ErrorKind;
let error = Error::from(ErrorKind::InvalidData);Implementations§
Source§impl Error
impl Error
Sourcepub fn leftovers(&self) -> &[u8] ⓘ
pub fn leftovers(&self) -> &[u8] ⓘ
Get the “leftover” bytes stored in this error.
Leftover bytes are bytes that were read from the inner reader of a type implementing
io::BufRead, before clearing the buffer and filling it again, in a call to one of
BufRead’s functions that returned an error. This means that they form an invalid or
incomplete codepoint but would be lost if not returned with this error, as the call cleared
the buffer they were coming from.
It is guaranteed that, if the error contains a non-zero amount of leftover bytes, the following read operation on the reader that returned the error will not return any of those bytes, nor “skip” bytes from the reader.
It is also guaranteed that, if the error contains a non-zero amount of leftover bytes, their amount is of the expected length of a codepoint, based on the first invalid byte read, i.e. the first of the leftover bytes.
If you want to be sure not to lose any bytes from the inner reader, you should check if
the error is holding “leftovers” with error.leftovers.is_empty().
§Examples
The following example plays with buffer capacity to purposefully trigger a read that will return an error holding leftover bytes. The user should not bother thinking about buffer capacity in most cases, so this example may be a bit harder to follow along.
use std::io::{BufReader, Read};
use utf8_bufread::BufRead;
let input = "💖💖";
assert_eq!(input.len(), 8);
// The reader will successfully read the first codepoint, but trying to read the second one
// will result in an error since '💖' is 4 byte long, and we only take the first 7 bytes.
// Since the reader as a buffer capacity of 6, it will have to clear and refill its buffer
// to attempt reading the incomplete codepoint, then fail.
let mut reader = BufReader::with_capacity(6, &input.as_bytes()[..7]);
// First read is successful
let s = reader.read_str().unwrap();
assert_eq!(s.as_ref(), "💖");
// Storing how many bytes were read with the first call for later use
let first_read_len = s.len();
// Second read gives us an error
let err = reader.read_str();
assert!(err.is_err());
let err = err.unwrap_err();
// Since the reader had to clear and re-fill its buffer, the error will contained leftover
// bytes
assert!(!err.leftovers().is_empty());
// We can still "manually" read from the reader, but any bytes read before clearing the
// inner buffer are "lost" (they are stored as leftovers in previously returned error)
let mut buf: [u8; 8] = Default::default();
// If the reader didn't had to clear its buffer, we should have read 3 bytes.
// But since it did, we have 2 bytes stored in the error, hence why we only read 1 byte
assert_eq!(1, reader.read(&mut buf).unwrap());
// The input was truncated to 7 bytes, and we did read all 7 bytes
assert_eq!(7, first_read_len + err.leftovers().len() + 1)Sourcepub fn into_inner(self) -> Option<Box<dyn Error + Send + Sync>>
pub fn into_inner(self) -> Option<Box<dyn Error + Send + Sync>>
Consumes the Error, returning its inner error (if any).
If this Error was constructed from an ErrorKind, then this function will
return None, otherwise it will return Some.
§Panics
This function will panic if this error is holding “leftover” bytes.
§Examples
use std::io::{self, ErrorKind};
use utf8_bufread::Error;
fn print_error(err: Error) {
if let Some(inner_err) = err.into_inner() {
println!("Inner error: {}", inner_err);
} else {
println!("No inner error");
}
}
fn main() {
// Will print "No inner error".
print_error(Error::from(ErrorKind::Other));
// Will print "Inner error: ...".
print_error(Error::from(io::Error::from(ErrorKind::AddrInUse)));
}Sourcepub fn into_inner_checked(
self,
) -> Result<Option<Box<dyn Error + Send + Sync>>, Self>
pub fn into_inner_checked( self, ) -> Result<Option<Box<dyn Error + Send + Sync>>, Self>
Consumes the Error, returning its inner error (if any).
If this Error was constructed from an ErrorKind or is holding “leftover” bytes,
then this function will return None, otherwise it will return Some.
§Examples
use std::io::{self, ErrorKind};
use utf8_bufread::Error;
fn print_error(err: Error) {
if let Some(inner_err) = err.into_inner_checked().ok().flatten() {
println!("Inner error: {}", inner_err);
} else {
println!("No inner error, or transforming the error would cause data loss");
}
}
fn main() {
// Will print "No inner error".
print_error(Error::from(ErrorKind::Other));
// Will print "Inner error: ...".
print_error(Error::from(io::Error::from(ErrorKind::AddrInUse)));
}Sourcepub fn into_inner_lossy(self) -> Option<Box<dyn Error + Send + Sync>>
pub fn into_inner_lossy(self) -> Option<Box<dyn Error + Send + Sync>>
Consumes the Error, returning its inner error (if any).
If this Error was constructed from an ErrorKind, then this function will
return None, otherwise it will return Some. Any leftover bytes held by this error
are lost in the process.
§Examples
use std::io::{self, ErrorKind};
use utf8_bufread::Error;
fn print_error(err: Error) {
if let Some(inner_err) = err.into_inner() {
println!("Inner error: {}", inner_err);
} else {
println!("No inner error");
}
}
fn main() {
// Will print "No inner error".
print_error(Error::from(ErrorKind::Other));
// Will print "Inner error: ...".
print_error(Error::from(io::Error::from(ErrorKind::AddrInUse)));
}