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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
use std::{borrow::Cow, string::FromUtf8Error};
use thiserror::Error;
/// Overall error type for everything that can go wrong with
/// Java deserialization
#[derive(Debug, Error)]
pub enum JavaError {
/// An error in the read/stream/deserialization process
#[error("Error read from stream")]
ReadError(#[from] StreamError),
/// An error arising from the conversion of read data to Rust struct
#[error("Error converting read object into something useful: {0}")]
ConvertError(#[from] ConversionError),
}
/// Error for things that can go wrong with deserialization
#[derive(Debug, Error)]
pub enum StreamError {
/// If the stream ends while the parser is still expecting more data
#[error("Unexpected end of stream")]
EndOfStream(#[from] std::io::Error),
/// If the stream does not represent Serialized Java objects
#[error("This isn't a JavaObject - magic numbers: {0:X}")]
NonJavaObject(u16),
/// If the stream version is not one we can handle
#[error("Unknown serialization version: {0}")]
UnknownVersion(u16),
/// If the next stream marker is not a value recognised by the serialization
/// protocol
///
/// The byte read from the stream will be included in the error.
#[error("Unknown mark: {0}")]
UnknownMark(u8),
/// If the type or a field is not one of the allowed characters
///
/// The character being read as a type specification is included in the error
#[error("Unknown type marker: {0}")]
UnrecognisedType(char),
/// If a back reference is to an unregistered handle
///
/// The unrecognised handle is included in the error
#[error("Unknown reference handle: {0}")]
UnknownReference(u32),
/// If the reference registered to a handle is not of the correct type
///
/// The included string is the type that was expected, not the type found.
#[error("Invalid reference. Expected {0}")]
InvalidReference(&'static str),
/// The stream is not valid for some other reason
///
/// The included string gives an error message of the problem found.
#[error("Invalid Stream: {0}")]
InvalidStream(&'static str),
/// This feature is not implemented yet
/// Some features are not possible without access to the Java source that
/// wrote the stream.
#[error("{0} isn't implemented yet")]
NotImplemented(&'static str),
}
impl From<FromUtf8Error> for StreamError {
fn from(_: FromUtf8Error) -> Self {
StreamError::InvalidStream("String is not valid UTF-8")
}
}
/// Things that can go wrong when converting deserialized java objects into
/// Rust entities
#[derive(Debug, Error)]
pub enum ConversionError {
/// Error signifying a required field does not exist in the deserialized
/// Java Object
#[error("Field '{0}' does not exist")]
FieldNotFound(String),
/// Everyone's favourite Java exception brought to rust. Returned if a
/// non-optional field has a null value.
#[error("No object found")]
NullPointerException,
/// The deserialized object was not the type required.
#[error("Expected '{0}'")]
InvalidType(&'static str),
/// Read block data instead of object
#[error("Unexpected block data")]
UnexpectedBlockData(Vec<u8>),
/// Annotation not available
#[error("Missing Annotation: {0}")]
MissingAnnotations(usize),
/// Incorrect class
#[error("Expected class '{0}', found '{1}'")]
IncorrectClass(Cow<'static, str>, Cow<'static, str>),
/// Unmatched class for enum
#[error("Class '{0}' was not expected")]
UnexpectedClass(String),
}