1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! OneNote parsing error handling.

#[cfg(feature = "backtrace")]
use std::backtrace::Backtrace;
use std::borrow::Cow;
use std::{io, string};
use thiserror::Error;

/// The result of parsing a OneNote file.
pub type Result<T> = std::result::Result<T, Error>;

/// A parsing error.
///
/// If the crate is compiled with the `backtrace` feature enabled, the
/// parsing error struct will contain a backtrace of the location where
/// the error occured. The backtrace can be accessed using
/// [`std::error::Error::backtrace()`].
#[derive(Error, Debug)]
#[error("{kind}")]
pub struct Error {
    kind: ErrorKind,

    #[cfg(feature = "backtrace")]
    backtrace: Backtrace,
}

impl From<ErrorKind> for Error {
    #[cfg(feature = "backtrace")]
    fn from(kind: ErrorKind) -> Self {
        Error {
            kind,
            backtrace: Backtrace::capture(),
        }
    }

    #[cfg(not(feature = "backtrace"))]
    fn from(kind: ErrorKind) -> Self {
        Error { kind }
    }
}

impl From<std::io::Error> for Error {
    fn from(err: std::io::Error) -> Self {
        ErrorKind::from(err).into()
    }
}

impl From<std::string::FromUtf16Error> for Error {
    fn from(err: std::string::FromUtf16Error) -> Self {
        ErrorKind::from(err).into()
    }
}

impl From<widestring::MissingNulError<u16>> for Error {
    fn from(err: widestring::MissingNulError<u16>) -> Self {
        ErrorKind::from(err).into()
    }
}

impl From<uuid::Error> for Error {
    fn from(err: uuid::Error) -> Self {
        ErrorKind::from(err).into()
    }
}

/// Details about a parsing error
#[allow(missing_docs)]
#[derive(Error, Debug)]
pub enum ErrorKind {
    /// Hit the end of the OneNote file before it was expected.
    #[error("Unexpected end of file")]
    UnexpectedEof,

    /// The parser was asked to process a table-of-contents file that turned out not to be one.
    #[error("Not a table of contents file: {file}")]
    NotATocFile { file: String },

    /// The parser was asked to process a section file that turned out not to be one.
    #[error("Not a section file: {file}")]
    NotASectionFile { file: String },

    /// When parsing a section group the table-of-contents file for this group was found to be missing.
    #[error("Table of contents file is missing in dir {dir}")]
    TocFileMissing { dir: String },

    /// Malformed data was encountered when parsing the OneNote file.
    #[error("Malformed data: {0}")]
    MalformedData(Cow<'static, str>),

    /// Malformed data was encountered when parsing the OneNote data.
    #[error("Malformed OneNote data: {0}")]
    MalformedOneNoteData(Cow<'static, str>),

    /// Malformed data was encountered when parsing the OneNote file contents.
    #[error("Malformed OneNote file data: {0}")]
    MalformedOneNoteFileData(Cow<'static, str>),

    /// Malformed data was encountered when parsing the OneStore data.
    #[error("Malformed OneStore data: {0}")]
    MalformedOneStoreData(Cow<'static, str>),

    /// Malformed data was encountered when parsing the FSSHTTPB data.
    #[error("Malformed FSSHTTPB data: {0}")]
    MalformedFssHttpBData(Cow<'static, str>),

    /// A malformed UUID was encountered
    #[error("Invalid UUID: {err}")]
    InvalidUuid {
        #[from]
        err: uuid::Error,
    },

    /// An I/O failure was encountered during parsing.
    #[error("I/O failure: {err}")]
    IO {
        #[from]
        err: io::Error,
    },

    /// A malformed UTF-16 string was encountered during parsing.
    #[error("Malformed UTF-16 string: {err}")]
    Utf16Error {
        #[from]
        err: string::FromUtf16Error,
    },

    /// A UTF-16 string without a null terminator was encountered during parsing.
    #[error("UTF-16 string is missing null terminator: {err}")]
    Utf16MissingNull {
        #[from]
        err: widestring::MissingNulError<u16>,
    },
}