open_lark/card/components/containers/
column_set.rs1use serde::{Deserialize, Serialize};
2
3use crate::card::{components::CardElement, href::FeishuCardHrefVal};
4
5#[derive(Debug, Serialize, Deserialize)]
7pub struct ColumnSetContainer {
8 tag: String,
10 #[serde(skip_serializing_if = "Option::is_none")]
17 horizontal_spacing: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
24 horizontal_align: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
33 margin: Option<String>,
34 flex_mode: String,
44 #[serde(skip_serializing_if = "Option::is_none")]
50 background_style: Option<String>,
51 columns: Vec<Column>,
53 #[serde(skip_serializing_if = "Option::is_none")]
56 action: Option<ColumnAction>,
57}
58
59impl Default for ColumnSetContainer {
60 fn default() -> Self {
61 ColumnSetContainer {
62 tag: "column_set".to_string(),
63 background_style: None,
64 horizontal_spacing: None,
65 horizontal_align: None,
66 columns: vec![],
67 margin: None,
68 flex_mode: "".to_string(),
69 action: None,
70 }
71 }
72}
73
74impl ColumnSetContainer {
75 pub fn new() -> Self {
76 ColumnSetContainer::default()
77 }
78
79 pub fn horizontal_spacing(mut self, horizontal_spacing: impl ToString) -> Self {
80 self.horizontal_spacing = Some(horizontal_spacing.to_string());
81 self
82 }
83
84 pub fn horizontal_align(mut self, horizontal_align: impl ToString) -> Self {
85 self.horizontal_align = Some(horizontal_align.to_string());
86 self
87 }
88
89 pub fn margin(mut self, margin: impl ToString) -> Self {
90 self.margin = Some(margin.to_string());
91 self
92 }
93
94 pub fn flex_mode(mut self, flex_mode: impl ToString) -> Self {
95 self.flex_mode = flex_mode.to_string();
96 self
97 }
98
99 pub fn background_style(mut self, background_style: impl ToString) -> Self {
100 self.background_style = Some(background_style.to_string());
101 self
102 }
103
104 pub fn columns(mut self, columns: Vec<Column>) -> Self {
105 self.columns = columns;
106 self
107 }
108
109 pub fn action(mut self, action: ColumnAction) -> Self {
110 self.action = Some(action);
111 self
112 }
113}
114
115#[derive(Debug, Serialize, Deserialize)]
117pub struct Column {
118 tag: String,
120 #[serde(skip_serializing_if = "Option::is_none")]
125 background_style: Option<String>,
126 #[serde(skip_serializing_if = "Option::is_none")]
132 width: Option<String>,
133 #[serde(skip_serializing_if = "Option::is_none")]
135 weight: Option<u32>,
136 #[serde(skip_serializing_if = "Option::is_none")]
142 vertical_align: Option<String>,
143 #[serde(skip_serializing_if = "Option::is_none")]
150 vertical_spacing: Option<String>,
151 #[serde(skip_serializing_if = "Option::is_none")]
157 padding: Option<String>,
158 elements: Vec<CardElement>,
160 #[serde(skip_serializing_if = "Option::is_none")]
163 action: Option<ColumnAction>,
164}
165
166impl Default for Column {
167 fn default() -> Self {
168 Column {
169 tag: "column".to_string(),
170 background_style: None,
171 width: None,
172 weight: None,
173 vertical_align: None,
174 vertical_spacing: None,
175 padding: None,
176 elements: vec![],
177 action: None,
178 }
179 }
180}
181
182impl Column {
183 pub fn new() -> Self {
184 Self::default()
185 }
186
187 pub fn background_style(mut self, background_style: impl ToString) -> Self {
188 self.background_style = Some(background_style.to_string());
189 self
190 }
191
192 pub fn width(mut self, width: impl ToString) -> Self {
193 self.width = Some(width.to_string());
194 self
195 }
196
197 pub fn weight(mut self, weight: u32) -> Self {
198 self.weight = Some(weight);
199 self
200 }
201
202 pub fn vertical_align(mut self, vertical_align: impl ToString) -> Self {
203 self.vertical_align = Some(vertical_align.to_string());
204 self
205 }
206
207 pub fn vertical_spacing(mut self, vertical_spacing: impl ToString) -> Self {
208 self.vertical_spacing = Some(vertical_spacing.to_string());
209 self
210 }
211
212 pub fn padding(mut self, padding: impl ToString) -> Self {
213 self.padding = Some(padding.to_string());
214 self
215 }
216
217 pub fn elements(mut self, elements: Vec<CardElement>) -> Self {
218 self.elements = elements;
219 self
220 }
221
222 pub fn action(mut self, action: ColumnAction) -> Self {
223 self.action = Some(action);
224 self
225 }
226}
227
228#[derive(Debug, Serialize, Deserialize, Default)]
231pub struct ColumnAction {
232 #[serde(skip_serializing_if = "Option::is_none")]
234 multi_url: Option<FeishuCardHrefVal>,
235}
236
237impl ColumnAction {
238 pub fn new() -> Self {
239 Self::default()
240 }
241
242 pub fn multi_url(mut self, multi_url: FeishuCardHrefVal) -> Self {
243 self.multi_url = Some(multi_url);
244 self
245 }
246}
247
248#[cfg(test)]
249mod test {
250 use serde_json::json;
251
252 use crate::card::{
253 components::containers::column_set::{Column, ColumnAction, ColumnSetContainer},
254 href::FeishuCardHrefVal,
255 };
256
257 #[test]
258 fn test_column_set() {
259 let column_set = ColumnSetContainer::new()
260 .horizontal_spacing("large")
261 .horizontal_align("left")
262 .margin("0px")
263 .flex_mode("none")
264 .background_style("default")
265 .action(
266 ColumnAction::new().multi_url(
267 FeishuCardHrefVal::new()
268 .url("https://open.feishu.cn")
269 .pc_url("https://open.feishu.com")
270 .ios_url("https://developer.apple.com/")
271 .android_url("https://developer.android.com/"),
272 ),
273 )
274 .columns(vec![Column::new()
275 .background_style("default")
276 .width("auto")
277 .weight(1)
278 .vertical_align("center")
279 .vertical_spacing("4px")
280 .padding("8px")
281 .action(
282 ColumnAction::new().multi_url(
283 FeishuCardHrefVal::new()
284 .url("https://www.baidu.com")
285 .pc_url("https://www.baidu.com")
286 .ios_url("https://www.google.com")
287 .android_url("https://www.apple.com.cn"),
288 ),
289 )]);
290
291 let expect = json!({
292 "tag": "column_set", "horizontal_spacing": "large", "horizontal_align": "left", "margin": "0px", "flex_mode": "none", "background_style": "default", "action": { "multi_url": {
300 "url": "https://open.feishu.cn",
301 "pc_url": "https://open.feishu.com",
302 "ios_url": "https://developer.apple.com/",
303 "android_url": "https://developer.android.com/"
304 }
305 },
306 "columns": [
307 {
309 "tag": "column",
310 "background_style": "default", "width": "auto", "weight": 1, "vertical_align": "center", "vertical_spacing": "4px", "padding": "8px", "action": {
317 "multi_url": {
319 "url": "https://www.baidu.com",
320 "pc_url": "https://www.baidu.com",
321 "ios_url": "https://www.google.com",
322 "android_url": "https://www.apple.com.cn"
323 }
324 },
325 "elements": [] }
327 ]
328 });
329
330 assert_eq!(json!(column_set), expect);
331 }
332}