safe_vk_common/
keyboard.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Deserialize, Serialize, Debug, Clone)]
4#[serde(untagged)]
5pub enum KeyboardAction<T> {
6    Text {
7        #[serde(rename = "type")]
8        button_type: String,
9        label: String,
10        payload: T,
11    },
12    OpenLink {
13        #[serde(rename = "type")]
14        button_type: String,
15        link: String,
16        label: String,
17        payload: T,
18    },
19    Location {
20        #[serde(rename = "type")]
21        button_type: String,
22        payload: T,
23    },
24    VkPay {
25        #[serde(rename = "type")]
26        button_type: String,
27        payload: T,
28        hash: String,
29    },
30    OpenApp {
31        #[serde(rename = "type")]
32        button_type: String,
33        app_id: u32,
34        owner_id: u32,
35        payload: T,
36        label: String,
37        hash: String,
38    },
39    Callback {
40        #[serde(rename = "type")]
41        button_type: String,
42        label: String,
43        payload: T,
44    },
45}
46
47#[derive(Deserialize, Serialize, Debug, Clone)]
48#[serde(rename_all = "lowercase")]
49pub enum KeyboardColor {
50    Primary,
51    Secondary,
52    Negative,
53    Positive,
54}
55
56#[derive(Deserialize, Serialize, Debug, Clone)]
57pub struct Keyboard<T> {
58    one_time: bool,
59    inline: bool,
60    buttons: Vec<Button<T>>,
61}
62
63#[derive(Deserialize, Serialize, Debug, Clone)]
64pub struct Button<T> {
65    action: KeyboardAction<T>,
66    color: Option<KeyboardColor>,
67}
68
69// Button colors are only for 'text' and 'callback' buttons
70impl<T> Button<T> {
71    pub fn new(action: KeyboardAction<T>, color: Option<KeyboardColor>) -> Self {
72        Button { action, color }
73    }
74
75    pub fn text(label: &str, payload: T, color: KeyboardColor) -> Self {
76        let button_type = String::from("text");
77        Button::new(
78            KeyboardAction::Text {
79                button_type,
80                label: label.to_string(),
81                payload,
82            },
83            Some(color),
84        )
85    }
86
87    pub fn open_link(link: &str, label: &str, payload: T) -> Self {
88        let button_type = String::from("open_link");
89        Button::new(
90            KeyboardAction::OpenLink {
91                button_type,
92                link: link.to_string(),
93                label: label.to_string(),
94                payload,
95            },
96            None,
97        )
98    }
99
100    pub fn location(payload: T) -> Self {
101        let button_type = String::from("location");
102        Button::new(
103            KeyboardAction::Location {
104                button_type,
105                payload,
106            },
107            None,
108        )
109    }
110
111    pub fn vkpay(payload: T, hash: &str) -> Self {
112        let button_type = String::from("vkpay");
113        Button::new(
114            KeyboardAction::VkPay {
115                button_type,
116                payload,
117                hash: hash.to_string(),
118            },
119            None,
120        )
121    }
122
123    pub fn open_app(app_id: u32, owner_id: u32, payload: T, label: &str, hash: &str) -> Self {
124        let button_type = String::from("open_app");
125        Button::new(
126            KeyboardAction::OpenApp {
127                button_type,
128                app_id,
129                owner_id,
130                payload,
131                label: label.to_string(),
132                hash: hash.to_string(),
133            },
134            None,
135        )
136    }
137
138    pub fn callback(label: &str, payload: T, color: KeyboardColor) -> Self {
139        let button_type = String::from("callback");
140        Button::new(
141            KeyboardAction::Callback {
142                button_type,
143                label: label.to_string(),
144                payload,
145            },
146            Some(color),
147        )
148    }
149}
150
151#[derive(Debug, Serialize, Deserialize)]
152pub struct ShowSnackbar {
153    /// The type of action, always set to 'show_snackbar'.
154    #[serde(rename = "type")]
155    event_type: &'static str,
156    /// The text to display in the snackbar. Maximum length is 90 characters.
157    text: String,
158}
159
160#[derive(Debug, Serialize, Deserialize)]
161pub struct OpenLink {
162    /// The type of action, always set to 'open_link'.
163    #[serde(rename = "type")]
164    event_type: &'static str,
165    /// The URL to be opened.
166    link: String,
167}
168
169#[derive(Debug, Serialize, Deserialize)]
170pub struct OpenApp {
171    /// The type of action, always set to 'open_app'.
172    #[serde(rename = "type")]
173    event_type: &'static str,
174    /// The app identifier for the VK Mini Apps.
175    app_id: i32,
176    /// The identifier of the community where the app is installed, if it is opened in a community context.
177    owner_id: i32,
178    /// The navigation hash that will be added to the launch parameters after the '#' symbol.
179    ///
180    /// Do not include the '#' symbol in the hash.
181    hash: String,
182}
183
184impl ShowSnackbar {
185    /// Creates a new `ShowSnackbar` action.
186    pub fn new(text: impl Into<String>) -> Self {
187        ShowSnackbar {
188            event_type: "show_snackbar",
189            text: text.into(),
190        }
191    }
192}
193
194impl OpenLink {
195    /// Creates a new `OpenLink` action.
196    pub fn new(link: impl Into<String>) -> Self {
197        OpenLink {
198            event_type: "open_link",
199            link: link.into(),
200        }
201    }
202}
203
204impl OpenApp {
205    /// Creates a new `OpenApp` action with the specified parameters.
206    pub fn new(app_id: i32, owner_id: i32, hash: String) -> Self {
207        OpenApp {
208            event_type: "open_app",
209            app_id,
210            owner_id,
211            hash,
212        }
213    }
214}