1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//! Contains the definition of the error type used by the eoncoding functions in the crate.
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
/// The error returned by [`zalgo_encode`](crate::zalgo_encode), [`ZalgoString::new`](crate::ZalgoString::new), and [`zalgo_wrap_python`](crate::zalgo_wrap_python)
/// if they encounter a byte they can not encode.
///
/// Only implements the [`Error`](std::error::Error) trait if the `std` feature is enabled.
pub enum Error {
/// Represents a valid ASCII character that is outside of the encodable set.
/// The first `u8` in the variant is the byte value of the character, the first `usize`
/// is the 1-indexed line number where the character occured, the second `usize` is
/// the 1-indexed column in which the character occured and the `&str` is a description
/// of the character.
UnencodableAscii(u8, usize, usize, &'static str),
/// Represents some other character.
/// The two `usize`s represent the same thing as in the `UnencodableAscii` variant,
/// but the `u8` is only the first byte of the character.
NotAscii(u8, usize, usize),
}
impl Error {
/// Returns the 1-indexed line number of the line on which the unencodable byte occured.
///
/// # Examples
///
/// ```
/// # use zalgo_codec_common::{Error, zalgo_encode};
/// assert_eq!(zalgo_encode("❤️").err().unwrap().line(), 1);
/// assert_eq!(zalgo_encode("a\nb\nc\r\n").err().unwrap().line(), 3);
/// ```
#[must_use = "the method returns a new valus and does not modify `self`"]
pub const fn line(&self) -> usize {
match self {
Self::UnencodableAscii(_, line, _, _) | Self::NotAscii(_, line, _) => *line,
}
}
/// Returns the 1-indexed column where the unencodable byte occured.
/// Columns are counted from left to right and the count resets for each new line.
///
/// # Example
///
/// ```
/// # use zalgo_codec_common::{Error, zalgo_encode};
/// assert_eq!(zalgo_encode("I ❤️ 🎂").err().unwrap().column(), 3);
/// assert_eq!(zalgo_encode("I\n❤️\n🎂").err().unwrap().column(), 1);
/// ```
#[must_use = "the method returns a new valus and does not modify `self`"]
pub const fn column(&self) -> usize {
match self {
Self::UnencodableAscii(_, _, column, _) | Self::NotAscii(_, _, column) => *column,
}
}
/// Returns the value of the first byte of the unencodable character.
///
/// # Examples
///
/// ```
/// # use zalgo_codec_common::{Error, zalgo_encode};
/// assert_eq!(zalgo_encode("\r").err().unwrap().byte(), 13);
/// ```
/// Note that this might not be the complete representation of
/// the character in unicode, just the first byte of it.
/// ```
/// # use zalgo_codec_common::{Error, zalgo_encode};
/// assert_eq!(zalgo_encode("❤️").err().unwrap().byte(), 226);
/// // Even though
/// assert_eq!("❤️".as_bytes(), &[226, 157, 164, 239, 184, 143])
/// ```
#[must_use = "the method returns a new value and does not modify `self`"]
pub const fn byte(&self) -> u8 {
match self {
Self::UnencodableAscii(byte, _, _, _) | Self::NotAscii(byte, _, _) => *byte,
}
}
/// Return a representation of the unencodable byte.
/// This exists if the character is an unencodable ASCII character.
/// If it is some other unicode character we only know its first byte, so we can not
/// accurately represent it.
///
/// # Examples
///
/// ```
/// # use zalgo_codec_common::zalgo_encode;
/// assert_eq!(zalgo_encode("\r").err().unwrap().representation(), Some("Carriage Return"));
/// assert_eq!(zalgo_encode("❤️").err().unwrap().representation(), None);
/// ```
#[must_use = "the method returns a new value and does not modify `self`"]
pub const fn representation(&self) -> Option<&'static str> {
match self {
Self::UnencodableAscii(_, _, _, repr) => Some(*repr),
Self::NotAscii(_, _, _) => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::UnencodableAscii(byte, line, column, repr) => write!(
f,
"line {line} at column {column}: can not encode ASCII \"{repr}\" character with byte value {byte}"
),
Self::NotAscii(byte, line, column) => write!(
f,
"line {line} at column {column}: byte value {byte} does not correspond to an ASCII character"
),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}