use std::convert::Infallible;
use axum::extract::FromRequestParts;
use serde::Serialize;
use serde::de::DeserializeOwned;
#[derive(Debug)]
pub struct SessionError(pub String);
impl std::fmt::Display for SessionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "session error: {}", self.0)
}
}
impl std::error::Error for SessionError {}
pub struct Session(pub(crate) crate::auth::tower_sessions::Session);
impl Session {
pub async fn put<T: Serialize>(&self, key: &str, value: T) -> Result<(), SessionError> {
self.0
.insert(key, value)
.await
.map_err(|e| SessionError(e.to_string()))
}
pub async fn get<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>, SessionError> {
self.0
.get(key)
.await
.map_err(|e| SessionError(e.to_string()))
}
pub async fn forget<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>, SessionError> {
self.0
.remove(key)
.await
.map_err(|e| SessionError(e.to_string()))
}
pub async fn regenerate(&self) -> Result<(), SessionError> {
self.0
.cycle_id()
.await
.map_err(|e| SessionError(e.to_string()))
}
pub async fn flush(&self) -> Result<(), SessionError> {
self.0
.flush()
.await
.map_err(|e| SessionError(e.to_string()))
}
pub fn raw(&self) -> &crate::auth::tower_sessions::Session {
&self.0
}
}
impl<S> FromRequestParts<S> for Session
where
S: Send + Sync,
{
type Rejection = Infallible;
async fn from_request_parts(
parts: &mut axum::http::request::Parts,
state: &S,
) -> Result<Self, Self::Rejection> {
let session = crate::auth::tower_sessions::Session::from_request_parts(parts, state)
.await
.map_err(|_| unreachable!("Session extraction is infallible"))?;
Ok(Session(session))
}
}