1
//! Declare an error type for the tor-consdiff crate.
2

            
3
use thiserror::Error;
4
use tor_netdoc::parse2;
5

            
6
use std::num::ParseIntError;
7

            
8
/// An error type from the tor-consdiff crate.
9
#[derive(Clone, Debug, Error)]
10
#[non_exhaustive]
11
pub enum Error {
12
    /// We got a consensus diff that we couldn't parse, or which we found
13
    /// to be somehow invalid.
14
    // TODO: it would be neat to have line numbers here.
15
    #[error("Invalid diff: {0}")]
16
    BadDiff(&'static str),
17

            
18
    /// We received or generated a diff that is implausibly large.
19
    #[error("Diff too large in relation to consensus")]
20
    DiffTooLarge,
21

            
22
    /// We got a consensus diff that looked valid, but we couldn't apply it
23
    /// to the given input.
24
    #[error("Diff didn't apply to input: {0}")]
25
    CantApply(&'static str),
26

            
27
    /// Invalid input for consdiff computation supplied, most likely not a valid
28
    /// consensus.
29
    #[error("Invalid input supplied: {0}")]
30
    InvalidInput(parse2::ParseError),
31

            
32
    /// Internal error.
33
    #[error("Internal error")]
34
    Bug(tor_error::Bug),
35
}
36

            
37
impl From<ParseIntError> for Error {
38
5
    fn from(_e: ParseIntError) -> Error {
39
5
        Error::BadDiff("can't parse line number")
40
5
    }
41
}
42
impl From<hex::FromHexError> for Error {
43
2
    fn from(_e: hex::FromHexError) -> Error {
44
2
        Error::BadDiff("invalid hexadecimal in 'hash' line")
45
2
    }
46
}
47

            
48
impl From<parse2::ParseError> for Error {
49
    fn from(e: parse2::ParseError) -> Self {
50
        Self::InvalidInput(e)
51
    }
52
}
53

            
54
impl From<tor_error::Bug> for Error {
55
    fn from(e: tor_error::Bug) -> Self {
56
        Self::Bug(e)
57
    }
58
}
59

            
60
/// An error type for consensus diff generation.
61
///
62
// TODO: Potentially make this a first-class citizen error and rename Error to
63
// ApplyConsDiffError.
64
#[derive(Clone, Debug, Error, PartialEq, Eq)]
65
pub(crate) enum GenEdDiffError {
66
    /// Line does not end with a Unix line ending.
67
    #[error("Line {lno} does not end with a Unix line ending")]
68
    MissingUnixLineEnding {
69
        /// The line number of the missing newline.
70
        lno: usize,
71
    },
72

            
73
    /// Diff results in the insertion of a line with a single dot, which is not
74
    /// possible according to the specification.
75
    #[error("Dotline found at {lno}")]
76
    ContainsDotLine {
77
        /// The line number of the missing newline.
78
        lno: usize,
79
    },
80

            
81
    /// Formatting error, mostly convenience to allow for `?` in write calls.
82
    #[error("Formatting error: {0}")]
83
    Write(#[from] std::fmt::Error),
84
}