]> git.proxmox.com Git - rustc.git/blame - src/vendor/conv/src/macros.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / vendor / conv / src / macros.rs
CommitLineData
ea8adc8c
XL
1/*!\r
2This module provides convenience macros to help with implementing the conversion traits.\r
3\r
4# `TryFrom!`\r
5\r
6```ignore\r
7macro_rules! TryFrom {\r
8 (($target:ty) $enum:item) => { ... };\r
9}\r
10```\r
11\r
12This macro attempts to derive an implementation of the [`TryFrom`](../trait.TryFrom.html) trait. Specifically, it supports `enum`s consisting entirely of unitary variants, with or without explicit values. The source type can be any integer type which the variants of the enumeration can be explicitly cast to (*i.e.* using `as`).\r
13\r
14If a conversion fails (due to there being no matching variant for the specified integer value `src`), then the conversion returns `Err(Unrepresentable(src))` (see [`Unrepresentable`](../errors/struct.Unrepresentable.html)).\r
15\r
16It is compatible with the [`custom_derive!`](https://crates.io/crates/custom_derive) macro.\r
17\r
18## Example\r
19\r
20Using `custom_derive!`:\r
21\r
22```\r
23#[macro_use] extern crate conv;\r
24#[macro_use] extern crate custom_derive;\r
25\r
26custom_derive! {\r
27 #[derive(Debug, PartialEq, TryFrom(i32))]\r
28 enum Colours {\r
29 Red = 0,\r
30 Green = 5,\r
31 Blue\r
32 }\r
33}\r
34\r
35fn main() {\r
36 use conv::{TryFrom, Unrepresentable};\r
37\r
38 assert_eq!(Colours::try_from(0), Ok(Colours::Red));\r
39 assert_eq!(Colours::try_from(1), Err(Unrepresentable(1)));\r
40 assert_eq!(Colours::try_from(5), Ok(Colours::Green));\r
41 assert_eq!(Colours::try_from(6), Ok(Colours::Blue));\r
42 assert_eq!(Colours::try_from(7), Err(Unrepresentable(7)));\r
43}\r
44```\r
45\r
46The above is equivalent to the following:\r
47\r
48```\r
49#[macro_use] extern crate conv;\r
50\r
51#[derive(Debug, PartialEq)]\r
52enum Colours {\r
53 Red = 0,\r
54 Green = 5,\r
55 Blue\r
56}\r
57\r
58TryFrom! { (i32) enum Colours {\r
59 Red = 0,\r
60 Green = 5,\r
61 Blue\r
62} }\r
63# fn main() {}\r
64```\r
65*/\r
66\r
67/**\r
68See the documentation for the [`macros`](./macros/index.html#tryfrom!) module for details.\r
69*/\r
70#[macro_export]\r
71macro_rules! TryFrom {\r
72 (($prim:ty) $(pub)* enum $name:ident { $($body:tt)* }) => {\r
73 TryFrom! {\r
74 @collect_variants ($name, $prim),\r
75 ($($body)*,) -> ()\r
76 }\r
77 };\r
78\r
79 (\r
80 @collect_variants ($name:ident, $prim:ty),\r
81 ($(,)*) -> ($($var_names:ident,)*)\r
82 ) => {\r
83 impl $crate::TryFrom<$prim> for $name {\r
84 type Err = $crate::errors::Unrepresentable<$prim>;\r
85 fn try_from(src: $prim) -> Result<$name, Self::Err> {\r
86 $(\r
87 if src == $name::$var_names as $prim {\r
88 return Ok($name::$var_names);\r
89 }\r
90 )*\r
91 Err($crate::errors::Unrepresentable(src))\r
92 }\r
93 }\r
94 };\r
95\r
96 (\r
97 @collect_variants $fixed:tt,\r
98 (#[$_attr:meta] $($tail:tt)*) -> $var_names:tt\r
99 ) => {\r
100 TryFrom! {\r
101 @skip_meta $fixed,\r
102 ($($tail)*) -> $var_names\r
103 }\r
104 };\r
105\r
106 (\r
107 @collect_variants $fixed:tt,\r
108 ($var:ident $(= $_val:expr)*, $($tail:tt)*) -> ($($var_names:tt)*)\r
109 ) => {\r
110 TryFrom! {\r
111 @collect_variants $fixed,\r
112 ($($tail)*) -> ($($var_names)* $var,)\r
113 }\r
114 };\r
115\r
116 (\r
117 @collect_variants ($name:ident),\r
118 ($var:ident $_struct:tt, $($tail:tt)*) -> ($($var_names:tt)*)\r
119 ) => {\r
120 const _error: () = concat!(\r
121 "cannot derive TryFrom for ",\r
122 stringify!($name),\r
123 ", due to non-unitary variant ",\r
124 stringify!($var),\r
125 "."\r
126 );\r
127 };\r
128 \r
129 (\r
130 @skip_meta $fixed:tt,\r
131 (#[$_attr:meta] $($tail:tt)*) -> $var_names:tt\r
132 ) => {\r
133 TryFrom! {\r
134 @skip_meta $fixed,\r
135 ($($tail)*) -> $var_names\r
136 }\r
137 };\r
138\r
139 (\r
140 @skip_meta $fixed:tt,\r
141 ($var:ident $($tail:tt)*) -> $var_names:tt\r
142 ) => {\r
143 TryFrom! {\r
144 @collect_variants $fixed,\r
145 ($var $($tail)*) -> $var_names\r
146 }\r
147 };\r
148}\r