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 got a consensus diff that looked valid, but we couldn't apply it
19
    /// to the given input.
20
    #[error("Diff didn't apply to input: {0}")]
21
    CantApply(&'static str),
22

            
23
    /// Invalid input for consdiff computation supplied, most likely not a valid
24
    /// consensus.
25
    #[error("Invalid input supplied: {0}")]
26
    InvalidInput(parse2::ParseError),
27

            
28
    /// Internal error.
29
    #[error("Internal error")]
30
    Bug(tor_error::Bug),
31
}
32

            
33
impl From<ParseIntError> for Error {
34
10
    fn from(_e: ParseIntError) -> Error {
35
10
        Error::BadDiff("can't parse line number")
36
10
    }
37
}
38
impl From<hex::FromHexError> for Error {
39
4
    fn from(_e: hex::FromHexError) -> Error {
40
4
        Error::BadDiff("invalid hexadecimal in 'hash' line")
41
4
    }
42
}
43

            
44
impl From<parse2::ParseError> for Error {
45
    fn from(e: parse2::ParseError) -> Self {
46
        Self::InvalidInput(e)
47
    }
48
}
49

            
50
impl From<tor_error::Bug> for Error {
51
    fn from(e: tor_error::Bug) -> Self {
52
        Self::Bug(e)
53
    }
54
}
55

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

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

            
77
    /// Formatting error, mostly convenience to allow for `?` in write calls.
78
    #[error("Formatting error: {0}")]
79
    Write(#[from] std::fmt::Error),
80
}