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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::{AccessError, Integer, Panic, ReflectValueType, ValueTypeInfo, VmError, VmErrorKind};
use thiserror::Error;
#[derive(Error, Debug)]
#[error(transparent)]
pub struct ValueError {
kind: Box<ValueErrorKind>,
}
impl ValueError {
pub fn kind(&self) -> &ValueErrorKind {
&self.kind
}
pub fn unsmuggle_vm_error(self) -> Result<VmError, Self> {
match *self.kind {
ValueErrorKind::Panic { reason } => Ok(VmError::from(VmErrorKind::Panic { reason })),
ValueErrorKind::VmError { error } => Ok(error),
kind => Err(Self {
kind: Box::new(kind),
}),
}
}
}
impl<E> From<E> for ValueError
where
ValueErrorKind: From<E>,
{
fn from(err: E) -> Self {
Self {
kind: Box::new(ValueErrorKind::from(err)),
}
}
}
#[derive(Debug, Error)]
pub enum ValueErrorKind {
#[error("panicked `{reason}`")]
Panic {
reason: Panic,
},
#[error("{error}")]
VmError {
#[source]
error: VmError,
},
#[error("failed to access value: {error}")]
AccessError {
#[from]
error: AccessError,
},
#[error("expected `{expected}`, but found `{actual}`")]
Expected {
expected: ValueTypeInfo,
actual: ValueTypeInfo,
},
#[error("expected `Any` type, but found `{actual}`")]
ExpectedAny {
actual: ValueTypeInfo,
},
#[error("failed to convert value `{from}` to integer `{to}`")]
ValueToIntegerCoercionError {
from: Integer,
to: &'static str,
},
#[error("failed to convert integer `{from}` to value `{to}`")]
IntegerToValueCoercionError {
from: Integer,
to: &'static str,
},
#[error("expected a tuple of length `{expected}`, but found one with length `{actual}`")]
ExpectedTupleLength {
actual: usize,
expected: usize,
},
#[error("unexpectedly ran out of items to iterate over")]
IterationError,
}
impl ValueError {
pub fn expected<T>(actual: ValueTypeInfo) -> Self
where
T: ReflectValueType,
{
Self::from(ValueErrorKind::Expected {
expected: T::value_type_info(),
actual,
})
}
pub fn expected_any(actual: ValueTypeInfo) -> Self {
Self::from(ValueErrorKind::ExpectedAny { actual })
}
}