1use std::{error::Error, fmt::Display};
2
3use winnow::error::ContextError;
4
5#[derive(Debug)]
6#[derive(thiserror::Error)]
7pub enum ParseError {
8 #[error("{0}")]
9 WinnowCtx(ContextError),
10 #[error("Time broken: {0:?}")]
11 Time(chrono::offset::LocalResult<chrono::DateTime<chrono::Utc>>),
12 #[error(transparent)]
13 Bplist(#[from] BplistErr),
14 #[error(transparent)]
15 IO(#[from] std::io::Error),
16 #[error("End of binarycookies, can't decode any more data")]
17 ParsingCompleted,
18}
19
20impl ParseError {
21 pub const fn is_completed(&self) -> bool {
22 matches!(self, Self::ParsingCompleted)
23 }
24}
25
26#[derive(Clone, Copy)]
27#[derive(Debug)]
28#[derive(thiserror::Error)]
29pub enum BplistErr {
30 #[error(r#"Not start with b"bplist00""#)]
31 Magic,
32 #[error(r#"The object not dict, need update decoder"#)]
33 NotDict,
34 #[error(r#"The dict key not `NSHTTPCookieAcceptPolicy`, need update decoder"#)]
35 BadKey,
36 #[error(r#"The int not one byte, need update decoder"#)]
37 OneByteInt,
38}
39
40#[derive(Clone, Copy)]
41#[derive(PartialEq, Eq, PartialOrd, Ord)]
42pub enum ExpectErr {
43 U32(u32),
44 U64(u64),
45 Magic([u8; 4]),
46 EndHeader([u8; 4]),
47}
48
49impl std::fmt::Debug for ExpectErr {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 f.write_fmt(format_args!("{}", self))
52 }
53}
54
55impl Error for ExpectErr {}
56
57impl Display for ExpectErr {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 match self {
60 Self::U32(binary) => f.write_fmt(format_args!("{:#>06x}", binary)),
61 Self::U64(binary) => f.write_fmt(format_args!("{:#010x}", binary)),
62 Self::Magic(e) => {
63 let s: String = e
64 .iter()
65 .map(|&v| v as char)
66 .collect();
67 f.write_fmt(format_args!(r#"b"{s}""#))
68 },
69 Self::EndHeader(e) => f.write_fmt(format_args!("{e:?}")),
70 }
71 }
72}
73
74pub type Result<T> = std::result::Result<T, ParseError>;