#![allow(clippy::useless_format)]
use super::*;
#[derive(Error, Clone, Debug, Eq, PartialEq)]
#[error(
"failed to parse network document, type {doctype}: {file}:{lno}{}",
match column {
// TODO MSRV 1.89 (or maybe earlier): change format! to format_args!
// https://releases.rs/docs/1.89.0/#libraries
// 2x here, and remove the clippy allow at the module top-level.
Some(column) => format!(".{}", *column),
None => format!(""),
},
)]
#[non_exhaustive]
pub struct ParseError {
#[source]
pub problem: ErrorProblem,
pub doctype: &'static str,
pub file: String,
pub lno: usize,
pub column: Option<usize>,
}
impl ParseError {
pub fn new(
problem: ErrorProblem,
doctype: &'static str,
file: &str,
lno: usize,
column: Option<usize>,
) -> Self {
Self {
problem,
doctype,
file: file.to_owned(),
lno,
column,
}
}
}
#[derive(Error, Copy, Clone, Debug, Eq, PartialEq, Deftly)]
#[derive_deftly(ErrorProblem)]
#[non_exhaustive]
pub enum ErrorProblem {
#[error("empty document")]
EmptyDocument,
#[error("wrong document type")]
WrongDocumentType,
#[error("multiple top-level documents")]
MultipleDocuments,
#[error("item missing required base64-encoded Object")]
MissingObject,
#[error("item repeated when not allowed")]
ItemRepeated,
#[error("item forbidden (in this kind of document or location)")]
ItemForbidden,
#[error("item repeated when not allowed")]
ItemMisplacedAfterSignature,
#[error("document contains nul byte")]
NulByte,
#[error("item keyword line starts with whitespace")]
KeywordLineStartsWithWhitespace,
#[error("no keyword when item keyword line expected")]
MissingKeyword,
#[error("no keyword when item keyword line expected: {0}")]
InvalidKeyword(#[from] keyword::InvalidKeyword),
#[error("missing item {keyword}")]
MissingItem {
keyword: &'static str,
},
#[error("missing argument {field}")]
MissingArgument {
field: &'static str,
},
#[error("invalid value for argument {field}")]
InvalidArgument {
field: &'static str,
column: usize,
},
#[error("too many arguments")]
UnexpectedArgument {
column: usize,
},
#[error("base64-encoded Object footer not found")]
ObjectMissingFooter,
#[error("base64-encoded Object END label does not match BEGIN")]
ObjectMismatchedLabels,
#[error("base64-encoded Object label is not as expected")]
ObjectIncorrectLabel,
#[error("base64-encoded Object has incorrectly formatted delimiter lines")]
InvalidObjectDelimiters,
#[error("base64-encoded Object found where none expected")]
ObjectUnexpected,
#[error("base64-encoded Object contains invalid base64")]
ObjectInvalidBase64,
#[error("base64-encoded Object contains invalid data")]
ObjectInvalidData,
#[error("other problem: {0}")]
OtherBadDocument(&'static str),
#[error("internal error in document parser: {0}")]
Internal(&'static str),
#[error("document parsing API misused: {0}")]
BadApiUsage(&'static str),
}
#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ArgumentError {
#[error("missing argument")]
Missing,
#[error("invalid value for argument")]
Invalid,
#[error("too many arguments")]
Unexpected,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct UnexpectedArgument {
pub(super) column: usize,
}
#[derive(Error, Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum VerifyFailed {
#[error("netdoc signature verification failed")]
VerifyFailed,
#[error("document is too new - clock skew?")]
TooNew,
#[error("document is too old")]
TooOld,
#[error("document not signed by the right testator (or too few known testators)")]
InsufficientTrustedSigners,
#[error("document has inconsistent content")]
Inconsistent,
#[error("parsing problem in embedded document")]
ParseEmbedded(#[from] ErrorProblem),
#[error("document has uncategorised problem found during verification")]
Other,
#[error("verification prevented by software bug")]
Bug,
}
impl From<signature::Error> for VerifyFailed {
fn from(_: signature::Error) -> VerifyFailed {
VerifyFailed::VerifyFailed
}
}
define_derive_deftly! {
ErrorProblem:
impl ErrorProblem {
pub fn column(&self) -> Option<usize> {
Some(match self {
${for fields {
${when approx_equal($fname, column)}
$vtype { column, .. } => *column,
}}
_ => return None,
})
}
}
}
use derive_deftly_template_ErrorProblem;
impl From<UnexpectedArgument> for ErrorProblem {
fn from(ua: UnexpectedArgument) -> ErrorProblem {
EP::UnexpectedArgument { column: ua.column }
}
}
impl From<UnexpectedArgument> for ArgumentError {
fn from(_ua: UnexpectedArgument) -> ArgumentError {
AE::Unexpected
}
}