open_lark/card/components/interactive_components/
image_picker.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use crate::card::components::content_components::plain_text::PlainText;
5
6#[derive(Debug, Serialize, Deserialize)]
8pub struct ImagePicker {
9 tag: String,
11 #[serde(skip_serializing_if = "Option::is_none")]
16 style: Option<String>,
17 #[serde(skip_serializing_if = "Option::is_none")]
24 multi_select: Option<bool>,
25 #[serde(skip_serializing_if = "Option::is_none")]
31 layout: Option<String>,
32 #[serde(skip_serializing_if = "Option::is_none")]
36 name: Option<String>,
37 #[serde(skip_serializing_if = "Option::is_none")]
44 required: Option<bool>,
45 #[serde(skip_serializing_if = "Option::is_none")]
50 can_preview: Option<bool>,
51 #[serde(skip_serializing_if = "Option::is_none")]
57 aspect_ratio: Option<String>,
58 #[serde(skip_serializing_if = "Option::is_none")]
63 disabled: Option<bool>,
64 #[serde(skip_serializing_if = "Option::is_none")]
66 disabled_tips: Option<PlainText>,
67 #[serde(skip_serializing_if = "Option::is_none")]
69 value: Option<Value>,
70 #[serde(skip_serializing_if = "Option::is_none")]
72 options: Option<Vec<SelectImageOption>>,
73}
74
75#[derive(Debug, Serialize, Deserialize, Default)]
76pub struct SelectImageOption {
77 img_key: String,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 value: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
87 disabled: Option<bool>,
88 #[serde(skip_serializing_if = "Option::is_none")]
90 disabled_tips: Option<PlainText>,
91 #[serde(skip_serializing_if = "Option::is_none")]
93 hover_tips: Option<PlainText>,
94}
95
96impl SelectImageOption {
97 pub fn new(img_key: &str) -> Self {
98 Self {
99 img_key: img_key.to_string(),
100 value: None,
101 disabled: None,
102 disabled_tips: None,
103 hover_tips: None,
104 }
105 }
106
107 pub fn value(mut self, value: &str) -> Self {
108 self.value = Some(value.to_string());
109 self
110 }
111
112 pub fn disabled(mut self, disabled: bool) -> Self {
113 self.disabled = Some(disabled);
114 self
115 }
116
117 pub fn disabled_tips(mut self, disabled_tips: PlainText) -> Self {
118 self.disabled_tips = Some(disabled_tips);
119 self
120 }
121
122 pub fn hover_tips(mut self, hover_tips: PlainText) -> Self {
123 self.hover_tips = Some(hover_tips);
124 self
125 }
126}
127
128impl Default for ImagePicker {
129 fn default() -> Self {
130 Self {
131 tag: "select_img".to_string(),
132 style: None,
133 multi_select: None,
134 layout: None,
135 name: None,
136 required: None,
137 can_preview: None,
138 aspect_ratio: None,
139 disabled: None,
140 disabled_tips: None,
141 value: None,
142 options: None,
143 }
144 }
145}
146
147impl ImagePicker {
148 pub fn new() -> Self {
149 Self::default()
150 }
151
152 pub fn style(mut self, style: &str) -> Self {
153 self.style = Some(style.to_string());
154 self
155 }
156
157 pub fn multi_select(mut self, multi_select: bool) -> Self {
158 self.multi_select = Some(multi_select);
159 self
160 }
161
162 pub fn layout(mut self, layout: &str) -> Self {
163 self.layout = Some(layout.to_string());
164 self
165 }
166
167 pub fn name(mut self, name: &str) -> Self {
168 self.name = Some(name.to_string());
169 self
170 }
171
172 pub fn required(mut self, required: bool) -> Self {
173 self.required = Some(required);
174 self
175 }
176
177 pub fn can_preview(mut self, can_preview: bool) -> Self {
178 self.can_preview = Some(can_preview);
179 self
180 }
181
182 pub fn aspect_ratio(mut self, aspect_ratio: &str) -> Self {
183 self.aspect_ratio = Some(aspect_ratio.to_string());
184 self
185 }
186
187 pub fn disabled(mut self, disabled: bool) -> Self {
188 self.disabled = Some(disabled);
189 self
190 }
191
192 pub fn disabled_tips(mut self, disabled_tips: PlainText) -> Self {
193 self.disabled_tips = Some(disabled_tips);
194 self
195 }
196
197 pub fn value(mut self, value: Value) -> Self {
198 self.value = Some(value);
199 self
200 }
201
202 pub fn options(mut self, options: Vec<SelectImageOption>) -> Self {
203 self.options = Some(options);
204 self
205 }
206}
207
208#[cfg(test)]
209mod test {
210 use serde_json::json;
211
212 use super::*;
213
214 #[test]
215 fn test_image_picker() {
216 let image_picker = ImagePicker::new()
217 .style("laser")
218 .multi_select(false)
219 .layout("bisect")
220 .name("choice_123")
221 .required(false)
222 .can_preview(false)
223 .aspect_ratio("16:9")
224 .disabled(false)
225 .disabled_tips(PlainText::text("用户禁用提示文案"))
226 .value(json!({"key": "value"}))
227 .options(vec![SelectImageOption::new("xxxxxxxxxxxxxx")
228 .value("picture1")
229 .disabled(false)
230 .disabled_tips(PlainText::text("用户禁用提示文案"))
231 .hover_tips(PlainText::text("第一张图"))]);
232
233 let json = json!( {
234 "tag": "select_img", "style": "laser", "multi_select": false, "layout": "bisect", "name": "choice_123", "required": false, "can_preview": false, "aspect_ratio": "16:9", "disabled": false, "disabled_tips": { "tag": "plain_text",
245 "content": "用户禁用提示文案"
246 },
247 "value": { "key": "value"
249 },
250 "options": [
252 {
253 "img_key": "xxxxxxxxxxxxxx", "value": "picture1", "disabled": false, "disabled_tips": { "tag": "plain_text",
258 "content": "用户禁用提示文案"
259 },
260 "hover_tips": { "tag": "plain_text",
262 "content": "第一张图"
263 },
264 }
265 ]
266 });
267
268 assert_eq!(json!(image_picker), json);
269 }
270}