open_lark/card/components/interactive_components/
checker.rs1use serde::{Deserialize, Serialize};
2
3use crate::card::{
4 components::{
5 content_components::plain_text::PlainText, interactive_components::input::InputConfirm,
6 },
7 icon::FeishuCardTextIcon,
8 interactions::Behaviors,
9};
10
11#[derive(Debug, Serialize, Deserialize)]
13pub struct Checker {
14 tag: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
20 name: Option<String>,
21 #[serde(skip_serializing_if = "Option::is_none")]
26 checked: Option<bool>,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 text: Option<PlainText>,
30 #[serde(skip_serializing_if = "Option::is_none")]
35 overall_checkable: Option<bool>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 button_area: Option<ButtonArea>,
39 #[serde(skip_serializing_if = "Option::is_none")]
41 checked_style: Option<CheckedStyle>,
42 #[serde(skip_serializing_if = "Option::is_none")]
48 margin: Option<String>,
49 #[serde(skip_serializing_if = "Option::is_none")]
55 padding: Option<String>,
56 #[serde(skip_serializing_if = "Option::is_none")]
61 confirm: Option<InputConfirm>,
62 behaviors: Vec<Behaviors>,
64 #[serde(skip_serializing_if = "Option::is_none")]
68 hover_tips: Option<PlainText>,
69 #[serde(skip_serializing_if = "Option::is_none")]
74 disabled: Option<bool>,
75 #[serde(skip_serializing_if = "Option::is_none")]
77 disabled_tips: Option<PlainText>,
78}
79
80impl Default for Checker {
81 fn default() -> Self {
82 Self {
83 tag: "checker".to_string(),
84 name: None,
85 checked: None,
86 text: None,
87 overall_checkable: None,
88 button_area: None,
89 checked_style: None,
90 margin: None,
91 padding: None,
92 confirm: None,
93 behaviors: vec![],
94 hover_tips: None,
95 disabled: None,
96 disabled_tips: None,
97 }
98 }
99}
100
101impl Checker {
102 pub fn new() -> Self {
103 Self::default()
104 }
105
106 pub fn name(mut self, name: &str) -> Self {
107 self.name = Some(name.to_string());
108 self
109 }
110
111 pub fn checked(mut self, checked: bool) -> Self {
112 self.checked = Some(checked);
113 self
114 }
115
116 pub fn text(mut self, text: PlainText) -> Self {
117 self.text = Some(text);
118 self
119 }
120
121 pub fn overall_checkable(mut self, overall_checkable: bool) -> Self {
122 self.overall_checkable = Some(overall_checkable);
123 self
124 }
125
126 pub fn button_area(mut self, button_area: ButtonArea) -> Self {
127 self.button_area = Some(button_area);
128 self
129 }
130
131 pub fn checked_style(mut self, checked_style: CheckedStyle) -> Self {
132 self.checked_style = Some(checked_style);
133 self
134 }
135
136 pub fn margin(mut self, margin: &str) -> Self {
137 self.margin = Some(margin.to_string());
138 self
139 }
140
141 pub fn padding(mut self, padding: &str) -> Self {
142 self.padding = Some(padding.to_string());
143 self
144 }
145
146 pub fn confirm(mut self, confirm: InputConfirm) -> Self {
147 self.confirm = Some(confirm);
148 self
149 }
150
151 pub fn behaviors(mut self, behaviors: Vec<Behaviors>) -> Self {
152 self.behaviors = behaviors;
153 self
154 }
155
156 pub fn hover_tips(mut self, hover_tips: PlainText) -> Self {
157 self.hover_tips = Some(hover_tips);
158 self
159 }
160
161 pub fn disabled(mut self, disabled: bool) -> Self {
162 self.disabled = Some(disabled);
163 self
164 }
165
166 pub fn disabled_tips(mut self, disabled_tips: PlainText) -> Self {
167 self.disabled_tips = Some(disabled_tips);
168 self
169 }
170}
171
172#[derive(Debug, Serialize, Deserialize, Default)]
174pub struct ButtonArea {
175 #[serde(skip_serializing_if = "Option::is_none")]
176 pc_display_rule: Option<String>,
177 #[serde(skip_serializing_if = "Option::is_none")]
178 buttons: Option<Vec<Buttons>>,
179}
180
181impl ButtonArea {
182 pub fn new() -> Self {
183 Self {
184 pc_display_rule: None,
185 buttons: None,
186 }
187 }
188
189 pub fn pc_display_rule(mut self, pc_display_rule: &str) -> Self {
190 self.pc_display_rule = Some(pc_display_rule.to_string());
191 self
192 }
193
194 pub fn buttons(mut self, buttons: Vec<Buttons>) -> Self {
195 self.buttons = Some(buttons);
196 self
197 }
198}
199
200#[derive(Debug, Serialize, Deserialize)]
202pub struct Buttons {
203 tag: String,
205 r#type: String,
211 #[serde(skip_serializing_if = "Option::is_none")]
218 size: Option<String>,
219 #[serde(skip_serializing_if = "Option::is_none")]
221 text: Option<PlainText>,
222 #[serde(skip_serializing_if = "Option::is_none")]
224 icon: Option<FeishuCardTextIcon>,
225 #[serde(skip_serializing_if = "Option::is_none")]
230 disabled: Option<bool>,
231 behaviors: Vec<Behaviors>,
233}
234
235impl Buttons {
236 pub fn new(r#type: &str) -> Self {
237 Self {
238 tag: "button".to_string(),
239 r#type: r#type.to_string(),
240 size: None,
241 text: None,
242 icon: None,
243 disabled: None,
244 behaviors: vec![],
245 }
246 }
247
248 pub fn r#type(mut self, r#type: &str) -> Self {
249 self.r#type = r#type.to_string();
250 self
251 }
252
253 pub fn size(mut self, size: &str) -> Self {
254 self.size = Some(size.to_string());
255 self
256 }
257
258 pub fn text(mut self, text: PlainText) -> Self {
259 self.text = Some(text);
260 self
261 }
262
263 pub fn icon(mut self, icon: FeishuCardTextIcon) -> Self {
264 self.icon = Some(icon);
265 self
266 }
267
268 pub fn disabled(mut self, disabled: bool) -> Self {
269 self.disabled = Some(disabled);
270 self
271 }
272
273 pub fn behaviors(mut self, behaviors: Vec<Behaviors>) -> Self {
274 self.behaviors = behaviors;
275 self
276 }
277}
278
279#[derive(Debug, Serialize, Deserialize, Default)]
280pub struct CheckedStyle {
281 show_strikethrough: Option<bool>,
283 opacity: Option<f32>,
285}
286
287impl CheckedStyle {
288 pub fn new() -> Self {
289 Self::default()
290 }
291
292 pub fn show_strikethrough(mut self, show_strikethrough: bool) -> Self {
293 self.show_strikethrough = Some(show_strikethrough);
294 self
295 }
296
297 pub fn opacity(mut self, opacity: f32) -> Self {
298 self.opacity = Some(opacity);
299 self
300 }
301}
302
303#[cfg(test)]
304mod test {
305 use serde_json::json;
306
307 use crate::card::interactions::CallbackBehavior;
308
309 use super::*;
310
311 #[test]
312 fn test_checker() {
313 let checker = super::Checker::new()
314 .name("check_1")
315 .checked(false)
316 .text(
317 PlainText::text("")
318 .text_size("normal")
319 .text_color("default")
320 .text_align("left"),
321 )
322 .overall_checkable(true)
323 .button_area(ButtonArea::new().pc_display_rule("always").buttons(
324 vec![Buttons::new("text")
325 .size("small")
326 .text(PlainText::text("text按钮"))
327 .icon(
328 FeishuCardTextIcon::new()
329 .token("chat-forbidden_outlined")
330 .color("orange")
331 .img_key("img_v2_38811724"),
332 ).disabled(false)],
333 ))
334 .checked_style(CheckedStyle::new().show_strikethrough(true).opacity(1.0))
335 .margin("0px")
336 .padding("0px")
337 .behaviors(vec![Behaviors::Callback(CallbackBehavior::new(
338 json!({"key": "value"}),
339 ))])
340 .disabled(false);
341
342 let json = json!({
343 "tag": "checker", "name": "check_1", "checked": false, "text": { "tag": "plain_text", "content": "", "text_size": "normal", "text_color": "default", "text_align": "left", },
353 "overall_checkable": true, "button_area": { "pc_display_rule": "always", "buttons": [ {
358 "tag": "button", "type": "text", "size": "small", "text": { "tag": "plain_text",
363 "content": "text按钮"
364 },
365 "icon": { "tag": "standard_icon", "token": "chat-forbidden_outlined", "color": "orange", "img_key": "img_v2_38811724" },
371 "disabled": false,
372 "behaviors": []
373 }
374 ]
375 },
376 "checked_style": { "show_strikethrough": true, "opacity": 1.0 },
380 "margin": "0px", "padding": "0px", "behaviors": [ {
386 "type": "callback", "value": {
388 "key": "value"
390 }
391 }
392 ],
393
394 "disabled": false, });
397
398 assert_eq!(json!(checker), json);
399 }
400}