1use indexmap::IndexMap;
4use serde::{Deserialize, Serialize};
5
6use crate::utils::{get_key, parse_hs_key};
7use crate::{
8 errors::{VmfError, VmfResult},
9 utils::To01String,
10 VmfBlock, VmfSerializable,
11};
12
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
15pub struct Editor {
16 pub color: String,
18 #[serde(default, skip_serializing_if = "Option::is_none")]
20 pub visgroup_id: Option<i32>,
21 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub group_id: Option<i32>,
24 pub visgroup_shown: bool,
26 pub visgroup_auto_shown: bool,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub comments: Option<String>,
31 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub logical_pos: Option<String>,
34}
35
36impl Default for Editor {
37 fn default() -> Self {
38 Self {
39 color: "255 255 255".to_string(),
40 visgroup_id: None,
41 group_id: None,
42 visgroup_shown: true,
43 visgroup_auto_shown: true,
44 comments: None,
45 logical_pos: None,
46 }
47 }
48}
49
50impl TryFrom<VmfBlock> for Editor {
51 type Error = VmfError;
52
53 fn try_from(block: VmfBlock) -> VmfResult<Self> {
54 let kv = &block.key_values;
55
56 Ok(Self {
57 color: get_key!(kv, "color", "255 255 255".to_string()).to_owned(),
58 visgroup_id: parse_hs_key!(kv, "visgroupid", i32).ok(),
59 group_id: parse_hs_key!(kv, "groupid", i32).ok(),
60 visgroup_shown: get_key!(kv, "visgroupshown", "_".to_string()) == "1",
61 visgroup_auto_shown: get_key!(kv, "visgroupautoshown", "_".to_string()) == "1",
62 comments: kv.get("comments").cloned(),
63 logical_pos: kv.get("logicalpos").cloned(),
64 })
65 }
66}
67
68impl From<Editor> for VmfBlock {
69 fn from(val: Editor) -> VmfBlock {
70 let mut key_values = IndexMap::new();
71 key_values.insert("color".to_string(), val.color);
72 if let Some(visgroup_id) = val.visgroup_id {
73 key_values.insert("visgroupid".to_string(), visgroup_id.to_string());
74 }
75 if let Some(group_id) = val.group_id {
76 key_values.insert("groupid".to_string(), group_id.to_string());
77 }
78 key_values.insert(
79 "visgroupshown".to_string(),
80 val.visgroup_shown.to_01_string(),
81 );
82 key_values.insert(
83 "visgroupautoshown".to_string(),
84 val.visgroup_auto_shown.to_01_string(),
85 );
86 if let Some(comments) = val.comments {
87 key_values.insert("comments".to_string(), comments);
88 }
89 if let Some(logical_pos) = val.logical_pos {
90 key_values.insert("logicalpos".to_string(), logical_pos);
91 }
92
93 VmfBlock {
94 name: "editor".to_string(),
95 key_values,
96 blocks: Vec::new(),
97 }
98 }
99}
100
101impl VmfSerializable for Editor {
102 fn to_vmf_string(&self, indent_level: usize) -> String {
103 let indent = "\t".repeat(indent_level);
104 let mut output = String::with_capacity(128);
105
106 output.push_str(&format!("{0}editor\n{0}{{\n", indent));
107 output.push_str(&format!("{}\t\"color\" \"{}\"\n", indent, self.color));
108 if let Some(visgroup_id) = self.visgroup_id {
109 output.push_str(&format!("{}\t\"visgroupid\" \"{}\"\n", indent, visgroup_id));
110 }
111 if let Some(group_id) = self.group_id {
112 output.push_str(&format!("{}\t\"groupid\" \"{}\"\n", indent, group_id));
113 }
114 output.push_str(&format!(
115 "{}\t\"visgroupshown\" \"{}\"\n",
116 indent,
117 self.visgroup_shown.to_01_string()
118 ));
119 output.push_str(&format!(
120 "{}\t\"visgroupautoshown\" \"{}\"\n",
121 indent,
122 self.visgroup_auto_shown.to_01_string()
123 ));
124 if let Some(comments) = &self.comments {
125 output.push_str(&format!("{}\t\"comments\" \"{}\"\n", indent, comments));
126 }
127 if let Some(logical_pos) = &self.logical_pos {
128 output.push_str(&format!("{}\t\"logicalpos\" \"{}\"\n", indent, logical_pos));
129 }
130
131 output.push_str(&format!("{}}}\n", indent));
132 output
133 }
134}