python_marshal/
error.rs

1use std::{
2    fmt::{Display, Formatter, Result},
3    string::FromUtf16Error,
4};
5
6use crate::{magic::PyVersion, Kind, Object};
7
8/// Represents errors that can occur while reading or writing Python marshal data.
9#[derive(Debug)]
10#[allow(dead_code)]
11pub enum Error {
12    UnsupportedPyVersion(PyVersion),
13    NoMagicNumber,
14    NoTimeStamp,
15    NoHash,
16    UnsupportedMagicNumber(u32),
17    DigitOutOfRange(u16),
18    UnnormalizedLong,
19    NullInTuple,
20    NullInList,
21    NullInSet,
22    NullInDict,
23    UnreadableKind,
24    InvalidConversion,
25    InvalidKind(Kind),
26    InvalidObject(Object),
27    InvalidData(std::io::Error),
28    InvalidString,
29    InvalidUtf16String(std::string::FromUtf16Error),
30    InvalidReference(usize),
31    InvalidStoreRef,
32    UnexpectedObject,
33    UnexpectedNull,
34    DepthLimitExceeded,
35}
36
37impl Display for Error {
38    fn fmt(&self, f: &mut Formatter) -> Result {
39        match self {
40            Error::UnsupportedPyVersion(vers) => write!(
41                f,
42                "unsupported Python version: {}.{}",
43                vers.major, vers.minor
44            ),
45            Error::NoMagicNumber => write!(f, "no magic number found"),
46            Error::NoTimeStamp => write!(f, "no timestamp found"),
47            Error::NoHash => write!(f, "no hash found"),
48            Error::UnsupportedMagicNumber(magic) => {
49                write!(f, "unsupported magic number: 0x{:08X}", magic)
50            }
51            Error::DigitOutOfRange(digit) => write!(
52                f,
53                "bad marshal data (digit out of range in long): {}",
54                digit
55            ),
56            Error::UnnormalizedLong => write!(f, "bad marshal data (unnormalized long data)"),
57            Error::NullInTuple => write!(f, "NULL object in marshal data for tuple"),
58            Error::NullInList => write!(f, "NULL object in marshal data for list"),
59            Error::NullInSet => write!(f, "NULL object in marshal data for set"),
60            Error::NullInDict => write!(f, "NULL object in marshal data for dict"),
61            Error::UnreadableKind => write!(f, "bad marshal data (unreadable kind)"),
62            Error::InvalidConversion => write!(f, "bad marshal data (invalid conversion)"),
63            Error::InvalidKind(kind) => write!(f, "invalid kind: {:?}", kind),
64            Error::InvalidObject(obj) => write!(f, "invalid object: {:?}", obj),
65            Error::InvalidData(err) => write!(f, "bad marshal data: {:?}", err),
66            Error::InvalidString => {
67                write!(f, "bad marshal data (invalid string)")
68            }
69            Error::InvalidUtf16String(err) => {
70                write!(f, "bad marshal data (invalid utf16 string): {:?}", err)
71            }
72            Error::InvalidReference(index) => {
73                write!(f, "bad marshal data (invalid reference index: {})", index)
74            }
75            Error::InvalidStoreRef => write!(f, "bad marshal data (invalid store reference)"),
76            Error::DepthLimitExceeded => write!(f, "depth limit exceeded while processing object"),
77            Error::UnexpectedObject => write!(f, "unexpected object"),
78            Error::UnexpectedNull => write!(f, "unexpected NULL object"),
79        }
80    }
81}
82
83impl std::error::Error for Error {}
84
85impl From<std::io::Error> for Error {
86    fn from(err: std::io::Error) -> Self {
87        Error::InvalidData(err)
88    }
89}
90
91impl From<std::string::FromUtf16Error> for Error {
92    fn from(err: FromUtf16Error) -> Self {
93        Error::InvalidUtf16String(err)
94    }
95}