PronounsToday/src/user_preferences/error.rs

106 lines
3.4 KiB
Rust

//! Errors that might occur when parsing or rendering prefstrings
//!
//! There are several possible points at which an error might occur when working with user
//! preference string. Each of these points are documented here, as well as
//! human-readable error messages and explainations of each.
use std::{
fmt,
ops::Range,
};
use data_encoding::DecodeError;
/// An error occured while trying to parse a user's prefstring
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum ParseError {
/// The provided prefstring wasn't properly formatted base32 text
///
/// This could be because an implementation generated text with a different alphabet,
/// or the provided text isn't base32 at all. The [`DecodeError`] in the error is the
/// error that caused this exception.
Base32Error(DecodeError),
/// The version of the prefstring didn't match the version of the parser
///
/// This could occur when the prefstring is of a newer version than the parser, or the
/// parser is meant for a different version of the prefstring than expected.
///
/// Parsing typically works by having a master parser which supports all implemented
/// versions of prefstrings, and which delegates to several sub parsers. Each sub
/// parser handles one and only one version of the spec. This error could occur if,
/// for example, a v0 prefstring was fed to the v1 parser.
///
/// The `expected_version` and `expected_variant` properties denote the accepted
/// version or range of accepted versions that the parser supported. The `actual_`
/// properties denote what was received. These can be `None` if a version wasn't
/// specified.
///
/// If `actual_version` is [`Some`] then so must be `actual_variant`, and vice versa.
VersionMismatch {
expected_version: Range<u8>,
expected_variant: Range<u8>,
actual_version_byte: u8,
},
/// The `content` part of the prefstring was malformed
///
/// Whatever version of the specification the prefstring was being parsed with does
/// not allow whatever is going on in the prefstring. More details are provided in
/// human-readable form in the attached string.
MalformedContent(String),
/// The passed prefstring was zero-length
///
/// The minimum length for a prefstring is one byte, but the version that was passed
/// was zero bytes long. Often, this means that the developer should simply use the
/// instance default preferences.
ZeroLengthPrefstring,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ParseError::Base32Error(e) => {
write!(f,
"A problem occured while deserializing the preference string as base32: {}",
e
)
},
ParseError::VersionMismatch {
expected_version,
expected_variant,
actual_version_byte,
} => {
write!(f,
"A parser meant to handle prefstring version {} through {} and
variants {} throught {} was given a prefstring of version {} and
variant {}.",
expected_version.start,
expected_version.end - 1,
expected_variant.start,
expected_variant.end - 1,
actual_version_byte >> 3,
actual_version_byte & 0b00000111,
)
},
ParseError::MalformedContent(msg) => {
write!(f,"The prefstring's content was malformed: {}", msg)
},
ParseError::ZeroLengthPrefstring => {
write!(f, "Tried to parse a zero-length prefstring")
}
}
}
}
impl From<DecodeError> for ParseError {
fn from(e: DecodeError) -> Self {
ParseError::Base32Error(e)
}
}