File tree Expand file tree Collapse file tree
sqlx-macros-core/src/derives Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -281,7 +281,7 @@ pub fn check_struct_attributes(
281281
282282 assert_attribute ! (
283283 !attributes. transparent,
284- "unexpected #[sqlx(transparent)]" ,
284+ "unexpected #[sqlx(transparent)] - only valid for structs with exactly one field " ,
285285 input
286286 ) ;
287287
Original file line number Diff line number Diff line change @@ -34,7 +34,7 @@ pub fn expand_derive_decode(input: &DeriveInput) -> syn::Result<TokenStream> {
3434 ..
3535 } ) => Err ( syn:: Error :: new_spanned (
3636 input,
37- "structs with zero or more than one unnamed field are not supported " ,
37+ "tuple structs may only have a single field" ,
3838 ) ) ,
3939 Data :: Struct ( DataStruct {
4040 fields : Fields :: Unit ,
Original file line number Diff line number Diff line change @@ -35,7 +35,7 @@ pub fn expand_derive_encode(input: &DeriveInput) -> syn::Result<TokenStream> {
3535 ..
3636 } ) => Err ( syn:: Error :: new_spanned (
3737 input,
38- "structs with zero or more than one unnamed field are not supported " ,
38+ "tuple structs may only have a single field" ,
3939 ) ) ,
4040 Data :: Struct ( DataStruct {
4141 fields : Fields :: Unit ,
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result<TokenStream> {
1515 match & input. data {
1616 // Newtype structs:
1717 // struct Foo(i32);
18+ // struct Foo { field: i32 };
1819 Data :: Struct ( DataStruct { fields, .. } )
1920 if fields. len ( ) == 1 && ( matches ! ( fields, Fields :: Unnamed ( _) ) || attrs. transparent ) =>
2021 {
@@ -31,7 +32,7 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result<TokenStream> {
3132 ..
3233 } ) => Err ( syn:: Error :: new_spanned (
3334 input,
34- "structs with zero or more than one unnamed field are not supported " ,
35+ "tuple structs may only have a single field" ,
3536 ) ) ,
3637 Data :: Struct ( DataStruct {
3738 fields : Fields :: Unit ,
Original file line number Diff line number Diff line change @@ -585,4 +585,28 @@ async fn test_uuid_is_compatible_mariadb() -> anyhow::Result<()> {
585585 Ok ( ( ) )
586586}
587587
588+ #[ derive( PartialEq , Eq , Debug , sqlx:: Type ) ]
589+ #[ sqlx( transparent) ]
590+ struct MyIntNamed {
591+ inner : i64 ,
592+ }
593+
594+ struct NamedTransparentRecord {
595+ id : MyIntNamed ,
596+ }
597+
598+ #[ sqlx_macros:: test]
599+ async fn test_named_transparent_struct ( ) -> anyhow:: Result < ( ) > {
600+ let mut conn = new :: < MySql > ( ) . await ?;
601+ let ( mut conn, id) = with_test_row ( & mut conn) . await ?;
602+
603+ let record = sqlx:: query!( "select id as `id: MyIntNamed` from tweet" )
604+ . fetch_one ( & mut * conn)
605+ . await ?;
606+
607+ assert_eq ! ( record. id, MyIntNamed { inner: 1 } ) ;
608+
609+ Ok ( ( ) )
610+ }
611+
588612// we don't emit bind parameter type-checks for MySQL so testing the overrides is redundant
Original file line number Diff line number Diff line change @@ -12,6 +12,13 @@ use std::ops::Bound;
1212#[ sqlx( transparent) ]
1313struct Transparent ( i32 ) ;
1414
15+ // Also possible for single-field named structs
16+ #[ derive( PartialEq , Debug , sqlx:: Type ) ]
17+ #[ sqlx( transparent) ]
18+ struct TransparentNamed {
19+ field : i32 ,
20+ }
21+
1522#[ derive( PartialEq , Debug , sqlx:: Type ) ]
1623// https://github.com/launchbadge/sqlx/issues/2611
1724// Previously, the derive would generate a `PgHasArrayType` impl that errored on an
Original file line number Diff line number Diff line change @@ -660,3 +660,27 @@ async fn pghstore_tests() -> anyhow::Result<()> {
660660
661661 Ok ( ( ) )
662662}
663+
664+ #[ derive( PartialEq , Eq , Debug , sqlx:: Type ) ]
665+ #[ sqlx( transparent) ]
666+ struct MyIntNamed {
667+ inner : i64 ,
668+ }
669+
670+ struct NamedTransparentRecord {
671+ id : MyIntNamed ,
672+ }
673+
674+ #[ sqlx_macros:: test]
675+ async fn test_named_transparent_struct ( ) -> anyhow:: Result < ( ) > {
676+ let mut conn = new :: < Postgres > ( ) . await ?;
677+ let mut conn = with_test_row ( & mut conn) . await ?;
678+
679+ let record = sqlx:: query_as!( NamedTransparentRecord , r#"select id as "id: _" from tweet"# )
680+ . fetch_one ( & mut * conn)
681+ . await ?;
682+
683+ assert_eq ! ( record. id, MyIntNamed { inner: 1 } ) ;
684+
685+ Ok ( ( ) )
686+ }
Original file line number Diff line number Diff line change @@ -333,4 +333,27 @@ async fn test_column_override_exact_nullable() -> anyhow::Result<()> {
333333 Ok ( ( ) )
334334}
335335
336+ #[ derive( PartialEq , Eq , Debug , sqlx:: Type ) ]
337+ #[ sqlx( transparent) ]
338+ struct MyIntNamed {
339+ inner : i64 ,
340+ }
341+
342+ struct NamedTransparentRecord {
343+ id : MyIntNamed ,
344+ }
345+
346+ #[ sqlx_macros:: test]
347+ async fn test_named_transparent_struct ( ) -> anyhow:: Result < ( ) > {
348+ let mut conn = new :: < Sqlite > ( ) . await ?;
349+
350+ let record = sqlx:: query_as!( Record , r#"select id as "id: _" from tweet"# )
351+ . fetch_one ( & mut conn)
352+ . await ?;
353+
354+ assert_eq ! ( record. id, MyIntNamed { inner: 1 } ) ;
355+
356+ Ok ( ( ) )
357+ }
358+
336359// we don't emit bind parameter typechecks for SQLite so testing the overrides is redundant
You can’t perform that action at this time.
0 commit comments