1use std::fmt;
7
8use crate::verify::Category;
9use crate::verify::render::Comparison;
10
11#[derive(Debug)]
12#[non_exhaustive]
13pub enum Refusal {
14 Unparseable(lopdf::Error),
16 PasswordRequired,
18 UndecryptedCryptFilters,
21 DamagedPageTree,
23 DamagedResources,
25 VerificationRegressed(Vec<(Category, usize, usize)>),
28 BelowSimilarityFloor(Comparison),
30 Internal(anyhow::Error),
32}
33
34impl fmt::Display for Refusal {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Refusal::Unparseable(e) => write!(f, "parsing the input: {e}"),
38 Refusal::PasswordRequired => {
39 f.write_str("input is encrypted with a password that is needed to open it")
40 }
41 Refusal::UndecryptedCryptFilters => f.write_str(
42 "input is encrypted with crypt filters the parser could not read, so it was not decrypted",
43 ),
44 Refusal::DamagedPageTree => {
45 f.write_str("page tree refers to objects the parser could not load")
46 }
47 Refusal::DamagedResources => {
48 f.write_str("page content or resources refer to objects the parser could not load")
49 }
50 Refusal::VerificationRegressed(regressions) => write!(
51 f,
52 "output failed verification with new problems {regressions:?}; nothing written (this is a bug, please report it)"
53 ),
54 Refusal::BelowSimilarityFloor(_) => {
55 f.write_str("pages below the similarity floor; nothing written (--strict)")
56 }
57 Refusal::Internal(e) => write!(f, "{e:#}"),
58 }
59 }
60}
61
62impl std::error::Error for Refusal {
63 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
64 match self {
65 Refusal::Unparseable(e) => Some(e),
66 Refusal::Internal(e) => Some(e.as_ref()),
67 _ => None,
68 }
69 }
70}
71
72impl From<anyhow::Error> for Refusal {
75 fn from(e: anyhow::Error) -> Self {
76 Refusal::Internal(e)
77 }
78}