1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-23 15:51:06 +01:00

feat(session): use real async traits (#365)

This commit is contained in:
Rob Ede 2024-01-04 04:10:46 +00:00 committed by GitHub
parent 77b8dcdf59
commit e2bf504055
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 36 additions and 28 deletions

View File

@ -22,7 +22,7 @@ jobs:
target: target:
- { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu } - { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu }
version: version:
- { name: msrv, version: 1.68.0 } - { name: msrv, version: 1.75.0 }
- { name: stable, version: stable } - { name: stable, version: stable }
name: ${{ matrix.target.name }} / ${{ matrix.version.name }} name: ${{ matrix.target.name }} / ${{ matrix.version.name }}
@ -83,7 +83,7 @@ jobs:
- { name: macOS, os: macos-latest, triple: x86_64-apple-darwin } - { name: macOS, os: macos-latest, triple: x86_64-apple-darwin }
- { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc } - { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc }
version: version:
- { name: msrv, version: 1.68.0 } - { name: msrv, version: 1.75.0 }
- { name: stable, version: stable } - { name: stable, version: stable }
name: ${{ matrix.target.name }} / ${{ matrix.version.name }} name: ${{ matrix.target.name }} / ${{ matrix.version.name }}

View File

@ -13,9 +13,10 @@ members = [
] ]
[workspace.package] [workspace.package]
homepage = "https://actix.rs"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
edition = "2021" edition = "2021"
rust-version = "1.68" rust-version = "1.75"
[patch.crates-io] [patch.crates-io]
actix-cors = { path = "./actix-cors" } actix-cors = { path = "./actix-cors" }

View File

@ -3,6 +3,7 @@
## Unreleased ## Unreleased
- `Cors` is now marked `#[must_use]`. - `Cors` is now marked `#[must_use]`.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.6.5 ## 0.6.5

View File

@ -2,6 +2,8 @@
## Unreleased ## Unreleased
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.6.0 ## 0.6.0
- Add `error` module. - Add `error` module.

View File

@ -2,6 +2,8 @@
## Unreleased ## Unreleased
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.10.0 ## 0.10.0
- Updated `prost` dependency to `0.12`. - Updated `prost` dependency to `0.12`.

View File

@ -2,6 +2,8 @@
## Unreleased ## Unreleased
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.13.0 ## 0.13.0
- Update `redis-async` dependency to `0.16`. - Update `redis-async` dependency to `0.16`.

View File

@ -2,6 +2,9 @@
## Unreleased ## Unreleased
- Remove use of `async-trait` on `SessionStore` trait.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.8.0 ## 0.8.0
- Set secure attribute when adding a session removal cookie. - Set secure attribute when adding a session removal cookie.

View File

@ -7,8 +7,8 @@ authors = [
] ]
description = "Session management for Actix Web" description = "Session management for Actix Web"
keywords = ["http", "web", "framework", "async", "session"] keywords = ["http", "web", "framework", "async", "session"]
homepage = "https://actix.rs" repository = "https://github.com/actix/actix-extras/tree/master/actix-session"
repository = "https://github.com/actix/actix-extras.git" homepage.workspace = true
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true
rust-version.workspace = true rust-version.workspace = true
@ -30,7 +30,6 @@ actix-utils = "3"
actix-web = { version = "4", default-features = false, features = ["cookies", "secure-cookies"] } actix-web = { version = "4", default-features = false, features = ["cookies", "secure-cookies"] }
anyhow = "1" anyhow = "1"
async-trait = "0.1"
derive_more = "0.99.7" derive_more = "0.99.7"
rand = { version = "0.8", optional = true } rand = { version = "0.8", optional = true }
serde = { version = "1" } serde = { version = "1" }

View File

