File tree Expand file tree Collapse file tree 8 files changed +83
-4
lines changed
sqlx-macros-core/src/derives Expand file tree Collapse file tree 8 files changed +83
-4
lines changed Original file line number Diff line number Diff line change @@ -281,7 +281,7 @@ pub fn check_struct_attributes(
281
281
282
282
assert_attribute ! (
283
283
!attributes. transparent,
284
- "unexpected #[sqlx(transparent)]" ,
284
+ "unexpected #[sqlx(transparent)] - only valid for structs with exactly one field " ,
285
285
input
286
286
) ;
287
287
Original file line number Diff line number Diff line change @@ -34,7 +34,7 @@ pub fn expand_derive_decode(input: &DeriveInput) -> syn::Result<TokenStream> {
34
34
..
35
35
} ) => Err ( syn:: Error :: new_spanned (
36
36
input,
37
- "structs with zero or more than one unnamed field are not supported " ,
37
+ "tuple structs may only have a single field" ,
38
38
) ) ,
39
39
Data :: Struct ( DataStruct {
40
40
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> {
35
35
..
36
36
} ) => Err ( syn:: Error :: new_spanned (
37
37
input,
38
- "structs with zero or more than one unnamed field are not supported " ,
38
+ "tuple structs may only have a single field" ,
39
39
) ) ,
40
40
Data :: Struct ( DataStruct {
41
41
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> {
15
15
match & input. data {
16
16
// Newtype structs:
17
17
// struct Foo(i32);
18
+ // struct Foo { field: i32 };
18
19
Data :: Struct ( DataStruct { fields, .. } )
19
20
if fields. len ( ) == 1 && ( matches ! ( fields, Fields :: Unnamed ( _) ) || attrs. transparent ) =>
20
21
{
@@ -31,7 +32,7 @@ pub fn expand_derive_type(input: &DeriveInput) -> syn::Result<TokenStream> {
31
32
..
32
33
} ) => Err ( syn:: Error :: new_spanned (
33
34
input,
34
- "structs with zero or more than one unnamed field are not supported " ,
35
+ "tuple structs may only have a single field" ,
35
36
) ) ,
36
37
Data :: Struct ( DataStruct {
37
38
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<()> {
585
585
Ok ( ( ) )
586
586
}
587
587
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_as!( NamedTransparentRecord , "select id as `id: _` from tweet" )
604
+ . fetch_one ( & mut * conn)
605
+ . await ?;
606
+
607
+ assert_eq ! ( record. id, MyIntNamed { inner: id. 0 } ) ;
608
+
609
+ Ok ( ( ) )
610
+ }
611
+
588
612
// 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;
12
12
#[ sqlx( transparent) ]
13
13
struct Transparent ( i32 ) ;
14
14
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
+
15
22
#[ derive( PartialEq , Debug , sqlx:: Type ) ]
16
23
// https://github.com/launchbadge/sqlx/issues/2611
17
24
// 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<()> {
660
660
661
661
Ok ( ( ) )
662
662
}
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<()> {
333
333
Ok ( ( ) )
334
334
}
335
335
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!( NamedTransparentRecord , 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
+
336
359
// 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