binary_cookies/
error.rs

1use std::{error::Error, fmt::Display};
2
3use chrono::offset::LocalResult;
4use snafu::{Location, Snafu};
5use winnow::error::ContextError;
6
7#[derive(Debug)]
8#[derive(Snafu)]
9#[snafu(visibility(pub))]
10pub enum ParseError {
11    #[snafu(display("{render}\n@:{location}"))]
12    WinnowCtx {
13        render: ContextError,
14        #[snafu(implicit)]
15        location: Location,
16    },
17    #[snafu(display("Time broken: {local_result:?}\n@:{location}"))]
18    Time {
19        local_result: LocalResult<chrono::DateTime<chrono::Utc>>,
20        #[snafu(implicit)]
21        location: Location,
22    },
23    #[snafu(display("{source}\n@:{location}"))]
24    Bplist {
25        source: BplistErr,
26        #[snafu(implicit)]
27        location: Location,
28    },
29    #[snafu(display("Read: {source}\n@:{location}",))]
30    Read {
31        source: std::io::Error,
32        #[snafu(implicit)]
33        location: Location,
34    },
35    #[snafu(display("End of binarycookies, can't decode any more data\n@:{location}"))]
36    ParsingCompleted {
37        #[snafu(implicit)]
38        location: Location,
39    },
40}
41
42impl ParseError {
43    pub const fn is_completed(&self) -> bool {
44        matches!(self, Self::ParsingCompleted { .. })
45    }
46}
47
48#[derive(Clone, Copy)]
49#[derive(Debug)]
50#[derive(Snafu)]
51#[snafu(visibility(pub))]
52pub enum BplistErr {
53    #[snafu(display(
54        r#"Not start with b"bplist00"
55@:{location}"#
56    ))]
57    Magic {
58        #[snafu(implicit)]
59        location: Location,
60    },
61    #[snafu(display("The object not dict, need update decoder\n@:{location}"))]
62    NotDict {
63        #[snafu(implicit)]
64        location: Location,
65    },
66    #[snafu(display(
67        "The dict key not `NSHTTPCookieAcceptPolicy`, need update decoder\n@:{location}"
68    ))]
69    BadKey {
70        #[snafu(implicit)]
71        location: Location,
72    },
73    #[snafu(display("The int not one byte, need update decoder\n@:{location}"))]
74    OneByteInt {
75        #[snafu(implicit)]
76        location: Location,
77    },
78}
79
80#[derive(Clone, Copy)]
81#[derive(PartialEq, Eq, PartialOrd, Ord)]
82pub enum ExpectErr {
83    U32(u32),
84    U64(u64),
85    Magic([u8; 4]),
86    EndHeader([u8; 4]),
87}
88
89impl std::fmt::Debug for ExpectErr {
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91        f.write_fmt(format_args!("{}", self))
92    }
93}
94
95impl Error for ExpectErr {}
96
97impl Display for ExpectErr {
98    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99        match self {
100            Self::U32(binary) => f.write_fmt(format_args!("got: {:#>06x}", binary)),
101            Self::U64(binary) => f.write_fmt(format_args!("got: {:#010x}", binary)),
102            Self::Magic(e) => {
103                let s: String = e
104                    .iter()
105                    .map(|&v| v as char)
106                    .collect();
107                f.write_fmt(format_args!(r#"got: b"{s}""#))
108            },
109            Self::EndHeader(e) => f.write_fmt(format_args!("got: {e:?}")),
110        }
111    }
112}
113
114pub type Result<T> = std::result::Result<T, ParseError>;