// Copyright (c) 2015 macro-attr contributors. // Copyright (c) 2020 Warlock . // // Licensed under the MIT license (see LICENSE or ) or the Apache License, Version 2.0 (see LICENSE of // ), at your option. All // files in the project carrying such notice may not be copied, modified, // or distributed except according to those terms. #![deny(warnings)] use macro_attr_2018::macro_attr; macro_rules! TryFrom { (($prim:ty) $(pub)* enum $name:ident { $($body:tt)* }) => { TryFrom! { @collect_variants ($name, $prim), ($($body)*,) -> () } }; ( @collect_variants ($name:ident, $prim:ty), ($(,)*) -> ($($var_names:ident,)*) ) => { impl TryFrom<$prim> for $name { type Error = $prim; fn try_from(src: $prim) -> Result<$name, $prim> { $( if src == $name::$var_names as $prim { return Ok($name::$var_names); } )* Err(src) } } }; ( @collect_variants $fixed:tt, ($var:ident $(= $_val:expr)*, $($tail:tt)*) -> ($($var_names:tt)*) ) => { TryFrom! { @collect_variants $fixed, ($($tail)*) -> ($($var_names)* $var,) } }; } macro_attr! { #[derive(Debug, PartialEq, TryFrom!(u8))] enum Get { Up, Down, AllAround } } #[test] fn test_try_from() { assert_eq!(Get::try_from(0u8), Ok(Get::Up)); assert_eq!(Get::try_from(1u8), Ok(Get::Down)); assert_eq!(Get::try_from(2u8), Ok(Get::AllAround)); assert_eq!(Get::try_from(3u8), Err(3u8)); }