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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
# What `#[derive(TryInto)]` generates
This derive allows you to convert enum variants into their corresponding
variant types.
One thing to note is that this derive doesn't actually generate an
implementation for the `TryInto` trait.
Instead it derives `TryFrom` for each variant in the enum and thus has an
indirect implementation of `TryInto` as recommended by the
[docs](https://doc.rust-lang.org/core/convert/trait.TryInto.html).
By using `#[try_into(owned, ref, ref_mut)]` it's possible to derive a `TryInto`
implementation for reference types as well.
You can pick any combination of `owned`, `ref` and `ref_mut`.
If that's not provided the default is `#[try_into(owned)]`.
With `#[try_into]` or `#[try_into(ignore)]` it's possible to indicate which
variants you want to derive `TryInto` for.
## Example usage
```rust
# use derive_more::TryInto;
#
#[derive(TryInto, Clone, Debug)]
#[try_into(owned, ref, ref_mut)]
enum MixedData {
Int(u32),
String(String),
}
let mixed_string = MixedData::String("foo".to_string());
let mixed_int1 = MixedData::Int(123);
let mixed_int2 = mixed_int1.clone();
let mut mixed_int3 = mixed_int1.clone();
assert_eq!(123u32, mixed_int1.try_into().unwrap());
let int_ref : &u32 = (&mixed_int2).try_into().unwrap();
assert_eq!(&123u32, int_ref);
let int_ref_mut : &mut u32 = (&mut mixed_int3).try_into().unwrap();
assert_eq!(&mut 123u32, int_ref_mut);
assert_eq!("foo".to_string(), String::try_from(mixed_string.clone()).unwrap());
assert!(u32::try_from(mixed_string).is_err());
```
## Structs
Deriving `TryInto` for structs is not supported because there is no failing
mode. Use `#[derive(Into)]` instead. `TryInto` will automatically get a
blanket implementation through `TryFrom`, automatically derived from `From`,
which `#[derive(Into)]` produces.
## Enums
When deriving `TryInto` for an enum, each enum variant gets its own
`TryFrom` implementation.
For instance, when deriving `TryInto` for an enum link this:
```rust
# use derive_more::TryInto;
#
#[derive(TryInto)]
enum MixedInts {
SmallInt(i32),
BigInt(i64),
TwoSmallInts(i32, i32),
NamedSmallInts { x: i64, y: i64 },
UnsignedOne(u32),
UnsignedTwo(u32),
#[try_into(ignore)]
NotImportant,
}
```
Code like this will be generated:
```rust
# enum MixedInts {
# SmallInt(i32),
# BigInt(i64),
# TwoSmallInts(i32, i32),
# NamedSmallInts { x: i64, y: i64 },
# UnsignedOne(u32),
# UnsignedTwo(u32),
# }
impl derive_more::TryFrom<MixedInts> for (i32) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
match value {
MixedInts::SmallInt(__0) => Ok(__0),
_ => Err("Only SmallInt can be converted to i32"),
}
}
}
impl derive_more::TryFrom<MixedInts> for (i64) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
match value {
MixedInts::BigInt(__0) => Ok(__0),
_ => Err("Only BigInt can be converted to i64"),
}
}
}
impl derive_more::TryFrom<MixedInts> for (i32, i32) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
match value {
MixedInts::TwoSmallInts(__0, __1) => Ok((__0, __1)),
_ => Err("Only TwoSmallInts can be converted to (i32, i32)"),
}
}
}
impl derive_more::TryFrom<MixedInts> for (i64, i64) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
match value {
MixedInts::NamedSmallInts { x: __0, y: __1 } => Ok((__0, __1)),
_ => Err("Only NamedSmallInts can be converted to (i64, i64)"),
}
}
}
impl derive_more::TryFrom<MixedInts> for (u32) {
type Error = &'static str;
fn try_from(value: MixedInts) -> Result<Self, Self::Error> {
match value {
MixedInts::UnsignedOne(__0) | MixedInts::UnsignedTwo(__0) => Ok(__0),
_ => Err("Only UnsignedOne, UnsignedTwo can be converted to u32"),
}
}
}
```
When deriving `TryInto` for an enum with Unit variants like this:
```rust
# use derive_more::TryInto;
#
#[derive(TryInto)]
enum EnumWithUnit {
SmallInt(i32),
Unit,
}
```
Code like this will be generated:
```rust
# enum EnumWithUnit {
# SmallInt(i32),
# Unit,
# }
impl derive_more::TryFrom<EnumWithUnit> for (i32) {
type Error = &'static str;
fn try_from(value: EnumWithUnit) -> Result<Self, Self::Error> {
match value {
EnumWithUnit::SmallInt(__0) => Ok(__0),
_ => Err("Only SmallInt can be converted to i32"),
}
}
}
impl derive_more::TryFrom<EnumWithUnit> for () {
type Error = &'static str;
fn try_from(value: EnumWithUnit) -> Result<Self, Self::Error> {
match value {
EnumWithUnit::Unit => Ok(()),
_ => Err("Only Unit can be converted to ()"),
}
}
}
```
|