From e1cef3462fd87b93cf1576803f993c149c8510c9 Mon Sep 17 00:00:00 2001 From: Roland Fredenhagen Date: Fri, 1 Sep 2023 14:45:53 +0200 Subject: [PATCH] fixup! Add `TryFrom` to convert repr to enum cleanup --- impl/src/parsing.rs | 4 ++-- impl/src/try_from.rs | 7 +++++-- tests/try_from.rs | 41 +++++++++++++++++++++++++++++++++-------- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/impl/src/parsing.rs b/impl/src/parsing.rs index 42b66376..dfbd21e0 100644 --- a/impl/src/parsing.rs +++ b/impl/src/parsing.rs @@ -245,8 +245,8 @@ pub fn seq( move |c| { parsers .iter_mut() - .fold(Some((TokenStream::new(), c)), |out, parser| { - let (mut out, mut c) = out?; + .try_fold((TokenStream::new(), c), |out, parser| { + let (mut out, mut c) = out; let (stream, cursor) = parser(c)?; out.extend(stream); c = cursor; diff --git a/impl/src/try_from.rs b/impl/src/try_from.rs index 809863e7..d4b85c19 100644 --- a/impl/src/try_from.rs +++ b/impl/src/try_from.rs @@ -92,7 +92,7 @@ impl<'a> Expansion<'a> { let repr = &self.repr.0; - let mut last_discriminant = quote!(0); + let mut last_discriminant = quote! {0}; let mut inc = 0usize; let (consts, (discriminants, variants)): ( Vec, @@ -115,7 +115,10 @@ impl<'a> Expansion<'a> { let inc = Literal::usize_unsuffixed(inc); fields.is_empty().then_some(( format_ident!("__DISCRIMINANT_{ident}"), - (quote!(#last_discriminant + #inc), quote!(#ident #fields)), + ( + quote! {#last_discriminant + #inc}, + quote! {#ident #fields}, + ), )) }; inc += 1; diff --git a/tests/try_from.rs b/tests/try_from.rs index afe8e341..5e032c88 100644 --- a/tests/try_from.rs +++ b/tests/try_from.rs @@ -7,17 +7,42 @@ use derive_more::TryFrom; #[repr(i16)] enum Enum { A, - Discriminant = 5, - Field(usize), - Empty {}, - FieldWithDiscriminant(u8, i64) = -14, - EmptyTuple(), + B = -21, + C, + D, } #[test] fn test() { assert_eq!(Enum::A, Enum::try_from(0).unwrap()); - assert_eq!(Enum::Discriminant, Enum::try_from(5).unwrap()); - assert_eq!(Enum::Empty {}, Enum::try_from(7).unwrap()); - assert_eq!(Enum::EmptyTuple(), Enum::try_from(-13).unwrap()); + assert_eq!(Enum::B, Enum::try_from(-21).unwrap()); + assert_eq!(Enum::C, Enum::try_from(-20).unwrap()); + assert_eq!(Enum::D, Enum::try_from(-19).unwrap()); + assert!(Enum::try_from(-1).is_err()); +} + +#[rustversion::since(1.66)] +mod discriminants_on_enum_with_fields { + use super::*; + + #[derive(TryFrom, Clone, Copy, Debug, Eq, PartialEq)] + #[repr(i16)] + enum Enum { + A, + Discriminant = 5, + Field(usize), + Empty {}, + FieldWithDiscriminant(u8, i64) = -14, + EmptyTuple(), + } + + #[test] + fn test() { + assert_eq!(Enum::A, Enum::try_from(0).unwrap()); + assert_eq!(Enum::Discriminant, Enum::try_from(5).unwrap()); + assert!(Enum::try_from(6).is_err()); + assert_eq!(Enum::Empty {}, Enum::try_from(7).unwrap()); + assert!(Enum::try_from(-14).is_err()); + assert_eq!(Enum::EmptyTuple(), Enum::try_from(-13).unwrap()); + } }