From 21608a935f9c8ba71f97bf017e6f44bf800ba77d Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum Date: Tue, 8 Feb 2022 12:18:35 -0500 Subject: [PATCH] Only emit `.try_into()?` when a type is specified The purpose of this transformation is for when the caller specifies `type = "..."`. In that case, we decode into the specified type and then convert into actual type. However, in cases where no type is specified, we have to decode into an unspecified type `T` and then convert into the final type; but the compiler (obviously) cannot determine the type `T`. Therefore, when no `type` is specified, we drop the `.try_into()?` and just attempt to decode into the final type directly. Signed-off-by: Nathaniel McCallum --- der/derive/src/choice/variant.rs | 58 +++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/der/derive/src/choice/variant.rs b/der/derive/src/choice/variant.rs index eeb5d2921..e9841cb99 100644 --- a/der/derive/src/choice/variant.rs +++ b/der/derive/src/choice/variant.rs @@ -47,8 +47,10 @@ impl ChoiceVariant { let tag = self.tag.to_tokens(); let ident = &self.ident; let decoder = self.attrs.decoder(); - quote! { - #tag => Ok(Self::#ident(#decoder.try_into()?)), + + match self.attrs.asn1_type { + Some(..) => quote! { #tag => Ok(Self::#ident(#decoder.try_into()?)), }, + None => quote! { #tag => Ok(Self::#ident(#decoder)), }, } } @@ -103,7 +105,6 @@ mod tests { quote! { ::der::Tag::Utf8String => Ok(Self::ExampleVariant( decoder.decode()? - .try_into()? )), } .to_string() @@ -134,6 +135,55 @@ mod tests { ) } + #[test] + fn utf8string() { + let span = Span::call_site(); + + let variant = ChoiceVariant { + ident: Ident::new("ExampleVariant", span), + attrs: FieldAttrs { + asn1_type: Some(Asn1Type::Utf8String), + ..Default::default() + }, + tag: Tag::Universal(Asn1Type::Utf8String), + }; + + assert_eq!( + variant.to_decode_tokens().to_string(), + quote! { + ::der::Tag::Utf8String => Ok(Self::ExampleVariant( + decoder.utf8_string()? + .try_into()? + )), + } + .to_string() + ); + + assert_eq!( + variant.to_encode_value_tokens().to_string(), + quote! { + Self::ExampleVariant(variant) => ::der::asn1::Utf8String::new(variant)?.encode_value(encoder), + } + .to_string() + ); + + assert_eq!( + variant.to_value_len_tokens().to_string(), + quote! { + Self::ExampleVariant(variant) => variant.value_len(), + } + .to_string() + ); + + assert_eq!( + variant.to_tagged_tokens().to_string(), + quote! { + Self::ExampleVariant(_) => ::der::Tag::Utf8String, + } + .to_string() + ) + } + #[test] fn implicit() { let span = Span::call_site(); @@ -153,7 +203,7 @@ mod tests { ::der::Tag::ContextSpecific { constructed: false, number: ::der::TagNumber::N0, - } => Ok(Self::ImplicitVariant(decoder.decode()?.try_into()?)), + } => Ok(Self::ImplicitVariant(decoder.decode()?)), } .to_string() );