Module tbot::state::chats [−][src]
A storage of state per chat.
The Chats
storage can be used to store some state for each chat
separately. An example of it is a questionary bot when the bot collects
some data from the user step-by-step:
enum Questionary { AskName, AskIfPraisedTheBorrowChecker { name: String, }, Done { name: String, has_praised_the_borrow_checker: bool, }, }
Chats
stores its states in a hash map where the key is the chat ID and
the value is the state for the chat. As explained in docs for state
,
if you want to mutate state, you need to manually wrap it in a lock,
and this applies to Chats
as well. Let’s wrap our state in a Mutex
:
use tbot::state::Chats; use tokio::sync::Mutex; let mut bot = tbot::from_env!("BOT_TOKEN") .stateful_event_loop(Mutex::new(Chats::new()));
Let’s start our questionary once the user starts the bot:
use tbot::prelude::*; bot.start(|context, state| async move { state.lock().await.insert(&*context, Questionary::AskName); let call_result = context.send_message("Hello! What's your name?").call().await; if let Err(err) = call_result { dbg!(err); } });
You can see that the insert
method can figure out the chat ID from
the context, but there’s still insert_by_id
if you need it. In fact,
Chats
’s API is very similar to the API of std
’s HashMap
,
but instead of the key you need to provide the context or use the equivalent
method with the _by_id
postfix.
If you need to, you can combine Chats
with other state stores like this:
use tbot::state::Chats; use tokio::sync::RwLock; #[derive(Default)] struct State { chats: RwLock<Chats<String>>, some_other_state: SomeOtherState, } let mut bot = tbot::from_env!("BOT_TOKEN") .stateful_event_loop(State::default());
Structs
Chats | A storage of state per chat. See the module’s docs to learn how to use it. |
Iter | An iterator over the entries of |
IterMut | A mutable iterator over the entries of |