Skip to main content

imessage_database/error/
plist.rs

1/*!
2 Errors that can happen when parsing plist data.
3*/
4
5use crabstep::error::TypedStreamError;
6
7use crate::error::digital_touch::DigitalTouchError;
8use crate::error::handwriting::HandwritingError;
9use std::fmt::{Display, Formatter, Result};
10
11/// Errors that can happen when parsing the plist data stored in the `payload_data` field
12#[derive(Debug)]
13pub enum PlistParseError {
14    /// Expected key was not found in the plist data
15    MissingKey(String),
16    /// No value was found at the specified index
17    NoValueAtIndex(usize),
18    /// Value had an incorrect type for the specified key
19    InvalidType(String, String),
20    /// Value had an incorrect type at the specified index
21    InvalidTypeIndex(usize, String),
22    /// Dictionary has mismatched number of keys and values
23    InvalidDictionarySize(usize, usize),
24    /// UID value cannot be represented as an object-table index on this target.
25    UidOutOfRange(u64),
26    /// No payload data was found
27    NoPayload,
28    /// Message is not of the expected type
29    WrongMessageType,
30    /// Could not parse an edited message
31    InvalidEditedMessage(String),
32    /// Error from typedstream parsing
33    TypedStreamError(TypedStreamError),
34    /// Error from handwriting data parsing
35    HandwritingError(HandwritingError),
36    /// Error from Digital Touch data parsing
37    DigitalTouchError(DigitalTouchError),
38    /// Error parsing a poll message
39    PollError,
40    /// Exceeded the maximum UID-reference resolution depth (likely a reference cycle)
41    RecursionLimit,
42}
43
44impl Display for PlistParseError {
45    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
46        match self {
47            PlistParseError::MissingKey(key) => write!(fmt, "Expected key {key}, found nothing!"),
48            PlistParseError::NoValueAtIndex(idx) => {
49                write!(fmt, "Payload referenced index {idx}, but there is no data!")
50            }
51            PlistParseError::InvalidType(key, value) => {
52                write!(fmt, "Invalid data found at {key}, expected {value}")
53            }
54            PlistParseError::InvalidTypeIndex(idx, value) => {
55                write!(
56                    fmt,
57                    "Invalid data found at object index {idx}, expected {value}"
58                )
59            }
60            PlistParseError::InvalidDictionarySize(a, b) => write!(
61                fmt,
62                "Invalid dictionary size, found {a} keys and {b} values"
63            ),
64            PlistParseError::UidOutOfRange(uid) => {
65                write!(fmt, "UID value {uid} cannot be used as an object index")
66            }
67            PlistParseError::NoPayload => write!(fmt, "Unable to acquire payload data!"),
68            PlistParseError::WrongMessageType => write!(fmt, "Message is not an app message!"),
69            PlistParseError::InvalidEditedMessage(message) => {
70                write!(fmt, "Unable to parse message from binary data: {message}")
71            }
72            PlistParseError::HandwritingError(why) => write!(fmt, "{why}"),
73            PlistParseError::DigitalTouchError(why) => write!(fmt, "{why}"),
74            PlistParseError::TypedStreamError(typed_stream_error) => {
75                write!(fmt, "TypedStream error: {typed_stream_error}")
76            }
77            PlistParseError::PollError => write!(fmt, "Unable to parse Poll Message!"),
78            PlistParseError::RecursionLimit => write!(
79                fmt,
80                "Exceeded maximum depth while resolving UID references; the archive may contain a reference cycle"
81            ),
82        }
83    }
84}
85
86impl std::error::Error for PlistParseError {
87    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
88        match self {
89            PlistParseError::TypedStreamError(e) => Some(e),
90            PlistParseError::HandwritingError(e) => Some(e),
91            PlistParseError::DigitalTouchError(e) => Some(e),
92            _ => None,
93        }
94    }
95}
96
97impl From<TypedStreamError> for PlistParseError {
98    fn from(error: TypedStreamError) -> Self {
99        PlistParseError::TypedStreamError(error)
100    }
101}