tide-flash 0.1.0

Tide (http-rs/tide) Flash Messages Middleware
Documentation
use http_types::cookies::SameSite;
use tide::http::cookies::Cookie;

use crate::{Flash, FlashMessage, FlashStore};

#[derive(Debug)]
pub struct CookieConfig {
    pub max_age: time::Duration,
    pub site: SameSite,
    pub http_only: bool,
    pub path: String,
}

impl Default for CookieConfig {
    fn default() -> Self {
        Self {
            max_age: time::Duration::seconds(60),
            site: SameSite::Lax,
            http_only: true,
            path: String::from("/"),
        }
    }
}

#[derive(Debug)]
pub struct CookieStore {
    pub config: CookieConfig,
}

impl Default for CookieStore {
    fn default() -> Self {
        Self {
            config: CookieConfig::default(),
        }
    }
}

impl FlashStore for CookieStore {
    fn load<State>(&self, req: &tide::Request<State>) -> Option<Vec<FlashMessage>> {
        match req.cookie("_flash") {
            None => None,
            Some(cookie) => {
                let messages: Vec<FlashMessage> =
                    serde_json::from_str(cookie.value()).unwrap_or_default();
                Some(messages)
            }
        }
    }

    fn insert(&self, res: &mut tide::Response) {
        if let Some(flash) = res.ext::<Flash>() {
            res.insert_cookie(
                Cookie::build(
                    "_flash",
                    serde_json::to_string(&flash.messages).unwrap_or_default(),
                )
                .max_age(self.config.max_age)
                .same_site(self.config.site)
                .http_only(self.config.http_only)
                .path(self.config.path.clone())
                .finish(),
            );
        }
    }

    fn clear(&self, res: &mut tide::Response) {
        res.insert_cookie(
            Cookie::build("_flash", "")
                .max_age(time::Duration::seconds(0))
                .same_site(self.config.site)
                .http_only(self.config.http_only)
                .path(self.config.path.clone())
                .finish(),
        );
    }
}