use core::fmt;
#[cfg(feature = "std")]
use std::backtrace::Backtrace;
use alloc::string::FromUtf8Error;
#[derive(Debug)]
pub struct EncodeError {
unencodable_character: char,
line: usize,
column: usize,
index: usize,
#[cfg(feature = "std")]
backtrace: Backtrace,
}
impl EncodeError {
#[inline]
#[must_use = "this associated method does not modify its inputs and just returns a new value"]
pub(crate) fn new(
unencodable_character: char,
line: usize,
column: usize,
index: usize,
) -> Self {
Self {
unencodable_character,
line,
column,
index,
#[cfg(feature = "std")]
backtrace: Backtrace::capture(),
}
}
#[inline]
#[must_use = "the method returns a new value and does not modify `self`"]
pub const fn line(&self) -> usize {
self.line
}
#[inline]
#[must_use = "the method returns a new value and does not modify `self`"]
pub const fn column(&self) -> usize {
self.column
}
#[inline]
#[must_use = "the method returns a new value and does not modify `self`"]
pub const fn char(&self) -> char {
self.unencodable_character
}
#[inline]
#[must_use = "the method returns a new value and does not modify `self`"]
pub const fn index(&self) -> usize {
self.index
}
#[cfg(feature = "std")]
#[inline]
pub fn backtrace(&self) -> &Backtrace {
&self.backtrace
}
}
impl fmt::Display for EncodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"can not encode {:?} character at string index {}, on line {} at column {}",
self.char(),
self.index(),
self.line(),
self.column(),
)
}
}
impl core::error::Error for EncodeError {}
#[derive(Debug)]
pub struct DecodeError {
source_error: FromUtf8Error,
#[cfg(feature = "std")]
backtrace: Backtrace,
}
impl DecodeError {
pub(crate) fn new(source_error: FromUtf8Error) -> Self {
Self {
#[cfg(feature = "std")]
backtrace: Backtrace::capture(),
source_error,
}
}
#[cfg(feature = "std")]
pub fn backtrace(&self) -> &Backtrace {
&self.backtrace
}
pub fn into_from_utf8_error(self) -> FromUtf8Error {
self.source_error
}
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"could not decode the string because {}",
self.source_error
)
}
}
impl core::error::Error for DecodeError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
Some(&self.source_error)
}
}
#[cfg(test)]
mod test {
use super::{DecodeError, EncodeError};
use alloc::{string::String, vec};
#[test]
fn test_error() {
let err = EncodeError::new('å', 1, 7, 6);
assert_eq!(err.char(), 'å');
assert_eq!(err.line(), 1);
assert_eq!(err.column(), 7);
assert_eq!(err.index(), 6);
}
#[test]
fn test_decode_error() {
let err =
DecodeError::new(String::from_utf8(vec![255, 255, 255, 255, 255, 255]).unwrap_err());
assert_eq!(err.into_from_utf8_error().into_bytes(), vec![255; 6]);
}
}