1
1
//! Wrapper around string which is decodable as an enum
2
2
3
+ use std:: marker:: PhantomData ;
4
+
3
5
/// Wrapper around string which is decodable as an enum
4
- pub struct Choice ( pub String ) ;
6
+ ///
7
+ /// Postgres creates a new type for enums with a unique name.
8
+ /// Therefore, `Choice` is generic over a ZST which implements [`ChoiceName`] to provide the postgres name.
9
+ ///
10
+ /// If the generic is not provided, `Choice` won't be usable with postgres
11
+ pub struct Choice < N = ( ) > ( pub String , pub PhantomData < N > ) ;
12
+
13
+ /// Trait to associate a postgres type name with [`Choice`]
14
+ pub trait ChoiceName {
15
+ /// The sql name to use for postgres
16
+ const NAME : & ' static str ;
17
+ }
5
18
6
19
#[ cfg( feature = "sqlx" ) ]
7
20
const _: ( ) = {
@@ -12,53 +25,56 @@ const _: () = {
12
25
#[ cfg( feature = "postgres" ) ]
13
26
const _: ( ) = {
14
27
use sqlx:: Postgres ;
15
- impl Type < Postgres > for Choice {
28
+ impl < N : ChoiceName > Type < Postgres > for Choice < N > {
16
29
fn type_info ( ) -> <Postgres as Database >:: TypeInfo {
17
- < str as Type < Postgres > > :: type_info ( )
30
+ sqlx :: postgres :: PgTypeInfo :: with_name ( N :: NAME )
18
31
}
19
32
fn compatible ( ty : & <Postgres as Database >:: TypeInfo ) -> bool {
20
- <str as Type < Postgres > >:: compatible ( ty)
33
+ * ty == sqlx:: postgres:: PgTypeInfo :: with_name ( N :: NAME )
34
+ || <str as Type < Postgres > >:: compatible ( ty)
21
35
}
22
36
}
23
- impl < ' r > Decode < ' r , Postgres > for Choice {
37
+ impl < ' r , N : ChoiceName > Decode < ' r , Postgres > for Choice < N > {
24
38
fn decode ( value : <Postgres as HasValueRef < ' r > >:: ValueRef ) -> Result < Self , BoxDynError > {
25
- <String as Decode < ' r , Postgres > >:: decode ( value) . map ( Self )
39
+ <String as Decode < ' r , Postgres > >:: decode ( value)
40
+ . map ( |string| Self ( string, PhantomData ) )
26
41
}
27
42
}
28
43
} ;
29
44
30
45
#[ cfg( feature = "mysql" ) ]
31
46
const _: ( ) = {
32
47
use sqlx:: MySql ;
33
- impl Type < MySql > for Choice {
48
+ impl < N > Type < MySql > for Choice < N > {
34
49
fn type_info ( ) -> <MySql as Database >:: TypeInfo {
35
50
<str as Type < MySql > >:: type_info ( )
36
51
}
37
52
fn compatible ( ty : & <MySql as Database >:: TypeInfo ) -> bool {
38
53
<str as Type < MySql > >:: compatible ( ty)
39
54
}
40
55
}
41
- impl < ' r > Decode < ' r , MySql > for Choice {
56
+ impl < ' r , N > Decode < ' r , MySql > for Choice < N > {
42
57
fn decode ( value : <MySql as HasValueRef < ' r > >:: ValueRef ) -> Result < Self , BoxDynError > {
43
- <String as Decode < ' r , MySql > >:: decode ( value) . map ( Self )
58
+ <String as Decode < ' r , MySql > >:: decode ( value) . map ( |string| Self ( string , PhantomData ) )
44
59
}
45
60
}
46
61
} ;
47
62
48
63
#[ cfg( feature = "sqlite" ) ]
49
64
const _: ( ) = {
50
65
use sqlx:: Sqlite ;
51
- impl Type < Sqlite > for Choice {
66
+ impl < N > Type < Sqlite > for Choice < N > {
52
67
fn type_info ( ) -> <Sqlite as Database >:: TypeInfo {
53
68
<str as Type < Sqlite > >:: type_info ( )
54
69
}
55
70
fn compatible ( ty : & <Sqlite as Database >:: TypeInfo ) -> bool {
56
71
<str as Type < Sqlite > >:: compatible ( ty)
57
72
}
58
73
}
59
- impl < ' r > Decode < ' r , Sqlite > for Choice {
74
+ impl < ' r , N > Decode < ' r , Sqlite > for Choice < N > {
60
75
fn decode ( value : <Sqlite as HasValueRef < ' r > >:: ValueRef ) -> Result < Self , BoxDynError > {
61
- <String as Decode < ' r , Sqlite > >:: decode ( value) . map ( Self )
76
+ <String as Decode < ' r , Sqlite > >:: decode ( value)
77
+ . map ( |string| Self ( string, PhantomData ) )
62
78
}
63
79
}
64
80
} ;
0 commit comments