use crate::NamespaceAlias;
use thiserror::Error as ThisError;
#[cfg(feature = "utils")]
#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
use std::{path::PathBuf, sync::Arc};
#[non_exhaustive]
#[derive(ThisError, Debug, Clone)]
pub enum Error {
#[error("Title contains illegal UTF-8 sequences or forbidden Unicode characters: \"{0}\"")]
IllegalUtf8(String),
#[error(
"Title is empty or contains only the name of a namespace: \"{0}\""
)]
Empty(String),
#[error("Title refers to a talk page that cannot exist: \"{0}\"")]
TalkNamespace(String),
#[error("Title has relative path: \"{0}\"")]
Relative(String),
#[error("Title contains invalid magic tilde sequence (~~~): \"{0}\"")]
MagicTildes(String),
#[error("Title is too long")]
TooLong(String),
#[error("Title starts with a leading colon: \"{0}\"")]
LeadingColon(String),
#[error("Title has invalid characters: \"{0}\"")]
Characters(String),
#[error("Unknown namespace aliases found")]
UnknownAliases(Vec<NamespaceAlias>),
#[cfg(feature = "parsing")]
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
#[error("Failed to generate regular expression for illegal title characters: {0}")]
IllegalTitleRegex(#[from] regex::Error),
#[error("Missing key in HashMap: {0}")]
NamespaceInfoMissingKey(&'static str),
#[error("Invalid ID in HashMap: {0}")]
NamespaceInfoInvalidId(String),
#[error("Unknown namespace ID: {0}")]
UnknownNamespace(i32),
#[error("Failed to parse JSON at {}", path.canonicalize().as_ref().unwrap_or(path).display())]
#[cfg(feature = "utils")]
#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
JsonFile {
path: PathBuf,
source: Arc<serde_json::Error>,
},
#[error("Failed to parse JSON")]
#[cfg(feature = "utils")]
#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
Json { source: Arc<serde_json::Error> },
#[error("Failed to {action} at {}", path.canonicalize().as_ref().unwrap_or(path).display())]
#[cfg(feature = "utils")]
#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
Io {
action: &'static str,
source: Arc<std::io::Error>,
path: PathBuf,
},
}
impl Error {
pub fn mw_title_codec_error_code(&self) -> Option<&'static str> {
use Error::*;
Some(match self {
IllegalUtf8(_) => "title-invalid-utf8",
Empty(_) => "title-invalid-empty",
TalkNamespace(_) => "title-invalid-talk-namespace",
Relative(_) => "title-invalid-relative",
MagicTildes(_) => "title-invalid-magic-tilde",
TooLong(_) => "title-invalid-too-long",
LeadingColon(_) => "title-invalid-leading-colon",
Characters(_) => "title-invalid-characters",
_ => return None,
})
}
#[cfg(feature = "utils")]
pub fn from_io<P: Into<PathBuf>>(
action: &'static str,
source: std::io::Error,
path: P,
) -> Self {
Error::Io {
action,
source: Arc::new(source),
path: path.into(),
}
}
}