2021-10-21 22:33:38 +00:00
|
|
|
//! 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
|
2021-10-22 01:48:13 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2021-10-21 22:33:38 +00:00
|
|
|
#[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,
|
2021-10-22 01:48:13 +00:00
|
|
|
|
|
|
|
/// The prefstring assumes the existance of more pronouns than exist
|
|
|
|
///
|
|
|
|
/// Often a symptom of a malformed prefstring, this error occurs when the prefstring
|
2021-10-22 03:06:14 +00:00
|
|
|
/// is correctly formatted, but when a [`crate::WeightedTable`] is formed
|
2021-10-22 01:48:13 +00:00
|
|
|
/// from it, the prefstring refers to a pronoun with an index greater than is in the
|
|
|
|
/// list. For example, setting the weight of pronoun set number 20 when there's only
|
|
|
|
/// 15 pronoun sets known by the instance.
|
|
|
|
///
|
|
|
|
/// This can be caused by reducing the number of available pronouns after a prefstring
|
|
|
|
/// has been generated, or by trying to parse a lucky malformed prefstring.
|
|
|
|
PrefstringExceedsPronounCount,
|
2021-10-22 03:06:14 +00:00
|
|
|
|
|
|
|
/// Attempted to roll or generate an empty table
|
|
|
|
///
|
|
|
|
/// Whatever you're doing, you would have ended up with an empty
|
|
|
|
/// [`crate::WeightedTable`], either by evaluating a prefstring that doesn't match any
|
|
|
|
/// pronouns, or by creating an invalid weighted table. Either way, you got this
|
|
|
|
/// error instead.
|
|
|
|
EmptyWeightedTable,
|
2021-10-21 22:33:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
2021-10-22 01:48:13 +00:00
|
|
|
},
|
|
|
|
ParseError::PrefstringExceedsPronounCount => {
|
|
|
|
write!(f, "The user preferences refers to pronouns beyond those that are known")
|
2021-10-21 22:33:38 +00:00
|
|
|
}
|
2021-10-22 03:06:14 +00:00
|
|
|
ParseError::EmptyWeightedTable => {
|
|
|
|
write!(f, "Attempted to create or roll an empty roll table")
|
|
|
|
}
|
2021-10-21 22:33:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<DecodeError> for ParseError {
|
|
|
|
fn from(e: DecodeError) -> Self {
|
|
|
|
ParseError::Base32Error(e)
|
|
|
|
}
|
|
|
|
}
|