1use crate::{datatype::CompositeValue, element::Orient};
2use charming_macros::CharmingSetters;
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Clone, Copy)]
6#[serde(rename_all = "snake_case")]
7pub enum SaveAsImageType {
8 Png,
9 Jpg,
10 Svg,
11}
12
13#[serde_with::apply(
14 Option => #[serde(skip_serializing_if = "Option::is_none")],
15 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
16)]
17#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
18#[serde(rename_all = "camelCase")]
19pub struct SaveAsImage {
20 show: Option<bool>,
21 #[serde(rename = "type")]
22 type_: Option<SaveAsImageType>,
23 name: Option<String>,
24 background_color: Option<String>,
25}
26
27#[serde_with::apply(
28 Option => #[serde(skip_serializing_if = "Option::is_none")],
29 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
30)]
31#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
32#[serde(rename_all = "camelCase")]
33pub struct Restore {
34 show: Option<bool>,
35 title: Option<String>,
36}
37
38#[serde_with::apply(
39 Option => #[serde(skip_serializing_if = "Option::is_none")],
40 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
41)]
42#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
43#[serde(rename_all = "camelCase")]
44pub struct DataView {
45 show: Option<bool>,
46 title: Option<String>,
47 read_only: Option<bool>,
48}
49
50#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Clone, Copy)]
51#[serde(rename_all = "snake_case")]
52pub enum MagicTypeType {
53 Line,
55 Bar,
57 Stack,
59}
60
61impl From<&str> for MagicTypeType {
62 fn from(s: &str) -> Self {
63 match s {
64 "line" => Self::Line,
65 "bar" => Self::Bar,
66 "stack" => Self::Stack,
67 _ => panic!("Invalid magic type type: {s}"),
68 }
69 }
70}
71
72#[serde_with::apply(
73 Option => #[serde(skip_serializing_if = "Option::is_none")],
74 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
75)]
76#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
77#[serde(rename_all = "camelCase")]
78pub struct MagicType {
79 type_: Option<Vec<MagicTypeType>>,
80 title: Option<String>,
81}
82
83#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Clone, Copy)]
84#[serde(rename_all = "camelCase")]
85pub enum BrushType {
86 Rect,
87 Polygon,
88 LineX,
89 LineY,
90 Keep,
91 Clear,
92}
93
94#[serde_with::apply(
95 Option => #[serde(skip_serializing_if = "Option::is_none")],
96 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
97)]
98#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
99#[serde(rename_all = "camelCase")]
100pub struct Brush {
101 #[serde(rename = "type")]
102 #[charming_set_vec]
103 type_: Vec<BrushType>,
104}
105
106#[serde_with::apply(
107 Option => #[serde(skip_serializing_if = "Option::is_none")],
108 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
109)]
110#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
111#[serde(rename_all = "camelCase")]
112pub struct ToolboxDataZoom {
113 y_axis_index: Option<CompositeValue>,
114}
115
116#[serde_with::apply(
117 Option => #[serde(skip_serializing_if = "Option::is_none")],
118 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
119)]
120#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
121#[serde(rename_all = "camelCase")]
122pub struct Feature {
123 save_as_image: Option<SaveAsImage>,
124 restore: Option<Restore>,
125 data_view: Option<DataView>,
126 magic_type: Option<MagicType>,
127 data_zoom: Option<ToolboxDataZoom>,
128 brush: Option<Brush>,
129}
130
131#[serde_with::apply(
132 Option => #[serde(skip_serializing_if = "Option::is_none")],
133 Vec => #[serde(default, skip_serializing_if = "Vec::is_empty")]
134)]
135#[derive(Serialize, Deserialize, CharmingSetters, Debug, PartialEq, PartialOrd, Clone)]
136#[serde(rename_all = "camelCase")]
137pub struct Toolbox {
138 show: Option<bool>,
139 feature: Option<Feature>,
140 orient: Option<Orient>,
141 left: Option<CompositeValue>,
142 top: Option<CompositeValue>,
143 right: Option<CompositeValue>,
144 bottom: Option<CompositeValue>,
145}
146
147impl Toolbox {
148 pub fn save_as_image_type(&self) -> Option<&SaveAsImageType> {
149 self.feature
150 .as_ref()
151 .and_then(|f| f.save_as_image.as_ref())
152 .and_then(|s| s.type_.as_ref())
153 }
154}