1use alloc::{borrow::Cow, boxed::Box, string::ToString};
4use core::{convert::Infallible, fmt::Display};
5
6#[derive(Debug, thiserror::Error)]
10#[error("{msg}")]
11pub struct ValueError<T> {
12 msg: Cow<'static, str>,
13 value: Box<T>,
14}
15
16impl<T> ValueError<T> {
17 pub fn new(value: T, msg: impl Display) -> Self {
19 Self { msg: Cow::Owned(msg.to_string()), value: Box::new(value) }
20 }
21
22 pub fn new_static(value: T, msg: &'static str) -> Self {
24 Self { msg: Cow::Borrowed(msg), value: Box::new(value) }
25 }
26
27 pub fn convert<U>(self) -> ValueError<U>
29 where
30 U: From<T>,
31 {
32 self.map(U::from)
33 }
34
35 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ValueError<U> {
37 ValueError { msg: self.msg, value: Box::new(f(*self.value)) }
38 }
39
40 pub fn into_value(self) -> T {
42 *self.value
43 }
44
45 pub const fn value(&self) -> &T {
47 &self.value
48 }
49}
50
51#[derive(Debug, thiserror::Error)]
54#[error("Unsupported transaction type: {0}")]
55pub struct UnsupportedTransactionType<TxType: Display>(TxType);
56
57impl<TxType: Display> UnsupportedTransactionType<TxType> {
58 pub const fn new(ty: TxType) -> Self {
60 Self(ty)
61 }
62
63 pub fn into_inner(self) -> TxType {
65 self.0
66 }
67}
68
69impl<TxType: Display> AsRef<TxType> for UnsupportedTransactionType<TxType> {
70 fn as_ref(&self) -> &TxType {
71 &self.0
72 }
73}
74
75impl<TxType: Display> From<Infallible> for UnsupportedTransactionType<TxType> {
76 fn from(value: Infallible) -> Self {
77 match value {}
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use crate::TxType;
85
86 #[test]
87 fn test_unsupported_tx_type_error_displays_itself_and_the_type() {
88 let error = UnsupportedTransactionType::new(TxType::Eip2930);
89 let actual_msg = error.to_string();
90 let expected_msg = "Unsupported transaction type: EIP-2930";
91
92 assert_eq!(actual_msg, expected_msg);
93 }
94}