//! 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, Eq, PartialEq)] #[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, expected_variant: Range, 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, /// The prefstring assumes the existance of more pronouns than exist /// /// Often a symptom of a malformed prefstring, this error occurs when the prefstring /// is correctly formatted, but when a [`crate::WeightedTable`] is formed /// 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, /// 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, } 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") }, ParseError::PrefstringExceedsPronounCount => { write!(f, "The user preferences refers to pronouns beyond those that are known") } ParseError::EmptyWeightedTable => { write!(f, "Attempted to create or roll an empty roll table") } } } } impl From for ParseError { fn from(e: DecodeError) -> Self { ParseError::Base32Error(e) } }