1use std::error::Error;
2use std::str;
3
4use snafu::{Backtrace, IntoError, Snafu};
5
6use crate::value::Value;
7
8#[derive(Snafu, Debug)]
9#[snafu(visibility(pub), context(suffix(false)))]
10#[non_exhaustive]
11pub enum DecodeError {
12 #[snafu(display("unexpected end of frame"))]
13 Underflow { backtrace: Backtrace },
14 #[snafu(display("frame contains extra data after decoding"))]
15 ExtraData { backtrace: Backtrace },
16 #[snafu(display("invalid utf8 when decoding string: {}", source))]
17 InvalidUtf8 {
18 backtrace: Backtrace,
19 source: str::Utf8Error,
20 },
21 #[snafu(display("invalid auth status: {:x}", auth_status))]
22 AuthStatusInvalid {
23 backtrace: Backtrace,
24 auth_status: u32,
25 },
26 #[snafu(display("unsupported transaction state: {:x}", transaction_state))]
27 InvalidTransactionState {
28 backtrace: Backtrace,
29 transaction_state: u8,
30 },
31 #[snafu(display("unsupported io format: {:x}", io_format))]
32 InvalidIoFormat { backtrace: Backtrace, io_format: u8 },
33 #[snafu(display("unsupported cardinality: {:x}", cardinality))]
34 InvalidCardinality {
35 backtrace: Backtrace,
36 cardinality: u8,
37 },
38 #[snafu(display("unsupported input language: {:x}", input_language))]
39 InvalidInputLanguage {
40 backtrace: Backtrace,
41 input_language: u8,
42 },
43 #[snafu(display("unsupported capability: {:b}", capabilities))]
44 InvalidCapabilities {
45 backtrace: Backtrace,
46 capabilities: u64,
47 },
48 #[snafu(display("unsupported compilation flags: {:b}", compilation_flags))]
49 InvalidCompilationFlags {
50 backtrace: Backtrace,
51 compilation_flags: u64,
52 },
53 #[snafu(display("unsupported dump flags: {:b}", dump_flags))]
54 InvalidDumpFlags {
55 backtrace: Backtrace,
56 dump_flags: u64,
57 },
58 #[snafu(display("unsupported describe aspect: {:x}", aspect))]
59 InvalidAspect { backtrace: Backtrace, aspect: u8 },
60 #[snafu(display("unsupported type descriptor: {:x}", descriptor))]
61 InvalidTypeDescriptor {
62 backtrace: Backtrace,
63 descriptor: u8,
64 },
65 #[snafu(display("invalid uuid: {}", source))]
66 InvalidUuid {
67 backtrace: Backtrace,
68 source: uuid::Error,
69 },
70 #[snafu(display("non-zero reserved bytes received in data"))]
71 NonZeroReservedBytes { backtrace: Backtrace },
72 #[snafu(display("object data size does not match its shape"))]
73 ObjectSizeMismatch { backtrace: Backtrace },
74 #[snafu(display("tuple size does not match its shape"))]
75 TupleSizeMismatch { backtrace: Backtrace },
76 #[snafu(display("unknown negative length marker"))]
77 InvalidMarker { backtrace: Backtrace },
78 #[snafu(display("array shape for the Set codec is invalid"))]
79 InvalidSetShape { backtrace: Backtrace },
80 #[snafu(display("array shape is invalid"))]
81 InvalidArrayShape { backtrace: Backtrace },
82 #[snafu(display("array or set shape is invalid"))]
83 InvalidArrayOrSetShape { backtrace: Backtrace },
84 #[snafu(display("decimal or bigint sign bytes have invalid value"))]
85 BadSign { backtrace: Backtrace },
86 #[snafu(display("invalid boolean value: {val:?}"))]
87 InvalidBool { backtrace: Backtrace, val: u8 },
88 #[snafu(display("invalid optional u32 value"))]
89 InvalidOptionU32 { backtrace: Backtrace },
90 #[snafu(display("datetime is out of range"))]
91 InvalidDate { backtrace: Backtrace },
92 #[snafu(display("json format is invalid"))]
93 InvalidJsonFormat { backtrace: Backtrace },
94 #[snafu(display("enum value returned is not in type descriptor"))]
95 ExtraEnumValue { backtrace: Backtrace },
96 #[snafu(display("too may descriptors ({})", index))]
97 TooManyDescriptors { backtrace: Backtrace, index: usize },
98 #[snafu(display("invalid index in input shape ({})", index))]
99 InvalidIndex { backtrace: Backtrace, index: usize },
100 #[snafu(display("uuid {} not found", uuid))]
101 UuidNotFound {
102 backtrace: Backtrace,
103 uuid: uuid::Uuid,
104 },
105 #[snafu(display("error decoding value"))]
106 DecodeValue {
107 backtrace: Backtrace,
108 source: Box<dyn Error + Send + Sync>,
109 },
110 #[snafu(display("missing required link or property"))]
111 MissingRequiredElement { backtrace: Backtrace },
112 #[snafu(display("invalid format of {annotation} annotation"))]
113 InvalidAnnotationFormat {
114 backtrace: Backtrace,
115 annotation: &'static str,
116 },
117 #[snafu(display("invalid type operation value"))]
118 InvalidTypeOperation { backtrace: Backtrace },
119}
120
121#[derive(Snafu, Debug)]
122#[snafu(visibility(pub(crate)), context(suffix(false)))]
123#[non_exhaustive]
124pub enum EncodeError {
125 #[snafu(display("message doesn't fit 4GiB"))]
126 MessageTooLong { backtrace: Backtrace },
127 #[snafu(display("string is larger than 64KiB"))]
128 StringTooLong { backtrace: Backtrace },
129 #[snafu(display("more than 64Ki extensions"))]
130 TooManyExtensions { backtrace: Backtrace },
131 #[snafu(display("more than 64Ki headers"))]
132 TooManyHeaders { backtrace: Backtrace },
133 #[snafu(display("more than 64Ki params"))]
134 TooManyParams { backtrace: Backtrace },
135 #[snafu(display("more than 64Ki attributes"))]
136 TooManyAttributes { backtrace: Backtrace },
137 #[snafu(display("more than 64Ki authentication methods"))]
138 TooManyMethods { backtrace: Backtrace },
139 #[snafu(display("more than 4Gi elements in the object"))]
140 TooManyElements { backtrace: Backtrace },
141 #[snafu(display("single element larger than 4Gi"))]
142 ElementTooLong { backtrace: Backtrace },
143 #[snafu(display("array or set has more than 4Gi elements"))]
144 ArrayTooLong { backtrace: Backtrace },
145 #[snafu(display("bigint has more than 256Ki digits"))]
146 BigIntTooLong { backtrace: Backtrace },
147 #[snafu(display("decimal has more than 256Ki digits"))]
148 DecimalTooLong { backtrace: Backtrace },
149 #[snafu(display("unknown message types cannot be encoded"))]
150 UnknownMessageCantBeEncoded { backtrace: Backtrace },
151 #[snafu(display(
152 "trying to encode invalid value type {} with codec {}",
153 value_type,
154 codec
155 ))]
156 InvalidValue {
157 backtrace: Backtrace,
158 value_type: &'static str,
159 codec: &'static str,
160 },
161 #[snafu(display("shape of data does not match shape of encoder"))]
162 ObjectShapeMismatch { backtrace: Backtrace },
163 #[snafu(display("datetime value is out of range"))]
164 DatetimeRange { backtrace: Backtrace },
165 #[snafu(display("tuple size doesn't match encoder"))]
166 TupleShapeMismatch { backtrace: Backtrace },
167 #[snafu(display("enum value is not in type descriptor"))]
168 MissingEnumValue { backtrace: Backtrace },
169}
170
171impl From<crate::new_protocol::prelude::ParseError> for DecodeError {
172 fn from(e: crate::new_protocol::prelude::ParseError) -> Self {
173 match e {
174 crate::new_protocol::prelude::ParseError::TooShort => DecodeError::Underflow {
175 backtrace: Backtrace::capture(),
176 },
177 e => DecodeError::DecodeValue {
178 backtrace: Backtrace::capture(),
179 source: Box::new(e),
180 },
181 }
182 }
183}
184
185#[derive(Snafu, Debug)]
186#[snafu(visibility(pub(crate)), context(suffix(false)))]
187#[non_exhaustive]
188pub enum CodecError {
189 #[snafu(display("type position {} is absent", position))]
190 UnexpectedTypePos { backtrace: Backtrace, position: u16 },
191 #[snafu(display("base scalar with uuid {} not found", uuid))]
192 UndefinedBaseScalar {
193 backtrace: Backtrace,
194 uuid: uuid::Uuid,
195 },
196}
197
198pub fn invalid_value(codec: &'static str, value: &Value) -> EncodeError {
199 InvalidValue {
200 codec,
201 value_type: value.kind(),
202 }
203 .build()
204}
205
206pub fn decode_error<E: Error + Send + Sync + 'static>(e: E) -> DecodeError {
207 DecodeValue.into_error(Box::new(e))
208}