1use crate::models;
12use serde::{Deserialize, Serialize};
13
14#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
15pub struct FrameNode {
16 #[serde(rename = "id")]
18 pub id: String,
19 #[serde(rename = "name")]
21 pub name: String,
22 #[serde(rename = "visible", skip_serializing_if = "Option::is_none")]
24 pub visible: Option<bool>,
25 #[serde(rename = "locked", skip_serializing_if = "Option::is_none")]
27 pub locked: Option<bool>,
28 #[serde(rename = "isFixed", skip_serializing_if = "Option::is_none")]
30 pub is_fixed: Option<bool>,
31 #[serde(rename = "scrollBehavior")]
33 pub scroll_behavior: ScrollBehavior,
34 #[serde(rename = "rotation", skip_serializing_if = "Option::is_none")]
36 pub rotation: Option<f64>,
37 #[serde(rename = "componentPropertyReferences", skip_serializing_if = "Option::is_none")]
39 pub component_property_references: Option<std::collections::HashMap<String, String>>,
40 #[serde(rename = "pluginData", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")]
41 pub plugin_data: Option<Option<serde_json::Value>>,
42 #[serde(rename = "sharedPluginData", default, with = "::serde_with::rust::double_option", skip_serializing_if = "Option::is_none")]
43 pub shared_plugin_data: Option<Option<serde_json::Value>>,
44 #[serde(rename = "boundVariables", skip_serializing_if = "Option::is_none")]
45 pub bound_variables: Option<Box<models::IsLayerTraitBoundVariables>>,
46 #[serde(rename = "explicitVariableModes", skip_serializing_if = "Option::is_none")]
48 pub explicit_variable_modes: Option<std::collections::HashMap<String, String>>,
49 #[serde(rename = "blendMode")]
51 pub blend_mode: models::BlendMode,
52 #[serde(rename = "opacity", skip_serializing_if = "Option::is_none")]
54 pub opacity: Option<f64>,
55 #[serde(rename = "children")]
57 pub children: Vec<models::SubcanvasNode>,
58 #[serde(rename = "preserveRatio", skip_serializing_if = "Option::is_none")]
60 pub preserve_ratio: Option<bool>,
61 #[serde(rename = "constraints", skip_serializing_if = "Option::is_none")]
63 pub constraints: Option<Box<models::LayoutConstraint>>,
64 #[serde(rename = "relativeTransform", skip_serializing_if = "Option::is_none")]
66 pub relative_transform: Option<Vec<Vec<f64>>>,
67 #[serde(rename = "size", skip_serializing_if = "Option::is_none")]
69 pub size: Option<Box<models::Vector>>,
70 #[serde(rename = "layoutAlign", skip_serializing_if = "Option::is_none")]
72 pub layout_align: Option<LayoutAlign>,
73 #[serde(rename = "layoutGrow", skip_serializing_if = "Option::is_none")]
75 pub layout_grow: Option<f64>,
76 #[serde(rename = "layoutPositioning", skip_serializing_if = "Option::is_none")]
78 pub layout_positioning: Option<LayoutPositioning>,
79 #[serde(rename = "minWidth", skip_serializing_if = "Option::is_none")]
81 pub min_width: Option<f64>,
82 #[serde(rename = "maxWidth", skip_serializing_if = "Option::is_none")]
84 pub max_width: Option<f64>,
85 #[serde(rename = "minHeight", skip_serializing_if = "Option::is_none")]
87 pub min_height: Option<f64>,
88 #[serde(rename = "maxHeight", skip_serializing_if = "Option::is_none")]
90 pub max_height: Option<f64>,
91 #[serde(rename = "layoutSizingHorizontal", skip_serializing_if = "Option::is_none")]
93 pub layout_sizing_horizontal: Option<LayoutSizingHorizontal>,
94 #[serde(rename = "layoutSizingVertical", skip_serializing_if = "Option::is_none")]
96 pub layout_sizing_vertical: Option<LayoutSizingVertical>,
97 #[serde(rename = "clipsContent")]
99 pub clips_content: bool,
100 #[serde(rename = "background", skip_serializing_if = "Option::is_none")]
102 pub background: Option<Vec<models::Paint>>,
103 #[serde(rename = "backgroundColor", skip_serializing_if = "Option::is_none")]
105 pub background_color: Option<Box<models::Rgba>>,
106 #[serde(rename = "layoutGrids", skip_serializing_if = "Option::is_none")]
108 pub layout_grids: Option<Vec<models::LayoutGrid>>,
109 #[serde(rename = "overflowDirection", skip_serializing_if = "Option::is_none")]
111 pub overflow_direction: Option<OverflowDirection>,
112 #[serde(rename = "layoutMode", skip_serializing_if = "Option::is_none")]
114 pub layout_mode: Option<LayoutMode>,
115 #[serde(rename = "primaryAxisSizingMode", skip_serializing_if = "Option::is_none")]
117 pub primary_axis_sizing_mode: Option<PrimaryAxisSizingMode>,
118 #[serde(rename = "counterAxisSizingMode", skip_serializing_if = "Option::is_none")]
120 pub counter_axis_sizing_mode: Option<CounterAxisSizingMode>,
121 #[serde(rename = "primaryAxisAlignItems", skip_serializing_if = "Option::is_none")]
123 pub primary_axis_align_items: Option<PrimaryAxisAlignItems>,
124 #[serde(rename = "counterAxisAlignItems", skip_serializing_if = "Option::is_none")]
126 pub counter_axis_align_items: Option<CounterAxisAlignItems>,
127 #[serde(rename = "paddingLeft", skip_serializing_if = "Option::is_none")]
129 pub padding_left: Option<f64>,
130 #[serde(rename = "paddingRight", skip_serializing_if = "Option::is_none")]
132 pub padding_right: Option<f64>,
133 #[serde(rename = "paddingTop", skip_serializing_if = "Option::is_none")]
135 pub padding_top: Option<f64>,
136 #[serde(rename = "paddingBottom", skip_serializing_if = "Option::is_none")]
138 pub padding_bottom: Option<f64>,
139 #[serde(rename = "itemSpacing", skip_serializing_if = "Option::is_none")]
141 pub item_spacing: Option<f64>,
142 #[serde(rename = "itemReverseZIndex", skip_serializing_if = "Option::is_none")]
144 pub item_reverse_z_index: Option<bool>,
145 #[serde(rename = "strokesIncludedInLayout", skip_serializing_if = "Option::is_none")]
147 pub strokes_included_in_layout: Option<bool>,
148 #[serde(rename = "layoutWrap", skip_serializing_if = "Option::is_none")]
150 pub layout_wrap: Option<LayoutWrap>,
151 #[serde(rename = "counterAxisSpacing", skip_serializing_if = "Option::is_none")]
153 pub counter_axis_spacing: Option<f64>,
154 #[serde(rename = "counterAxisAlignContent", skip_serializing_if = "Option::is_none")]
156 pub counter_axis_align_content: Option<CounterAxisAlignContent>,
157 #[serde(rename = "cornerRadius", skip_serializing_if = "Option::is_none")]
159 pub corner_radius: Option<f64>,
160 #[serde(rename = "cornerSmoothing", skip_serializing_if = "Option::is_none")]
162 pub corner_smoothing: Option<f64>,
163 #[serde(rename = "rectangleCornerRadii", skip_serializing_if = "Option::is_none")]
165 pub rectangle_corner_radii: Option<Vec<f64>>,
166 #[serde(rename = "fills")]
168 pub fills: Vec<models::Paint>,
169 #[serde(rename = "styles", skip_serializing_if = "Option::is_none")]
171 pub styles: Option<std::collections::HashMap<String, String>>,
172 #[serde(rename = "strokes", skip_serializing_if = "Option::is_none")]
174 pub strokes: Option<Vec<models::Paint>>,
175 #[serde(rename = "strokeWeight", skip_serializing_if = "Option::is_none")]
177 pub stroke_weight: Option<f64>,
178 #[serde(rename = "strokeAlign", skip_serializing_if = "Option::is_none")]
180 pub stroke_align: Option<StrokeAlign>,
181 #[serde(rename = "strokeJoin", skip_serializing_if = "Option::is_none")]
183 pub stroke_join: Option<StrokeJoin>,
184 #[serde(rename = "strokeDashes", skip_serializing_if = "Option::is_none")]
186 pub stroke_dashes: Option<Vec<f64>>,
187 #[serde(rename = "fillGeometry", skip_serializing_if = "Option::is_none")]
189 pub fill_geometry: Option<Vec<models::Path>>,
190 #[serde(rename = "strokeGeometry", skip_serializing_if = "Option::is_none")]
192 pub stroke_geometry: Option<Vec<models::Path>>,
193 #[serde(rename = "strokeCap", skip_serializing_if = "Option::is_none")]
195 pub stroke_cap: Option<StrokeCap>,
196 #[serde(rename = "strokeMiterAngle", skip_serializing_if = "Option::is_none")]
198 pub stroke_miter_angle: Option<f64>,
199 #[serde(rename = "exportSettings", skip_serializing_if = "Option::is_none")]
201 pub export_settings: Option<Vec<models::ExportSetting>>,
202 #[serde(rename = "effects")]
204 pub effects: Vec<models::Effect>,
205 #[serde(rename = "isMask", skip_serializing_if = "Option::is_none")]
207 pub is_mask: Option<bool>,
208 #[serde(rename = "maskType", skip_serializing_if = "Option::is_none")]
210 pub mask_type: Option<MaskType>,
211 #[serde(rename = "isMaskOutline", skip_serializing_if = "Option::is_none")]
213 pub is_mask_outline: Option<bool>,
214 #[serde(rename = "transitionNodeID", skip_serializing_if = "Option::is_none")]
216 pub transition_node_id: Option<String>,
217 #[serde(rename = "transitionDuration", skip_serializing_if = "Option::is_none")]
219 pub transition_duration: Option<f64>,
220 #[serde(rename = "transitionEasing", skip_serializing_if = "Option::is_none")]
222 pub transition_easing: Option<models::EasingType>,
223 #[serde(rename = "individualStrokeWeights", skip_serializing_if = "Option::is_none")]
225 pub individual_stroke_weights: Option<Box<models::StrokeWeights>>,
226}
227
228impl FrameNode {
229 pub fn new(id: String, name: String, scroll_behavior: ScrollBehavior, blend_mode: models::BlendMode, children: Vec<models::SubcanvasNode>, clips_content: bool, fills: Vec<models::Paint>, effects: Vec<models::Effect>) -> FrameNode {
230 FrameNode {
231 id,
232 name,
233 visible: None,
234 locked: None,
235 is_fixed: None,
236 scroll_behavior,
237 rotation: None,
238 component_property_references: None,
239 plugin_data: None,
240 shared_plugin_data: None,
241 bound_variables: None,
242 explicit_variable_modes: None,
243 blend_mode,
244 opacity: None,
245 children,
246 preserve_ratio: None,
247 constraints: None,
248 relative_transform: None,
249 size: None,
250 layout_align: None,
251 layout_grow: None,
252 layout_positioning: None,
253 min_width: None,
254 max_width: None,
255 min_height: None,
256 max_height: None,
257 layout_sizing_horizontal: None,
258 layout_sizing_vertical: None,
259 clips_content,
260 background: None,
261 background_color: None,
262 layout_grids: None,
263 overflow_direction: None,
264 layout_mode: None,
265 primary_axis_sizing_mode: None,
266 counter_axis_sizing_mode: None,
267 primary_axis_align_items: None,
268 counter_axis_align_items: None,
269 padding_left: None,
270 padding_right: None,
271 padding_top: None,
272 padding_bottom: None,
273 item_spacing: None,
274 item_reverse_z_index: None,
275 strokes_included_in_layout: None,
276 layout_wrap: None,
277 counter_axis_spacing: None,
278 counter_axis_align_content: None,
279 corner_radius: None,
280 corner_smoothing: None,
281 rectangle_corner_radii: None,
282 fills,
283 styles: None,
284 strokes: None,
285 stroke_weight: None,
286 stroke_align: None,
287 stroke_join: None,
288 stroke_dashes: None,
289 fill_geometry: None,
290 stroke_geometry: None,
291 stroke_cap: None,
292 stroke_miter_angle: None,
293 export_settings: None,
294 effects,
295 is_mask: None,
296 mask_type: None,
297 is_mask_outline: None,
298 transition_node_id: None,
299 transition_duration: None,
300 transition_easing: None,
301 individual_stroke_weights: None,
302 }
303 }
304}
305#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
307pub enum ScrollBehavior {
308 #[serde(rename = "SCROLLS")]
309 Scrolls,
310 #[serde(rename = "FIXED")]
311 Fixed,
312 #[serde(rename = "STICKY_SCROLLS")]
313 StickyScrolls,
314}
315
316impl Default for ScrollBehavior {
317 fn default() -> ScrollBehavior {
318 Self::Scrolls
319 }
320}
321#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
323pub enum LayoutAlign {
324 #[serde(rename = "INHERIT")]
325 Inherit,
326 #[serde(rename = "STRETCH")]
327 Stretch,
328 #[serde(rename = "MIN")]
329 Min,
330 #[serde(rename = "CENTER")]
331 Center,
332 #[serde(rename = "MAX")]
333 Max,
334}
335
336impl Default for LayoutAlign {
337 fn default() -> LayoutAlign {
338 Self::Inherit
339 }
340}
341#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
343pub enum LayoutPositioning {
344 #[serde(rename = "AUTO")]
345 Auto,
346 #[serde(rename = "ABSOLUTE")]
347 Absolute,
348}
349
350impl Default for LayoutPositioning {
351 fn default() -> LayoutPositioning {
352 Self::Auto
353 }
354}
355#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
357pub enum LayoutSizingHorizontal {
358 #[serde(rename = "FIXED")]
359 Fixed,
360 #[serde(rename = "HUG")]
361 Hug,
362 #[serde(rename = "FILL")]
363 Fill,
364}
365
366impl Default for LayoutSizingHorizontal {
367 fn default() -> LayoutSizingHorizontal {
368 Self::Fixed
369 }
370}
371#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
373pub enum LayoutSizingVertical {
374 #[serde(rename = "FIXED")]
375 Fixed,
376 #[serde(rename = "HUG")]
377 Hug,
378 #[serde(rename = "FILL")]
379 Fill,
380}
381
382impl Default for LayoutSizingVertical {
383 fn default() -> LayoutSizingVertical {
384 Self::Fixed
385 }
386}
387#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
389pub enum OverflowDirection {
390 #[serde(rename = "HORIZONTAL_SCROLLING")]
391 HorizontalScrolling,
392 #[serde(rename = "VERTICAL_SCROLLING")]
393 VerticalScrolling,
394 #[serde(rename = "HORIZONTAL_AND_VERTICAL_SCROLLING")]
395 HorizontalAndVerticalScrolling,
396 #[serde(rename = "NONE")]
397 None,
398}
399
400impl Default for OverflowDirection {
401 fn default() -> OverflowDirection {
402 Self::HorizontalScrolling
403 }
404}
405#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
407pub enum LayoutMode {
408 #[serde(rename = "NONE")]
409 None,
410 #[serde(rename = "HORIZONTAL")]
411 Horizontal,
412 #[serde(rename = "VERTICAL")]
413 Vertical,
414}
415
416impl Default for LayoutMode {
417 fn default() -> LayoutMode {
418 Self::None
419 }
420}
421#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
423pub enum PrimaryAxisSizingMode {
424 #[serde(rename = "FIXED")]
425 Fixed,
426 #[serde(rename = "AUTO")]
427 Auto,
428}
429
430impl Default for PrimaryAxisSizingMode {
431 fn default() -> PrimaryAxisSizingMode {
432 Self::Fixed
433 }
434}
435#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
437pub enum CounterAxisSizingMode {
438 #[serde(rename = "FIXED")]
439 Fixed,
440 #[serde(rename = "AUTO")]
441 Auto,
442}
443
444impl Default for CounterAxisSizingMode {
445 fn default() -> CounterAxisSizingMode {
446 Self::Fixed
447 }
448}
449#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
451pub enum PrimaryAxisAlignItems {
452 #[serde(rename = "MIN")]
453 Min,
454 #[serde(rename = "CENTER")]
455 Center,
456 #[serde(rename = "MAX")]
457 Max,
458 #[serde(rename = "SPACE_BETWEEN")]
459 SpaceBetween,
460}
461
462impl Default for PrimaryAxisAlignItems {
463 fn default() -> PrimaryAxisAlignItems {
464 Self::Min
465 }
466}
467#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
469pub enum CounterAxisAlignItems {
470 #[serde(rename = "MIN")]
471 Min,
472 #[serde(rename = "CENTER")]
473 Center,
474 #[serde(rename = "MAX")]
475 Max,
476 #[serde(rename = "BASELINE")]
477 Baseline,
478}
479
480impl Default for CounterAxisAlignItems {
481 fn default() -> CounterAxisAlignItems {
482 Self::Min
483 }
484}
485#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
487pub enum LayoutWrap {
488 #[serde(rename = "NO_WRAP")]
489 NoWrap,
490 #[serde(rename = "WRAP")]
491 Wrap,
492}
493
494impl Default for LayoutWrap {
495 fn default() -> LayoutWrap {
496 Self::NoWrap
497 }
498}
499#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
501pub enum CounterAxisAlignContent {
502 #[serde(rename = "AUTO")]
503 Auto,
504 #[serde(rename = "SPACE_BETWEEN")]
505 SpaceBetween,
506}
507
508impl Default for CounterAxisAlignContent {
509 fn default() -> CounterAxisAlignContent {
510 Self::Auto
511 }
512}
513#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
515pub enum StrokeAlign {
516 #[serde(rename = "INSIDE")]
517 Inside,
518 #[serde(rename = "OUTSIDE")]
519 Outside,
520 #[serde(rename = "CENTER")]
521 Center,
522}
523
524impl Default for StrokeAlign {
525 fn default() -> StrokeAlign {
526 Self::Inside
527 }
528}
529#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
531pub enum StrokeJoin {
532 #[serde(rename = "MITER")]
533 Miter,
534 #[serde(rename = "BEVEL")]
535 Bevel,
536 #[serde(rename = "ROUND")]
537 Round,
538}
539
540impl Default for StrokeJoin {
541 fn default() -> StrokeJoin {
542 Self::Miter
543 }
544}
545#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
547pub enum StrokeCap {
548 #[serde(rename = "NONE")]
549 None,
550 #[serde(rename = "ROUND")]
551 Round,
552 #[serde(rename = "SQUARE")]
553 Square,
554 #[serde(rename = "LINE_ARROW")]
555 LineArrow,
556 #[serde(rename = "TRIANGLE_ARROW")]
557 TriangleArrow,
558 #[serde(rename = "DIAMOND_FILLED")]
559 DiamondFilled,
560 #[serde(rename = "CIRCLE_FILLED")]
561 CircleFilled,
562 #[serde(rename = "TRIANGLE_FILLED")]
563 TriangleFilled,
564 #[serde(rename = "WASHI_TAPE_1")]
565 WashiTape1,
566 #[serde(rename = "WASHI_TAPE_2")]
567 WashiTape2,
568 #[serde(rename = "WASHI_TAPE_3")]
569 WashiTape3,
570 #[serde(rename = "WASHI_TAPE_4")]
571 WashiTape4,
572 #[serde(rename = "WASHI_TAPE_5")]
573 WashiTape5,
574 #[serde(rename = "WASHI_TAPE_6")]
575 WashiTape6,
576}
577
578impl Default for StrokeCap {
579 fn default() -> StrokeCap {
580 Self::None
581 }
582}
583#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
585pub enum MaskType {
586 #[serde(rename = "ALPHA")]
587 Alpha,
588 #[serde(rename = "VECTOR")]
589 Vector,
590 #[serde(rename = "LUMINANCE")]
591 Luminance,
592}
593
594impl Default for MaskType {
595 fn default() -> MaskType {
596 Self::Alpha
597 }
598}
599