baubot_core/
prelude.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Preludes for [crate::BauBot]

// Use this within the carate only
pub use crate::broadcaster::types;
#[allow(unused_imports)]
pub(crate) use log::{error, info, log, trace, warn};
pub(crate) use std::ops::Deref;
pub(crate) use std::sync::Arc;
pub(crate) use teloxide::dispatching::UpdateFilterExt;
pub(crate) use teloxide::dispatching::UpdateHandler;
pub(crate) use teloxide::prelude::*;
pub(crate) use teloxide::types::MessageId;
pub(crate) use teloxide::types::ReplyParameters;
pub(crate) use teloxide::types::User;
pub(crate) use teloxide::utils::command::BotCommands;
pub(crate) use tokio::task;

#[macro_export]
/// Message formatter
macro_rules! fmt {
    (pass $string:literal ) => {
        concat!("🥳", " ", $string)
    };
    (fail $string:literal ) => {
        concat!("😞", " ", $string)
    };
    (timeout $string:literal ) => {
        concat!("⌚", " ", $string)
    };
}

#[test]
fn macro_test() {
    let string = fmt!(pass "hello");
    println!("{string}");
    let other_string = concat!("🥳", " ", "hello");
    assert_eq!(other_string, string);
}

/// Instruct the bot to reply to a particular
pub(crate) async fn reply_message(
    bot: &Bot,
    chat_id: i64,
    message_id: i32,
    text: String,
) -> Result<Message, teloxide::RequestError> {
    let message = bot
        .send_message(ChatId(chat_id), text)
        .reply_parameters(ReplyParameters::new(MessageId(message_id)))
        .parse_mode(teloxide::types::ParseMode::Html);
    message.await
}

/// Trait for database that [crate::BauBot] is able to interact with
pub trait BauData
where
    Self: Sync + Send,
{
    /// Get user's chat_id from the DB based on the suppled `username`.
    /// Please remember that any [String] output gets parsed by [crate::BauBot] as a Html entity.
    ///
    /// # Safety
    /// The implementation of this trait should make all necessary authentication choices at the
    /// appropriate stages (e.g. verifying that the user is allowed to receive or send requests)
    fn register_user_chat_id(
        &self,
        username: &str,
    ) -> impl std::future::Future<Output = Option<i64>> + Send;

    /// Insert user's `username `into the DB together with their `chat_id`.
    /// Please remember that any [String] output gets parsed by [crate::BauBot] as a Html entity.
    ///
    /// # Safety
    /// The implementation of this trait should make all necessary authentication choices at the
    /// appropriate stages (e.g. verifying that the user is allowed to receive or send requests)
    fn insert_chat_id(
        &self,
        username: &str,
        chat_id: i64,
    ) -> impl std::future::Future<Output = Result<Option<i64>, String>> + Send;

    /// Delete user's `username `into the DB together with their `chat_id`.
    /// Please remember that any [String] output gets parsed by [crate::BauBot] as a Html entity.
    ///
    /// # Safety
    /// The implementation of this trait should make all necessary authentication choices at the
    /// appropriate stages (e.g. verifying that the user is allowed to receive or send requests)
    fn delete_chat_id(
        &self,
        username: &str,
    ) -> impl std::future::Future<Output = Result<i64, String>> + Send;

    /// Get chat_id for `username`
    ///
    /// # Safety
    /// The implementation of this trait should make all necessary authentication choices at the
    /// appropriate stages (e.g. verifying that the user is allowed to receive or send requests)
    fn get_chat_id(&self, username: &str) -> impl std::future::Future<Output = Option<i64>> + Send;

    /// Check if `username` is an admin.
    ///
    /// # Safety
    /// The implementation of this trait should make all necessary authentication choices at the
    /// appropriate stages (e.g. verifying that the user is allowed to receive or send requests)
    fn is_admin(&self, username: &str) -> impl std::future::Future<Output = bool> + Send;
}

#[derive(BotCommands, Clone, Debug)]
#[command(rename_rule = "lowercase")]
pub(crate) enum Command {
    #[command(description = "Registers you as a user of the dobby service")]
    Start,
    #[command(description = "Unregister you as a user of the dobby service")]
    Unregister,
    #[command(description = "Get list of available commands")]
    Help,
}