use crate::SessionConfig;
use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt::Debug};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SessionData {
#[serde(skip)]
pub(crate) id: String,
pub(crate) data: HashMap<String, String>,
#[serde(skip)]
pub(crate) expires: DateTime<Utc>,
#[serde(skip)]
pub(crate) autoremove: DateTime<Utc>,
#[serde(skip)]
pub(crate) destroy: bool,
#[serde(skip)]
pub(crate) renew: bool,
pub(crate) longterm: bool,
#[serde(skip)]
pub(crate) store: bool,
#[serde(skip)]
pub(crate) update: bool,
#[serde(skip)]
pub(crate) requests: usize,
#[serde(skip)]
pub(crate) last_db_update: DateTime<Utc>,
}
impl SessionData {
#[inline]
pub(crate) fn new(id: String, storable: bool, config: &SessionConfig) -> Self {
Self {
id,
data: HashMap::new(),
expires: Utc::now() + config.lifespan,
destroy: false,
renew: false,
autoremove: Utc::now() + config.memory.memory_lifespan,
longterm: false,
store: storable,
update: true,
requests: 1,
last_db_update: Utc::now(),
}
}
#[inline]
pub(crate) fn expired(&self) -> bool {
self.expires < Utc::now()
}
#[inline]
pub(crate) fn service_clear(&mut self, memory_lifespan: Duration, clear_check: bool) {
if clear_check && self.autoremove < Utc::now() {
self.update = true;
if self.expired() {
self.data.clear();
}
}
self.autoremove = Utc::now() + memory_lifespan;
}
#[inline]
pub fn renew(&mut self) {
self.renew = true;
self.update = true;
}
#[inline]
pub fn update(&mut self) {
self.update = true;
}
#[inline]
pub fn destroy(&mut self) {
self.destroy = true;
}
#[inline]
pub fn set_longterm(&mut self, longterm: bool) {
self.longterm = longterm;
self.update = true;
}
#[inline]
pub fn set_store(&mut self, can_store: bool) {
self.store = can_store;
self.update = true;
}
#[inline]
pub fn get<T: serde::de::DeserializeOwned>(&self, key: &str) -> Option<T> {
let string = self.data.get(key)?;
serde_json::from_str(string).ok()
}
#[inline]
pub fn get_remove<T: serde::de::DeserializeOwned>(&mut self, key: &str) -> Option<T> {
let string = self.data.remove(key)?;
self.update = true;
serde_json::from_str(&string).ok()
}
#[inline]
pub fn set(&mut self, key: &str, value: impl Serialize) {
let value = serde_json::to_string(&value).unwrap_or_else(|_| "".to_string());
let _ = self.data.insert(key.to_string(), value);
self.update = true;
}
#[inline]
pub fn remove(&mut self, key: &str) {
let _ = self.data.remove(key);
self.update = true;
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
self.update = true;
}
#[inline]
pub(crate) fn remove_request(&mut self) {
self.requests = self.requests.saturating_sub(1);
}
#[inline]
pub(crate) fn set_request(&mut self) {
self.requests = self.requests.saturating_add(1);
}
#[inline]
pub(crate) fn is_parallel(&self) -> bool {
self.requests >= 1
}
}
#[derive(Debug)]
pub(crate) struct SessionTimers {
pub(crate) last_expiry_sweep: DateTime<Utc>,
pub(crate) last_database_expiry_sweep: DateTime<Utc>,
}