Skip to content

Commit eaa0b7a

Browse files
committed
initial commit
0 parents  commit eaa0b7a

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "async-redis-session"
3+
version = "0.1.0"
4+
authors = ["Jacob Rothstein <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
redis = { version = "0.16.0", features = ["aio"] }
9+
async-session = "1.0.2"
10+
serde = "1.0.114"
11+
serde_json = "1.0.56"
12+
async-trait = "0.1.36"
13+
http-types = "2.2.1"
14+
15+
[patch.crates-io]
16+
async-session = { path = "../async-session" }#git = "https://github.com/jbr/async-session", branch = "tide" }

src/lib.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
use async_session::{uuid::Uuid, Session, SessionStore};
2+
use http_types::cookies::Cookie;
3+
use redis::AsyncCommands;
4+
use redis::{Client, RedisError};
5+
use std::time::Duration;
6+
7+
#[derive(Clone)]
8+
pub struct RedisSessionStore {
9+
client: Client,
10+
ttl: Duration,
11+
}
12+
13+
impl RedisSessionStore {
14+
pub fn from_client(client: Client) -> Self {
15+
Self {
16+
client,
17+
ttl: Duration::from_secs(86400),
18+
}
19+
}
20+
21+
pub fn new(connection_info: impl redis::IntoConnectionInfo) -> Result<Self, RedisError> {
22+
Ok(Self::from_client(Client::open(connection_info)?))
23+
}
24+
}
25+
26+
#[async_trait::async_trait]
27+
impl SessionStore for RedisSessionStore {
28+
type Error = Error;
29+
30+
async fn load_session(&self, cookie: Cookie<'_>) -> Result<Option<Session>, Self::Error> {
31+
let mut connection = self.client.get_async_std_connection().await?;
32+
let value: String = connection.get(cookie.value()).await?;
33+
let session: Session = serde_json::from_str(&value)?;
34+
Ok(Some(session))
35+
}
36+
37+
async fn store_session(&self, session: Session) -> Result<String, Self::Error> {
38+
let id = session.id();
39+
let mut connection = self.client.get_async_std_connection().await?;
40+
let string = serde_json::to_string(&session)?;
41+
42+
let _: () = connection
43+
.set_ex(&id, string, self.ttl.as_secs() as usize)
44+
.await?;
45+
46+
Ok(id)
47+
}
48+
49+
async fn create_session(&self) -> Result<Session, Self::Error> {
50+
let sess = Session::new();
51+
sess.insert("id".to_string(), Uuid::new_v4().to_string());
52+
Ok(sess)
53+
}
54+
}
55+
56+
#[derive(Debug)]
57+
pub enum Error {
58+
RedisError(RedisError),
59+
SerdeError(serde_json::Error),
60+
}
61+
62+
impl std::fmt::Display for Error {
63+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64+
match self {
65+
Error::RedisError(e) => e.fmt(f),
66+
Error::SerdeError(e) => e.fmt(f),
67+
}
68+
}
69+
}
70+
71+
impl From<serde_json::Error> for Error {
72+
fn from(e: serde_json::Error) -> Self {
73+
Self::SerdeError(e)
74+
}
75+
}
76+
77+
impl From<RedisError> for Error {
78+
fn from(e: RedisError) -> Self {
79+
Self::RedisError(e)
80+
}
81+
}
82+
83+
impl std::error::Error for Error {}

0 commit comments

Comments
 (0)