1use std::collections::HashMap;
16use std::fmt;
17use std::sync::Arc;
18
19use serde::Serialize;
20use serde::de::DeserializeOwned;
21
22use crate::FsmState;
23use crate::error::StorageError;
24use crate::key::StateKey;
25use crate::storage::StateStorage;
26
27#[derive(Clone)]
32pub struct StateContext {
33 storage: Arc<dyn StateStorage>,
34 key: StateKey,
35 pub current_state: String,
37}
38
39impl StateContext {
40 pub fn new(storage: Arc<dyn StateStorage>, key: StateKey, current_state: String) -> Self {
42 Self {
43 storage,
44 key,
45 current_state,
46 }
47 }
48
49 pub async fn transition(&self, new_state: impl FsmState) -> Result<(), StorageError> {
51 self.storage
52 .set_state(self.key.clone(), new_state.as_key())
53 .await
54 }
55
56 pub async fn clear_state(&self) -> Result<(), StorageError> {
58 self.storage.clear_state(self.key.clone()).await
59 }
60
61 pub async fn set_data<T: Serialize>(&self, field: &str, value: T) -> Result<(), StorageError> {
63 let json = serde_json::to_value(value).map_err(|e| {
64 StorageError::with_source(format!("failed to serialize field `{field}`"), e)
65 })?;
66 self.storage.set_data(self.key.clone(), field, json).await
67 }
68
69 pub async fn get_data<T: DeserializeOwned>(
71 &self,
72 field: &str,
73 ) -> Result<Option<T>, StorageError> {
74 let raw = self.storage.get_data(self.key.clone(), field).await?;
75 match raw {
76 None => Ok(None),
77 Some(val) => {
78 let typed = serde_json::from_value(val).map_err(|e| {
79 StorageError::with_source(format!("failed to deserialize field `{field}`"), e)
80 })?;
81 Ok(Some(typed))
82 }
83 }
84 }
85
86 pub async fn get_all_data(&self) -> Result<HashMap<String, serde_json::Value>, StorageError> {
88 self.storage.get_all_data(self.key.clone()).await
89 }
90
91 pub async fn clear_data(&self) -> Result<(), StorageError> {
93 self.storage.clear_data(self.key.clone()).await
94 }
95
96 pub async fn clear_all(&self) -> Result<(), StorageError> {
98 self.storage.clear_all(self.key.clone()).await
99 }
100
101 pub fn key(&self) -> &StateKey {
103 &self.key
104 }
105}
106
107impl fmt::Debug for StateContext {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 f.debug_struct("StateContext")
110 .field("key", &self.key)
111 .field("current_state", &self.current_state)
112 .finish()
113 }
114}