@ -49,7 +49,6 @@ use crate::storage::{
#[non_exhaustive] #[non_exhaustive]
pub struct CookieSessionStore; pub struct CookieSessionStore;
#[async_trait::async_trait(?Send)]
impl SessionStore for CookieSessionStore { impl SessionStore for CookieSessionStore {
async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> { async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> {
serde_json::from_str(session_key.as_ref()) serde_json::from_str(session_key.as_ref())
@ -67,10 +66,10 @@ impl SessionStore for CookieSessionStore {
.map_err(anyhow::Error::new) .map_err(anyhow::Error::new)
.map_err(SaveError::Serialization)?; .map_err(SaveError::Serialization)?;
Ok(session_key session_key
.try_into() .try_into()
.map_err(Into::into) .map_err(Into::into)
.map_err(SaveError::Other)?) .map_err(SaveError::Other)
} }
async fn update( async fn update(

View File

@ -1,4 +1,4 @@
use std::collections::HashMap; use std::{collections::HashMap, future::Future};
use actix_web::cookie::time::Duration; use actix_web::cookie::time::Duration;
use derive_more::Display; use derive_more::Display;
@ -10,41 +10,39 @@ pub(crate) type SessionState = HashMap<String, String>;
/// The interface to retrieve and save the current session data from/to the chosen storage backend. /// The interface to retrieve and save the current session data from/to the chosen storage backend.
/// ///
/// You can provide your own custom session store backend by implementing this trait. /// You can provide your own custom session store backend by implementing this trait.
///
/// [`async-trait`](https://docs.rs/async-trait) is used for this trait's definition. Therefore, it
/// is required for implementations, too. In particular, we use the send-optional variant:
/// `#[async_trait(?Send)]`.
#[async_trait::async_trait(?Send)]
pub trait SessionStore { pub trait SessionStore {
/// Loads the session state associated to a session key. /// Loads the session state associated to a session key.
async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError>; fn load(
&self,
session_key: &SessionKey,
) -> impl Future<Output = Result<Option<SessionState>, LoadError>>;
/// Persist the session state for a newly created session. /// Persist the session state for a newly created session.
/// ///
/// Returns the corresponding session key. /// Returns the corresponding session key.
async fn save( fn save(
&self, &self,
session_state: SessionState, session_state: SessionState,
ttl: &Duration, ttl: &Duration,
) -> Result<SessionKey, SaveError>; ) -> impl Future<Output = Result<SessionKey, SaveError>>;
/// Updates the session state associated to a pre-existing session key. /// Updates the session state associated to a pre-existing session key.
async fn update( fn update(
&self, &self,
session_key: SessionKey, session_key: SessionKey,
session_state: SessionState, session_state: SessionState,
ttl: &Duration, ttl: &Duration,
) -> Result<SessionKey, UpdateError>; ) -> impl Future<Output = Result<SessionKey, UpdateError>>;
/// Updates the TTL of the session state associated to a pre-existing session key. /// Updates the TTL of the session state associated to a pre-existing session key.
async fn update_ttl( fn update_ttl(
&self, &self,
session_key: &SessionKey, session_key: &SessionKey,
ttl: &Duration, ttl: &Duration,
) -> Result<(), anyhow::Error>; ) -> impl Future<Output = Result<(), anyhow::Error>>;
/// Deletes a session from the store. /// Deletes a session from the store.
async fn delete(&self, session_key: &SessionKey) -> Result<(), anyhow::Error>; fn delete(&self, session_key: &SessionKey) -> impl Future<Output = Result<(), anyhow::Error>>;
} }
// We cannot derive the `Error` implementation using `derive_more` for our custom errors: // We cannot derive the `Error` implementation using `derive_more` for our custom errors:

View File

@ -118,7 +118,6 @@ impl RedisActorSessionStoreBuilder {
} }
} }
#[async_trait::async_trait(?Send)]
impl SessionStore for RedisActorSessionStore { impl SessionStore for RedisActorSessionStore {
async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> { async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> {
let cache_key = (self.configuration.cache_keygen)(session_key.as_ref()); let cache_key = (self.configuration.cache_keygen)(session_key.as_ref());

View File

@ -132,7 +132,6 @@ impl RedisSessionStoreBuilder {
} }
} }
#[async_trait::async_trait(?Send)]
impl SessionStore for RedisSessionStore { impl SessionStore for RedisSessionStore {
async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> { async fn load(&self, session_key: &SessionKey) -> Result<Option<SessionState>, LoadError> {
let cache_key = (self.configuration.cache_keygen)(session_key.as_ref()); let cache_key = (self.configuration.cache_keygen)(session_key.as_ref());

View File

@ -44,7 +44,6 @@ async fn errors_are_opaque() {
struct MockStore; struct MockStore;
#[async_trait::async_trait(?Send)]
impl SessionStore for MockStore { impl SessionStore for MockStore {
async fn load( async fn load(
&self, &self,

View File

@ -2,6 +2,8 @@
## Unreleased ## Unreleased
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.7.1 ## 0.7.1
- Fix doc examples. - Fix doc examples.

View File

@ -2,6 +2,8 @@
## Unreleased ## Unreleased
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.8.1 ## 0.8.1
- Implement `From<Basic>` for `BasicAuth`. - Implement `From<Basic>` for `BasicAuth`.

View File

@ -10,8 +10,8 @@
## Documentation & Resources ## Documentation & Resources
- [API Documentation](https://docs.rs/actix-ws) - [API Documentation](https://docs.rs/actix-ws)
- [Example Projects](https://github.com/actix/examples/tree/master/websockets) - [Example Chat Project](https://github.com/actix/examples/tree/master/websockets/chat-actorless)
- Minimum Supported Rust Version (MSRV): 1.68 - Minimum Supported Rust Version (MSRV): 1.75
## Usage ## Usage