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
//! # enum_repr_conv
//! `enum_repr_conv` is a proc-macro library that provides a convenient attribute-style `repr_conv()` macro
//! to specify a primitive integer type used for representing variants of the annotated fieldless enum as
//! values of this type.
//!
//! ## Description
//! `enum_repr_conv` bridges the gap between C-style enums and fieldless enums in Rust that can be
//! represented using a chosen primitive integer type. It implements conversions from enum variants into
//! integer values (infallible through [`std::convert::From`](https://doc.rust-lang.org/std/convert/trait.From.html))
//! and vice versa (fallible through [`std::convert::TryFrom`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html)).
//! This functionality is provided via `repr_conv(<type>)` macro that mimics the syntax and behavior of
//! [`repr(u*)/repr(i*)`](https://doc.rust-lang.org/nomicon/other-reprs.html#repru-repri) data layout
//! attributes but additionally provides practical and sensible implementations of common conversion traits.
use TokenStream;
use crateparse;
use crateproduce;
use cratetransform;
/// An attribute macro that mimics the syntax and behavior of `repr(u*)`/`repr(i*)` but additionally
/// implements [`std::convert::From`](https://doc.rust-lang.org/std/convert/trait.From.html) and
/// [`std::convert::TryFrom`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html)
/// traits to provide practical and sensible conversions between annontated enum variants and respective
/// integer values.
///
/// [`repr_conv`](macro@repr_conv) accepts a single parameter which is a primitive integer type.
///
/// ```rust
/// # use enum_repr_conv::repr_conv;
/// #[repr_conv(u16)]
/// #[derive(Debug, PartialEq, Eq)]
/// enum SupportedPorts {
/// FTP = 21,
/// SSH, // = 22
/// HTTP = 80,
/// HTTPS = 443,
/// }
///
/// // we can get a u16 for the FTP port easily...
/// assert_eq!(u16::from(SupportedPorts::FTP), 21);
/// //... and for the SSH port too
/// assert_eq!(u16::from(SupportedPorts::SSH), 22);
/// // HTTP port is supported and so conversion succeeds
/// assert_eq!(SupportedPorts::try_from(80).unwrap(), SupportedPorts::HTTP);
/// // Gopher is not supported; who needs it in 2025?!
/// assert!(SupportedPorts::try_from(70).is_err());
/// ```