vkteams_bot/api/utils/
keyboard.rs1use crate::api::types::*;
3use std::convert::From;
4
5impl From<Keyboard> for String {
6 fn from(val: Keyboard) -> Self {
8 val.get_keyboard()
9 }
10}
11impl Keyboard {
12 pub fn new() -> Self {
14 Self {
15 ..Default::default()
16 }
17 }
18 pub fn add_row(&mut self) -> Self {
20 self.buttons.push(vec![]);
21 self.to_owned()
22 }
23 pub fn get_row_index(&self) -> usize {
25 self.buttons.len() - 1
26 }
27 pub fn add_button(&mut self, button: &ButtonKeyboard) -> Self {
30 if self.buttons[self.get_row_index()].len() >= 8 {
32 self.add_row();
33 }
34 let row_index = self.get_row_index();
35 self.buttons[row_index].push(button.clone());
36 self.to_owned()
37 }
38 fn get_keyboard(&self) -> String {
40 serde_json::to_string(&self.buttons).unwrap()
41 }
42}
43impl ButtonKeyboard {
44 pub fn url(text: String, url: String, style: ButtonStyle) -> Self {
50 ButtonKeyboard {
51 text,
52 style: Some(style),
53 url: Some(url),
54 callback_data: None,
55 }
56 }
57 pub fn cb(text: String, cb: String, style: ButtonStyle) -> Self {
63 ButtonKeyboard {
64 text,
65 style: Some(style),
66 url: None,
67 callback_data: Some(cb),
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::api::types::ButtonStyle;
76
77 #[test]
78 fn test_keyboard_new_and_add_row() {
79 let mut kb = Keyboard::new();
80 assert_eq!(kb.buttons.len(), 1);
81 kb = kb.add_row();
82 assert_eq!(kb.buttons.len(), 2);
83 kb = kb.add_row();
84 assert_eq!(kb.buttons.len(), 3);
85 }
86
87 #[test]
88 fn test_keyboard_add_button_and_row_limits() {
89 let mut kb = Keyboard::new();
90 let btn = ButtonKeyboard::url(
91 "A".to_string(),
92 "http://a".to_string(),
93 ButtonStyle::Primary,
94 );
95 for _ in 0..8 {
97 kb = kb.add_button(&btn);
98 }
99 assert_eq!(kb.buttons.len(), 1);
100 assert_eq!(kb.buttons[0].len(), 8);
101 kb = kb.add_button(&btn);
103 assert_eq!(kb.buttons.len(), 2);
104 assert_eq!(kb.buttons[1].len(), 1);
105 }
106
107 #[test]
108 fn test_keyboard_get_row_index() {
109 let mut kb = Keyboard::new();
110 assert_eq!(kb.get_row_index(), 0);
111 kb = kb.add_row();
112 assert_eq!(kb.get_row_index(), 1);
113 }
114
115 #[test]
116 fn test_keyboard_to_string_json() {
117 let mut kb = Keyboard::new();
118 let btn = ButtonKeyboard::cb("B".to_string(), "cb".to_string(), ButtonStyle::Attention);
119 kb = kb.add_button(&btn);
120 let json: String = kb.clone().into();
121 let parsed: Vec<Vec<ButtonKeyboard>> = serde_json::from_str(&json).unwrap();
123 assert_eq!(parsed.len(), kb.buttons.len());
124 assert_eq!(parsed[0][0].text, "B");
125 }
126
127 #[test]
128 fn test_buttonkeyboard_url_and_cb() {
129 let btn_url = ButtonKeyboard::url(
130 "Link".to_string(),
131 "http://link".to_string(),
132 ButtonStyle::Base,
133 );
134 assert_eq!(btn_url.text, "Link");
135 assert_eq!(btn_url.url.as_deref(), Some("http://link"));
136 assert!(btn_url.callback_data.is_none());
137 let btn_cb =
138 ButtonKeyboard::cb("CB".to_string(), "data".to_string(), ButtonStyle::Attention);
139 assert_eq!(btn_cb.text, "CB");
140 assert_eq!(btn_cb.callback_data.as_deref(), Some("data"));
141 assert!(btn_cb.url.is_none());
142 }
143
144 #[test]
145 fn test_keyboard_add_many_buttons_multiple_rows() {
146 let mut kb = Keyboard::new();
147 let btn = ButtonKeyboard::url(
148 "A".to_string(),
149 "http://a".to_string(),
150 ButtonStyle::Primary,
151 );
152 for _ in 0..17 {
153 kb = kb.add_button(&btn);
154 }
155 assert_eq!(kb.buttons.len(), 3);
157 assert_eq!(kb.buttons[0].len(), 8);
158 assert_eq!(kb.buttons[1].len(), 8);
159 assert_eq!(kb.buttons[2].len(), 1);
160 }
161}