1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use core::fmt::{Debug, Display};

use alloc::string::{String, ToString};
use wasmparser::Encoding;

#[derive(Debug)]
pub enum ParseError {
    InvalidType,
    UnsupportedSection(String),
    DuplicateSection(String),
    EmptySection(String),
    UnsupportedOperator(String),
    ParseError { message: String, offset: usize },
    InvalidEncoding(Encoding),
    InvalidLocalCount { expected: u32, actual: u32 },
    EndNotReached,
    Other(String),
}

impl Display for ParseError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::InvalidType => write!(f, "invalid type"),
            Self::UnsupportedSection(section) => write!(f, "unsupported section: {}", section),
            Self::DuplicateSection(section) => write!(f, "duplicate section: {}", section),
            Self::EmptySection(section) => write!(f, "empty section: {}", section),
            Self::UnsupportedOperator(operator) => write!(f, "unsupported operator: {}", operator),
            Self::ParseError { message, offset } => {
                write!(f, "error parsing module: {} at offset {}", message, offset)
            }
            Self::InvalidEncoding(encoding) => write!(f, "invalid encoding: {:?}", encoding),
            Self::InvalidLocalCount { expected, actual } => {
                write!(f, "invalid local count: expected {}, actual {}", expected, actual)
            }
            Self::EndNotReached => write!(f, "end of module not reached"),
            Self::Other(message) => write!(f, "unknown error: {}", message),
        }
    }
}

#[cfg(any(feature = "std", all(not(feature = "std"), nightly)))]
impl crate::std::error::Error for ParseError {}

impl From<wasmparser::BinaryReaderError> for ParseError {
    fn from(value: wasmparser::BinaryReaderError) -> Self {
        Self::ParseError {
            message: value.message().to_string(),
            offset: value.offset(),
        }
    }
}

pub type Result<T, E = ParseError> = core::result::Result<T, E>;