#![warn(rust_2018_idioms)]
use std::error::Error as _;
#[cfg(feature = "std")]
use std::io;
use smol_bytes::{
Buffer, FromBytesError, InvalidIntegerLength, OutOfBounds, RangeOutOfBounds, TryPutError,
TryPutIntegerError, Utf8Bytes, Utf8BytesMut, Utf8Error,
};
#[test]
fn try_put_error_display_and_io() {
let big = [0u8; 63];
let err: TryPutError = Buffer::try_from(&big[..]).unwrap_err();
assert_eq!(err.requested, 63);
assert_eq!(err.available, 62);
assert_eq!(
err.to_string(),
"Not enough bytes remaining in buffer to write value (requested 63 but only 62 available)"
);
assert!(err.source().is_none());
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::Other);
assert!(
io_err
.to_string()
.contains("Not enough bytes remaining in buffer to write value")
);
}
}
#[test]
fn invalid_integer_length_display_from_and_io() {
let err = InvalidIntegerLength(9);
assert_eq!(
err.to_string(),
"invalid integer length: 9 (must be less or equal to 8)"
);
let promoted: TryPutIntegerError = err.into();
assert_eq!(promoted, TryPutIntegerError::InvalidLength(err));
assert_eq!(
promoted.to_string(),
"invalid integer length: 9 (must be less or equal to 8)"
);
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::InvalidInput);
assert!(io_err.to_string().contains("invalid integer length: 9"));
}
}
#[test]
fn try_put_integer_error_not_enough_space() {
let mut buf = Buffer::try_from(&[0u8; 60][..]).unwrap();
let err = buf.try_put_uint(0x010203, 3).unwrap_err();
assert_eq!(
err,
TryPutIntegerError::NotEnoughSpace(TryPutError {
requested: 3,
available: 2,
})
);
assert_eq!(
err.to_string(),
"Not enough bytes remaining in buffer to write value (requested 3 but only 2 available)"
);
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::Other);
}
}
#[test]
fn try_put_integer_error_invalid_length() {
let mut buf = Buffer::new();
let err = buf.try_put_uint(0, 9).unwrap_err();
assert_eq!(
err,
TryPutIntegerError::InvalidLength(InvalidIntegerLength(9))
);
assert_eq!(
err.to_string(),
"invalid integer length: 9 (must be less or equal to 8)"
);
}
#[test]
fn out_of_bounds_display_and_io() {
let mut buf = Buffer::try_from(&b"abc"[..]).unwrap();
let err: OutOfBounds = buf.try_advance(5).unwrap_err();
assert_eq!(err, OutOfBounds::new(5, 3));
assert_eq!(
err.to_string(),
"index out of bounds: requested 5 but only 3 available"
);
let mut buf = Buffer::try_from(&b"abc"[..]).unwrap();
assert_eq!(buf.try_split_off(10).unwrap_err(), OutOfBounds::new(10, 3));
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::InvalidInput);
assert!(
io_err
.to_string()
.contains("index out of bounds: requested 5")
);
}
}
#[test]
fn range_out_of_bounds_reversed_and_oob() {
let buf = Buffer::try_from(&b"hello"[..]).unwrap();
let (start, end) = (3usize, 2usize);
let err: RangeOutOfBounds = buf.try_slice(start..end).unwrap_err();
assert_eq!(err, RangeOutOfBounds::new(3, 2, 5));
assert_eq!(
err.to_string(),
"range out of bounds: requested 3..2 but only 5 available"
);
let err2 = buf.try_slice(0..10).unwrap_err();
assert_eq!(err2, RangeOutOfBounds::new(0, 10, 5));
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::InvalidInput);
assert!(
io_err
.to_string()
.contains("range out of bounds: requested 3..2")
);
}
}
#[test]
fn utf8_error_invalid_char_boundary() {
let mut s = Utf8BytesMut::from("café");
let err: Utf8Error = s.try_split_to(4).unwrap_err();
assert_eq!(err, Utf8Error::InvalidCharBoundary { at: 4 });
assert_eq!(
err.to_string(),
"index 4 does not lie on a UTF-8 character boundary"
);
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::InvalidInput);
assert!(
io_err
.to_string()
.contains("does not lie on a UTF-8 character boundary")
);
}
}
#[test]
fn utf8_error_out_of_bounds() {
let s = Utf8Bytes::from("hi");
let err: Utf8Error = s.try_slice(0..10).unwrap_err();
assert_eq!(err, Utf8Error::OutOfBounds { at: 10, len: 2 });
assert_eq!(err.to_string(), "index 10 out of bounds: length is 2");
}
#[test]
fn from_bytes_error_invalid_utf8() {
let raw: Vec<u8> = vec![0xFF, 0xFE];
let err: FromBytesError = smol_bytes::Utf8Buffer::try_from(raw.as_slice()).unwrap_err();
assert!(matches!(err, FromBytesError::InvalidUtf8(_)));
let text = err.to_string();
assert!(text.starts_with("invalid UTF-8: "), "got: {text}");
let inner = core::str::from_utf8(raw.as_slice()).unwrap_err();
assert!(text.contains(&inner.to_string()));
assert!(err.source().is_none());
let direct: FromBytesError = inner.into();
assert_eq!(direct, err);
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::InvalidInput);
assert!(io_err.to_string().contains("invalid UTF-8"));
}
}
#[test]
fn from_bytes_error_too_large() {
let long = [b'a'; 63];
let err: FromBytesError = smol_bytes::Utf8Buffer::try_from(&long[..]).unwrap_err();
assert!(matches!(err, FromBytesError::TooLarge(_)));
assert_eq!(
err.to_string(),
"Not enough bytes remaining in buffer to write value (requested 63 but only 62 available)"
);
assert!(err.source().is_none());
let put_err = TryPutError {
requested: 63,
available: 62,
};
let converted: FromBytesError = put_err.into();
assert_eq!(converted, err);
#[cfg(feature = "std")]
{
let io_err: io::Error = err.into();
assert_eq!(io_err.kind(), io::ErrorKind::InvalidInput);
}
}