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>;