use super::{Storage, StorageKey};
use crate::FromContext;
use serde::{de::DeserializeOwned, Serialize};
use std::collections::HashMap;
#[derive(FromContext)]
#[context(
key = "fsm_context",
description = "Context is used to manage state and data of the user in specified storage. \
This context is available only if `FSMContext` middleware is used and \
`user_id` in context is not empty."
)]
pub struct Context<S> {
storage: S,
key: StorageKey,
}
impl<S> Context<S> {
#[inline]
#[must_use]
pub fn new(storage: S, key: StorageKey) -> Self {
Self {
storage,
key,
}
}
}
impl<S> Clone for Context<S>
where
S: Clone,
{
#[inline]
fn clone(&self) -> Self {
Self {
storage: self.storage.clone(),
key: self.key.clone(),
}
}
}
impl<S> Context<S>
where
S: Storage,
{
pub async fn set_state<State>(&self, state: State) -> Result<(), S::Error>
where
State: AsRef<str> + Send,
{
self.storage.set_state(&self.key, state).await
}
pub async fn set_previous_state(&self) -> Result<(), S::Error> {
self.storage.set_previous_state(&self.key).await
}
pub async fn get_state(&self) -> Result<Option<Box<str>>, S::Error> {
self.storage.get_state(&self.key).await
}
pub async fn get_states(&self) -> Result<Box<[Box<str>]>, S::Error> {
self.storage.get_states(&self.key).await
}
pub async fn remove_states(&self) -> Result<(), S::Error> {
self.storage.remove_states(&self.key).await
}
pub async fn set_data<Key, Data>(&self, data: HashMap<Key, Data>) -> Result<(), S::Error>
where
Data: Serialize + Send,
Key: AsRef<str> + Send,
{
self.storage.set_data(&self.key, data).await
}
pub async fn set_value<Key, Value>(&self, value_key: Key, value: Value) -> Result<(), S::Error>
where
Value: Serialize + Send,
Key: AsRef<str> + Send,
{
self.storage.set_value(&self.key, value_key, value).await
}
pub async fn get_data<Data>(&self) -> Result<HashMap<Box<str>, Data>, S::Error>
where
Data: DeserializeOwned,
{
self.storage.get_data(&self.key).await
}
pub async fn get_value<Key, Value>(&self, value_key: Key) -> Result<Option<Value>, S::Error>
where
Value: DeserializeOwned,
Key: AsRef<str> + Send,
{
self.storage.get_value(&self.key, value_key).await
}
pub async fn remove_data(&self) -> Result<(), S::Error> {
self.storage.remove_data(&self.key).await
}
pub async fn finish(&self) -> Result<(), S::Error> {
self.storage.remove_states(&self.key).await?;
self.storage.remove_data(&self.key).await
}
}