use serde::{Deserialize, Serialize};
use crate::card::{
components::{
content_components::plain_text::PlainText, interactive_components::input::InputConfirm,
},
icon::FeishuCardTextIcon,
interactions::Behaviors,
};
#[derive(Debug, Serialize, Deserialize)]
pub struct Checker {
tag: String,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
checked: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
text: Option<PlainText>,
#[serde(skip_serializing_if = "Option::is_none")]
overall_checkable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
button_area: Option<ButtonArea>,
#[serde(skip_serializing_if = "Option::is_none")]
checked_style: Option<CheckedStyle>,
#[serde(skip_serializing_if = "Option::is_none")]
margin: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
padding: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
confirm: Option<InputConfirm>,
behaviors: Vec<Behaviors>,
#[serde(skip_serializing_if = "Option::is_none")]
hover_tips: Option<PlainText>,
#[serde(skip_serializing_if = "Option::is_none")]
disabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
disabled_tips: Option<PlainText>,
}
impl Default for Checker {
fn default() -> Self {
Self {
tag: "checker".to_string(),
name: None,
checked: None,
text: None,
overall_checkable: None,
button_area: None,
checked_style: None,
margin: None,
padding: None,
confirm: None,
behaviors: vec![],
hover_tips: None,
disabled: None,
disabled_tips: None,
}
}
}
impl Checker {
pub fn new() -> Self {
Self::default()
}
pub fn name(mut self, name: &str) -> Self {
self.name = Some(name.to_string());
self
}
pub fn checked(mut self, checked: bool) -> Self {
self.checked = Some(checked);
self
}
pub fn text(mut self, text: PlainText) -> Self {
self.text = Some(text);
self
}
pub fn overall_checkable(mut self, overall_checkable: bool) -> Self {
self.overall_checkable = Some(overall_checkable);
self
}
pub fn button_area(mut self, button_area: ButtonArea) -> Self {
self.button_area = Some(button_area);
self
}
pub fn checked_style(mut self, checked_style: CheckedStyle) -> Self {
self.checked_style = Some(checked_style);
self
}
pub fn margin(mut self, margin: &str) -> Self {
self.margin = Some(margin.to_string());
self
}
pub fn padding(mut self, padding: &str) -> Self {
self.padding = Some(padding.to_string());
self
}
pub fn confirm(mut self, confirm: InputConfirm) -> Self {
self.confirm = Some(confirm);
self
}
pub fn behaviors(mut self, behaviors: Vec<Behaviors>) -> Self {
self.behaviors = behaviors;
self
}
pub fn hover_tips(mut self, hover_tips: PlainText) -> Self {
self.hover_tips = Some(hover_tips);
self
}
pub fn disabled(mut self, disabled: bool) -> Self {
self.disabled = Some(disabled);
self
}
pub fn disabled_tips(mut self, disabled_tips: PlainText) -> Self {
self.disabled_tips = Some(disabled_tips);
self
}
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct ButtonArea {
#[serde(skip_serializing_if = "Option::is_none")]
pc_display_rule: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
buttons: Option<Vec<Buttons>>,
}
impl ButtonArea {
pub fn new() -> Self {
Self {
pc_display_rule: None,
buttons: None,
}
}
pub fn pc_display_rule(mut self, pc_display_rule: &str) -> Self {
self.pc_display_rule = Some(pc_display_rule.to_string());
self
}
pub fn buttons(mut self, buttons: Vec<Buttons>) -> Self {
self.buttons = Some(buttons);
self
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Buttons {
tag: String,
r#type: String,
#[serde(skip_serializing_if = "Option::is_none")]
size: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
text: Option<PlainText>,
#[serde(skip_serializing_if = "Option::is_none")]
icon: Option<FeishuCardTextIcon>,
#[serde(skip_serializing_if = "Option::is_none")]
disabled: Option<bool>,
behaviors: Vec<Behaviors>,
}
impl Buttons {
pub fn new(r#type: &str) -> Self {
Self {
tag: "button".to_string(),
r#type: r#type.to_string(),
size: None,
text: None,
icon: None,
disabled: None,
behaviors: vec![],
}
}
pub fn r#type(mut self, r#type: &str) -> Self {
self.r#type = r#type.to_string();
self
}
pub fn size(mut self, size: &str) -> Self {
self.size = Some(size.to_string());
self
}
pub fn text(mut self, text: PlainText) -> Self {
self.text = Some(text);
self
}
pub fn icon(mut self, icon: FeishuCardTextIcon) -> Self {
self.icon = Some(icon);
self
}
pub fn disabled(mut self, disabled: bool) -> Self {
self.disabled = Some(disabled);
self
}
pub fn behaviors(mut self, behaviors: Vec<Behaviors>) -> Self {
self.behaviors = behaviors;
self
}
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct CheckedStyle {
show_strikethrough: Option<bool>,
opacity: Option<f32>,
}
impl CheckedStyle {
pub fn new() -> Self {
Self::default()
}
pub fn show_strikethrough(mut self, show_strikethrough: bool) -> Self {
self.show_strikethrough = Some(show_strikethrough);
self
}
pub fn opacity(mut self, opacity: f32) -> Self {
self.opacity = Some(opacity);
self
}
}
#[cfg(test)]
mod test {
use serde_json::json;
use crate::card::interactions::CallbackBehavior;
use super::*;
#[test]
fn test_checker() {
let checker = super::Checker::new()
.name("check_1")
.checked(false)
.text(
PlainText::text("")
.text_size("normal")
.text_color("default")
.text_align("left"),
)
.overall_checkable(true)
.button_area(ButtonArea::new().pc_display_rule("always").buttons(
vec![Buttons::new("text")
.size("small")
.text(PlainText::text("text按钮"))
.icon(
FeishuCardTextIcon::new()
.token("chat-forbidden_outlined")
.color("orange")
.img_key("img_v2_38811724"),
).disabled(false)],
))
.checked_style(CheckedStyle::new().show_strikethrough(true).opacity(1.0))
.margin("0px")
.padding("0px")
.behaviors(vec![Behaviors::Callback(CallbackBehavior::new(
json!({"key": "value"}),
))])
.disabled(false);
let json = json!({
"tag": "checker", "name": "check_1", "checked": false, "text": { "tag": "plain_text", "content": "", "text_size": "normal", "text_color": "default", "text_align": "left", },
"overall_checkable": true, "button_area": { "pc_display_rule": "always", "buttons": [ {
"tag": "button", "type": "text", "size": "small", "text": { "tag": "plain_text",
"content": "text按钮"
},
"icon": { "tag": "standard_icon", "token": "chat-forbidden_outlined", "color": "orange", "img_key": "img_v2_38811724" },
"disabled": false,
"behaviors": []
}
]
},
"checked_style": { "show_strikethrough": true, "opacity": 1.0 },
"margin": "0px", "padding": "0px", "behaviors": [ {
"type": "callback", "value": {
"key": "value"
}
}
],
"disabled": false, });
assert_eq!(json!(checker), json);
}
}