1 use std::io; 2 use std::str; 3 4 use crate::reflect::error::ReflectError; 5 use crate::wire_format::WireType; 6 7 /// [`Result`] alias for [`Error`]. 8 pub type Result<T> = std::result::Result<T, crate::Error>; 9 10 /// Enum values added here for diagnostic purposes. 11 /// Users should not depend on specific values. 12 #[derive(Debug, thiserror::Error)] 13 pub(crate) enum WireError { 14 #[error("Unexpected EOF")] 15 UnexpectedEof, 16 #[error("Unexpected wire type")] 17 UnexpectedWireType(WireType), 18 #[error("Incorrect tag")] 19 IncorrectTag(u32), 20 #[error("Incorrect varint")] 21 IncorrectVarint, 22 #[error("Invalid UTF-8 sequence")] 23 Utf8Error, 24 #[error("Invalid enum `{}` value: {}", .0, .1)] 25 InvalidEnumValue(&'static str, i32), 26 #[error("Over recursion limit")] 27 OverRecursionLimit, 28 #[error("Truncated message")] 29 TruncatedMessage, 30 // not really possible 31 #[error("Limit overflow")] 32 LimitOverflow, 33 #[error("New limit must not be greater than current limit")] 34 LimitIncrease, 35 #[error("Encoded message size {0} is too large")] 36 MessageTooLarge(u64), 37 #[error("Value too large for u32: {}", .0)] 38 U32Overflow(u64), 39 #[error("Value too large for i32: {}", .0)] 40 I32Overflow(i64), 41 } 42 43 /// Generic protobuf error 44 #[derive(Debug, thiserror::Error)] 45 pub(crate) enum ProtobufError { 46 /// I/O error when reading or writing 47 #[error(transparent)] 48 IoError(#[from] io::Error), 49 /// Malformed input 50 #[error(transparent)] 51 WireError(#[from] WireError), 52 #[error(transparent)] 53 Reflect(#[from] ReflectError), 54 /// Protocol contains a string which is not valid UTF-8 string 55 #[error("UTF-8 decode error")] 56 Utf8( 57 #[source] 58 #[from] 59 str::Utf8Error, 60 ), 61 /// Not all required fields of message set. 62 #[error("Message `{}` is missing required fields", .0)] 63 MessageNotInitialized(String), 64 /// Message is too large. 65 #[error("Provided buffer has not enough capacity to write message `{0}`")] 66 BufferHasNotEnoughCapacity(String), 67 /// Protobuf type and runtime types mismatch. 68 #[error("Protobuf type and runtime types are not compatible")] 69 IncompatibleProtobufTypeAndRuntimeType, 70 /// Group field type not implemented. 71 #[error("Group field is not supported")] 72 GroupIsNotImplemented, 73 } 74 75 /// Error type for protobuf operations. 76 #[derive(Debug, thiserror::Error)] 77 #[error(transparent)] 78 pub struct Error(pub(crate) Box<ProtobufError>); 79 80 impl From<ProtobufError> for Error { 81 #[cold] from(e: ProtobufError) -> Self82 fn from(e: ProtobufError) -> Self { 83 Self(Box::new(e)) 84 } 85 } 86 87 impl From<WireError> for Error { 88 #[cold] from(e: WireError) -> Self89 fn from(e: WireError) -> Self { 90 Self(Box::new(ProtobufError::WireError(e))) 91 } 92 } 93 94 impl From<ReflectError> for Error { 95 #[cold] from(e: ReflectError) -> Self96 fn from(e: ReflectError) -> Self { 97 Self(Box::new(ProtobufError::Reflect(e))) 98 } 99 } 100 101 impl From<Error> for io::Error { 102 #[cold] from(err: Error) -> Self103 fn from(err: Error) -> Self { 104 match *err.0 { 105 ProtobufError::IoError(e) => e, 106 ProtobufError::WireError(e) => { 107 io::Error::new(io::ErrorKind::InvalidData, ProtobufError::WireError(e)) 108 } 109 ProtobufError::MessageNotInitialized(message) => io::Error::new( 110 io::ErrorKind::InvalidInput, 111 ProtobufError::MessageNotInitialized(message), 112 ), 113 e => io::Error::new(io::ErrorKind::Other, Box::new(e)), 114 } 115 } 116 } 117 118 impl From<io::Error> for Error { 119 #[cold] from(err: io::Error) -> Self120 fn from(err: io::Error) -> Self { 121 Error(Box::new(ProtobufError::IoError(err))) 122 } 123 } 124 125 #[cfg(test)] 126 mod test { 127 use std::mem; 128 129 #[test] error_size()130 fn error_size() { 131 assert_eq!(mem::size_of::<usize>(), mem::size_of::<crate::Error>()); 132 } 133 } 134