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