1use failure::Fail;
2
3#[derive(Debug, Fail, Clone)]
4pub enum DexParserError {
5 #[fail(display = "file unexpectedly ended early: expected {} bytes", needed)]
6 EndedEarly {
7 needed: usize
8 },
9 #[fail(display = "could not parse file: {}", reason)]
10 ParsingFailed {
11 reason: String
12 },
13 #[fail(display = "could not decode string to UTF8: may be malformed")]
14 EncodingError
15}
16
17impl<E: std::fmt::Debug + Clone> From<nom::Err<E>> for DexParserError {
18 fn from(e: nom::Err<E>) -> Self {
19 match e {
20 nom::Err::Incomplete(ref needed) => {
21 match needed {
22 nom::Needed::Unknown => DexParserError::ParsingFailed { reason: "file ended early".to_string() },
23 nom::Needed::Size(size) => DexParserError::EndedEarly { needed: *size }
24 }
25 },
26 nom::Err::Error(ctx) => {
27 match ctx {
28 nom::Context::Code(pos, kind) => {
29 DexParserError::ParsingFailed { reason: format!("parsing failed at byte {:?}: parser {:?}", pos, kind) }
30 },
31 nom::Context::List(errors) => {
32 let reason = errors.iter()
33 .map(|(pos, kind)| format!("parsing failed at byte {:?}: parser {:?}", pos, kind))
34 .collect::<Vec<String>>()
35 .join(": ");
36
37 DexParserError::ParsingFailed { reason }
38 }
39 }
40 },
41 nom::Err::Failure(ctx) => {
42 match ctx {
43 nom::Context::Code(pos, kind) => {
44 DexParserError::ParsingFailed { reason: format!("parsing failed at byte {:?}: parser {:?}", pos, kind) }
45 },
46 nom::Context::List(errors) => {
47 let reason = errors.iter()
48 .map(|(pos, kind)| format!("parsing failed at byte {:?}: parser {:?}", pos, kind))
49 .collect::<Vec<String>>()
50 .join(": ");
51
52 DexParserError::ParsingFailed { reason }
53 }
54 }
55 }
56 }
57 }
58}
59
60impl From<&'static str> for DexParserError {
61 fn from(e: &'static str) -> Self {
62 DexParserError::ParsingFailed { reason: e.to_string() }
63 }
64}
65
66impl From<String> for DexParserError {
67 fn from(e: String) -> Self {
68 DexParserError::ParsingFailed { reason: e }
69 }
70}
71
72impl From<::std::string::FromUtf8Error> for DexParserError {
73 fn from(_e: ::std::string::FromUtf8Error) -> Self {
74 DexParserError::ParsingFailed { reason: "could not parse string as UTF8".to_string() }
75 }
76}
77
78impl From<DexParserError> for nom::Err<&[u8]> {
79 fn from(e: DexParserError) -> Self {
80 nom::Err::Failure(nom::Context::Code(b"Failed to parse DEX file", nom::ErrorKind::Custom(0)))
82 }
83}