@@ -13,6 +13,7 @@ pub struct Email {
1313    pub  user_id :  i32 , 
1414    pub  email :  String , 
1515    pub  verified :  bool , 
16+     pub  primary :  bool , 
1617    #[ diesel( deserialize_as = String ,  serialize_as = String ) ]  
1718    pub  token :  SecretString , 
1819} 
@@ -24,46 +25,65 @@ pub struct NewEmail<'a> {
2425    pub  email :  & ' a  str , 
2526    #[ builder( default  = false ) ]  
2627    pub  verified :  bool , 
28+     #[ builder( default  = false ) ]  
29+     pub  primary :  bool , 
2730} 
2831
2932impl  NewEmail < ' _ >  { 
30-     pub  async  fn  insert ( & self ,  conn :  & mut  AsyncPgConnection )  -> QueryResult < ( ) >  { 
33+     pub  async  fn  insert ( & self ,  conn :  & mut  AsyncPgConnection )  -> QueryResult < Email >  { 
3134        diesel:: insert_into ( emails:: table) 
3235            . values ( self ) 
33-             . execute ( conn) 
34-             . await ?; 
35- 
36-         Ok ( ( ) ) 
36+             . returning ( Email :: as_returning ( ) ) 
37+             . get_result ( conn) 
38+             . await 
3739    } 
3840
39-     /// Inserts the email into the database and returns the confirmation token,  
40- /// or does nothing if  it already exists  and returns  `None`. 
41- pub  async  fn  insert_if_missing ( 
41+     /// Inserts the email into the database and returns it, unless  the user already has a  
42+ /// primary email, in which case  it will do nothing  and return  `None`. 
43+ pub  async  fn  insert_primary_if_missing ( 
4244        & self , 
4345        conn :  & mut  AsyncPgConnection , 
44-     )  -> QueryResult < Option < SecretString > >  { 
45-         diesel:: insert_into ( emails:: table) 
46-             . values ( self ) 
47-             . on_conflict_do_nothing ( ) 
48-             . returning ( emails:: token) 
49-             . get_result :: < String > ( conn) 
50-             . await 
51-             . map ( Into :: into) 
52-             . optional ( ) 
46+     )  -> QueryResult < Option < Email > >  { 
47+         // Check if the user already has a primary email 
48+         let  primary_count = emails:: table
49+             . filter ( emails:: user_id. eq ( self . user_id ) ) 
50+             . filter ( emails:: primary. eq ( true ) ) 
51+             . count ( ) 
52+             . get_result :: < i64 > ( conn) 
53+             . await ?; 
54+ 
55+         if  primary_count > 0  { 
56+             return  Ok ( None ) ;  // User already has a primary email 
57+         } 
58+ 
59+         self . insert ( conn) . await . map ( Some ) 
5360    } 
5461
55-     pub  async  fn  insert_or_update ( 
62+     // Inserts an email for the user, replacing the primary email if it exists. 
63+     pub  async  fn  insert_or_update_primary ( 
5664        & self , 
5765        conn :  & mut  AsyncPgConnection , 
58-     )  -> QueryResult < SecretString >  { 
59-         diesel:: insert_into ( emails:: table) 
60-             . values ( self ) 
61-             . on_conflict ( emails:: user_id) 
62-             . do_update ( ) 
63-             . set ( self ) 
64-             . returning ( emails:: token) 
65-             . get_result :: < String > ( conn) 
66-             . await 
67-             . map ( Into :: into) 
66+     )  -> QueryResult < Email >  { 
67+         // Attempt to update an existing primary email 
68+         let  updated_email = diesel:: update ( 
69+             emails:: table
70+                 . filter ( emails:: user_id. eq ( self . user_id ) ) 
71+                 . filter ( emails:: primary. eq ( true ) ) , 
72+         ) 
73+         . set ( ( 
74+             emails:: email. eq ( self . email ) , 
75+             emails:: verified. eq ( self . verified ) , 
76+         ) ) 
77+         . returning ( Email :: as_returning ( ) ) 
78+         . get_result ( conn) 
79+         . await 
80+         . optional ( ) ?; 
81+ 
82+         if  let  Some ( email)  = updated_email { 
83+             return  Ok ( email) ; 
84+         }  else  { 
85+             // Otherwise, insert a new email 
86+             self . insert ( conn) . await 
87+         } 
6888    } 
6989} 
0 commit comments