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
/// Derives From<T> implementations for enums whose variants can be expressed by such foreign
/// types.
///
/// For example, this:
/// ```
/// mod serde_json {
/// pub struct Error;
/// }
///
/// enum MyError {
/// SerializationError(serde_json::Error),
/// }
///
/// impl From<serde_json::Error> for MyError {
/// fn from(e: serde_json::Error) -> Self {
/// Self::SerializationError(e)
/// }
/// }
/// ```
/// is condensed using convertable-errors into this:
/// ```
/// # use convertable_errors::convertable_error;
///
/// mod serde_json {
/// # #[derive(PartialEq, Debug, Clone, Copy)]
/// pub struct Error;
/// }
///
/// convertable_error! {
/// # #[derive(PartialEq, Debug)]
/// enum MyError {
/// (SerializationError(serde_json::Error), [(serde_json::Error, Self::SerializationError)])
/// }
/// }
/// #
/// # let err = serde_json::Error;
/// # let my_err: MyError = err.into();
/// # assert_eq!(my_err, MyError::SerializationError(err));
/// ```
///
/// The syntax for defining a convertable enum with convertable-errors is as follows:
/// - Each variant of an enum must be wrapped in a tuple: `enum MyError { (Variant(ForeignType)), (Variant1) }`
/// - The first member of the tuple represents your variant. At the moment, only tuple variants and
/// unit variants are supported bc I'm a lazy fuck.
/// - The second member of the tuple (optional) represents the types that can be converted into
/// that variant: `enum MyError { (Variant(ForeignType), [ ... ]), (Variant1) }`
/// - The members of the convertable types array are each tuples representing the foreign type that
/// can be converted into your enum and the closure or variant to apply the foreign value to:
/// `[(ForeignType, Self::Variant)]`. Internally, this second member can be a closure `|x|
/// Self::Variant(x)`, a unit variant closure `|_| Self::Variant1`, or simply a variant identifier
/// where the value of the foreign type will be stored: `Self::Variant`. In practice, you can use
/// this macro for any enum, but I find it most useful for Error-like enums.
///
/// NOTE: This isn't a serious project, I might have made some mistakes, so feel free to open a PR
/// :) This is just a helpful snippet that I use and felt like sharing.
) => ;
=> ;
// function f(v: ForeignType) -> Self, or simply be type-to-type
=> ;
// A variant of an error without any equivalent foreign types needs no further computation.
=> ;
}