1
1
use std:: {
2
2
cell:: { Ref , RefCell } ,
3
- collections:: HashMap ,
4
3
error:: Error as StdError ,
5
4
mem,
6
5
rc:: Rc ,
@@ -16,6 +15,9 @@ use actix_web::{
16
15
use anyhow:: Context ;
17
16
use derive_more:: derive:: { Display , From } ;
18
17
use serde:: { de:: DeserializeOwned , Serialize } ;
18
+ use serde_json:: Value ;
19
+
20
+ use crate :: storage:: SessionState ;
19
21
20
22
/// The primary interface to access and modify session state.
21
23
///
@@ -70,7 +72,7 @@ pub enum SessionStatus {
70
72
71
73
#[ derive( Default ) ]
72
74
struct SessionInner {
73
- state : HashMap < String , String > ,
75
+ state : SessionState ,
74
76
status : SessionStatus ,
75
77
}
76
78
@@ -79,9 +81,9 @@ impl Session {
79
81
///
80
82
/// It returns an error if it fails to deserialize as `T` the JSON value associated with `key`.
81
83
pub fn get < T : DeserializeOwned > ( & self , key : & str ) -> Result < Option < T > , SessionGetError > {
82
- if let Some ( val_str ) = self . 0 . borrow ( ) . state . get ( key) {
84
+ if let Some ( value ) = self . 0 . borrow ( ) . state . get ( key) {
83
85
Ok ( Some (
84
- serde_json:: from_str ( val_str )
86
+ serde_json:: from_value ( value . to_owned ( ) )
85
87
. with_context ( || {
86
88
format ! (
87
89
"Failed to deserialize the JSON-encoded session data attached to key \
@@ -100,7 +102,7 @@ impl Session {
100
102
/// Get all raw key-value data from the session.
101
103
///
102
104
/// Note that values are JSON encoded.
103
- pub fn entries ( & self ) -> Ref < ' _ , HashMap < String , String > > {
105
+ pub fn entries ( & self ) -> Ref < ' _ , SessionState > {
104
106
Ref :: map ( self . 0 . borrow ( ) , |inner| & inner. state )
105
107
}
106
108
@@ -139,7 +141,7 @@ impl Session {
139
141
} )
140
142
. map_err ( SessionInsertError ) ?;
141
143
142
- inner. state . insert ( key, val) ;
144
+ inner. state . insert ( key, Value :: String ( val) ) ;
143
145
}
144
146
145
147
Ok ( ( ) )
@@ -148,7 +150,7 @@ impl Session {
148
150
/// Remove value from the session.
149
151
///
150
152
/// If present, the JSON encoded value is returned.
151
- pub fn remove ( & self , key : & str ) -> Option < String > {
153
+ pub fn remove ( & self , key : & str ) -> Option < Value > {
152
154
let mut inner = self . 0 . borrow_mut ( ) ;
153
155
154
156
if inner. status != SessionStatus :: Purged {
@@ -165,9 +167,9 @@ impl Session {
165
167
///
166
168
/// Returns `None` if key was not present in session. Returns `T` if deserialization succeeds,
167
169
/// otherwise returns un-deserialized JSON string.
168
- pub fn remove_as < T : DeserializeOwned > ( & self , key : & str ) -> Option < Result < T , String > > {
170
+ pub fn remove_as < T : DeserializeOwned > ( & self , key : & str ) -> Option < Result < T , Value > > {
169
171
self . remove ( key)
170
- . map ( |val_str | match serde_json:: from_str ( & val_str ) {
172
+ . map ( |val | match serde_json:: from_value ( val . clone ( ) ) {
171
173
Ok ( val) => Ok ( val) ,
172
174
Err ( _err) => {
173
175
tracing:: debug!(
@@ -176,7 +178,7 @@ impl Session {
176
178
std:: any:: type_name:: <T >( )
177
179
) ;
178
180
179
- Err ( val_str )
181
+ Err ( val )
180
182
}
181
183
} )
182
184
}
@@ -216,11 +218,13 @@ impl Session {
216
218
#[ allow( clippy:: needless_pass_by_ref_mut) ]
217
219
pub ( crate ) fn set_session (
218
220
req : & mut ServiceRequest ,
219
- data : impl IntoIterator < Item = ( String , String ) > ,
221
+ data : impl IntoIterator < Item = ( String , impl Into < Value > ) > ,
220
222
) {
221
223
let session = Session :: get_session ( & mut req. extensions_mut ( ) ) ;
222
224
let mut inner = session. 0 . borrow_mut ( ) ;
223
- inner. state . extend ( data) ;
225
+ inner
226
+ . state
227
+ . extend ( data. into_iter ( ) . map ( |( k, v) | ( k, v. into ( ) ) ) ) ;
224
228
}
225
229
226
230
/// Returns session status and iterator of key-value pairs of changes.
@@ -229,9 +233,7 @@ impl Session {
229
233
/// typemap, leaving behind a new empty map. It should only be used when the session is being
230
234
/// finalised (i.e. in `SessionMiddleware`).
231
235
#[ allow( clippy:: needless_pass_by_ref_mut) ]
232
- pub ( crate ) fn get_changes < B > (
233
- res : & mut ServiceResponse < B > ,
234
- ) -> ( SessionStatus , HashMap < String , String > ) {
236
+ pub ( crate ) fn get_changes < B > ( res : & mut ServiceResponse < B > ) -> ( SessionStatus , SessionState ) {
235
237
if let Some ( s_impl) = res
236
238
. request ( )
237
239
. extensions ( )
@@ -240,7 +242,7 @@ impl Session {
240
242
let state = mem:: take ( & mut s_impl. borrow_mut ( ) . state ) ;
241
243
( s_impl. borrow ( ) . status . clone ( ) , state)
242
244
} else {
243
- ( SessionStatus :: Unchanged , HashMap :: new ( ) )
245
+ ( SessionStatus :: Unchanged , SessionState :: new ( ) )
244
246
}
245
247
}
246
248
0 commit comments