1- use crate :: utils:: config:: load_config_sync;
2- use bson:: oid:: ObjectId ;
3- use chrono:: { DateTime , NaiveDateTime , TimeZone } ;
4- use serde:: {
5- de:: { self , Visitor } ,
6- Deserialize , Deserializer , Serialize , Serializer ,
7- } ;
8- use std:: { fmt, str:: FromStr } ;
1+ use crate :: models:: utils:: datetime_or_u64;
2+ use mongodb:: bson:: oid:: ObjectId ;
3+ use serde:: { Deserialize , Serialize } ;
94
105#[ derive( Debug , Serialize , Deserialize , Clone , PartialEq , Eq , Hash ) ]
116#[ serde( rename_all = "kebab-case" ) ]
@@ -24,24 +19,6 @@ pub enum ActivityStatus {
2419 Refused ,
2520}
2621
27- #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq , Eq , Hash ) ]
28- #[ serde( rename_all = "kebab-case" ) ]
29- pub enum ActivityMemberStatus {
30- Effective ,
31- Pending ,
32- Refused ,
33- Rejected ,
34- Draft ,
35- }
36-
37- #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq , Eq , Hash ) ]
38- #[ serde( rename_all = "kebab-case" ) ]
39- pub enum ActivityMode {
40- OnCampus ,
41- OffCampus ,
42- SocialPractice ,
43- }
44-
4522#[ derive( Debug , Serialize , Deserialize , Clone , PartialEq , Eq , Hash ) ]
4623#[ serde( rename_all = "kebab-case" ) ]
4724pub enum SpecialActivityCategory {
@@ -52,81 +29,9 @@ pub enum SpecialActivityCategory {
5229 Other ,
5330}
5431
55- #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq ) ]
56- pub struct ActivityMember {
57- #[ serde(
58- serialize_with = "objectid_to_string" ,
59- deserialize_with = "string_to_objectid"
60- ) ]
61- pub _id : ObjectId , // ObjectId
62- pub status : ActivityMemberStatus ,
63- pub impression : Option < String > ,
64- pub duration : f64 ,
65- pub mode : ActivityMode ,
66- pub history : Option < Vec < ActivityMemberHistory > > ,
67- pub images : Option < Vec < String > > ,
68- }
69-
70- #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq ) ]
71- pub struct ActivityMemberHistory {
72- pub impression : String ,
73- pub duration : f64 ,
74- pub time : String ,
75- #[ serde(
76- serialize_with = "objectid_to_string" ,
77- deserialize_with = "string_to_objectid"
78- ) ]
79- pub actioner : ObjectId , // ObjectId
80- pub action : ActivityMemberStatus ,
81- }
82-
83- pub fn objectid_to_string < S > ( value : & ObjectId , serializer : S ) -> Result < S :: Ok , S :: Error >
84- where
85- S : Serializer ,
86- {
87- serializer. serialize_str ( & value. to_hex ( ) )
88- }
89-
90- pub fn string_to_objectid < ' de , D > ( deserializer : D ) -> Result < ObjectId , D :: Error >
91- where
92- D : Deserializer < ' de > ,
93- {
94- struct ObjectIdOrStringVisitor ;
95-
96- impl < ' de > Visitor < ' de > for ObjectIdOrStringVisitor {
97- type Value = ObjectId ;
98-
99- fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
100- formatter. write_str ( "string or ObjectId" )
101- }
102-
103- fn visit_str < E > ( self , v : & str ) -> Result < Self :: Value , E >
104- where
105- E : de:: Error ,
106- {
107- ObjectId :: from_str ( v) . map_err ( de:: Error :: custom)
108- }
109-
110- fn visit_map < M > ( self , mut map : M ) -> Result < Self :: Value , M :: Error >
111- where
112- M : de:: MapAccess < ' de > ,
113- {
114- if let Some ( ( key, value) ) = map. next_entry :: < String , String > ( ) ? {
115- if key == "$oid" {
116- return self . visit_str ( & value) ;
117- }
118- }
119- Err ( de:: Error :: custom ( "expected a map with a key of '$oid'" ) )
120- }
121- }
122-
123- deserializer. deserialize_any ( ObjectIdOrStringVisitor )
124- }
125-
12632#[ derive( Debug , Serialize , Deserialize , Clone , PartialEq ) ]
12733#[ serde( rename_all = "camelCase" ) ]
12834pub struct Activity {
129- #[ serde( rename = "_id" ) ]
13035 pub _id : ObjectId ,
13136 #[ serde( rename = "type" ) ]
13237 pub activity_type : ActivityType ,
@@ -138,70 +43,9 @@ pub struct Activity {
13843 pub created_at : u64 ,
13944 #[ serde( deserialize_with = "datetime_or_u64" ) ]
14045 pub updated_at : u64 ,
141- #[ serde(
142- serialize_with = "objectid_to_string" ,
143- deserialize_with = "string_to_objectid"
144- ) ]
145- pub creator : ObjectId , // ObjectId
46+ pub creator : ObjectId ,
14647 pub status : ActivityStatus ,
147- pub members : Option < Vec < ActivityMember > > ,
48+ pub members : Vec < ObjectId > ,
14849 pub location : Option < String > ,
14950 pub category : Option < SpecialActivityCategory > ,
15051}
151-
152- pub fn datetime_or_u64 < ' de , D > ( deserializer : D ) -> Result < u64 , D :: Error >
153- where
154- D : Deserializer < ' de > ,
155- {
156- struct DateTimeOrU64 {
157- timezone : chrono:: FixedOffset ,
158- }
159-
160- impl < ' de > Visitor < ' de > for DateTimeOrU64 {
161- type Value = u64 ;
162-
163- fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
164- formatter. write_str ( "a UNIX timestamp as a u64 or a datetime string" )
165- }
166-
167- fn visit_u64 < E > ( self , value : u64 ) -> Result < Self :: Value , E >
168- where
169- E : de:: Error ,
170- {
171- Ok ( value)
172- }
173-
174- fn visit_i64 < E > ( self , value : i64 ) -> Result < Self :: Value , E >
175- where
176- E : de:: Error ,
177- {
178- Ok ( value as u64 )
179- }
180-
181- fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
182- where
183- E : de:: Error ,
184- {
185- if let Ok ( dt) = DateTime :: parse_from_rfc3339 ( value) {
186- Ok ( dt. timestamp ( ) as u64 )
187- } else if let Ok ( naive_dt) = NaiveDateTime :: parse_from_str ( value, "%Y-%m-%d %H:%M:%S" ) {
188- let dt = self
189- . timezone
190- . from_local_datetime ( & naive_dt)
191- . single ( )
192- . ok_or_else ( || {
193- de:: Error :: custom ( "Invalid datetime for the specified timezone" )
194- } ) ?;
195- Ok ( dt. timestamp ( ) as u64 )
196- } else {
197- Err ( de:: Error :: custom ( "Invalid datetime format" ) )
198- }
199- }
200- }
201-
202- let config = load_config_sync ( ) . unwrap ( ) ;
203- let offset: i32 = config. timezone . parse ( ) . unwrap ( ) ;
204- let timezone = chrono:: FixedOffset :: east_opt ( offset * 3600 ) . unwrap ( ) ;
205- let visitor = DateTimeOrU64 { timezone } ;
206- deserializer. deserialize_any ( visitor)
207- }
0 commit comments