use indexmap::IndexMap;
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use crate::utils::{get_key_ref, take_and_parse_key, take_key_or_default};
use crate::{
VmfBlock, VmfSerializable,
errors::{VmfError, VmfResult},
utils::To01String,
};
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Editor {
pub color: String,
#[cfg_attr(
feature = "serialization",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub visgroup_id: Option<i32>,
#[cfg_attr(
feature = "serialization",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub group_id: Option<i32>,
pub visgroup_shown: bool,
pub visgroup_auto_shown: bool,
#[cfg_attr(
feature = "serialization",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub comments: Option<String>,
#[cfg_attr(
feature = "serialization",
serde(default, skip_serializing_if = "Option::is_none")
)]
pub logical_pos: Option<String>,
}
impl Default for Editor {
fn default() -> Self {
Self {
color: "255 255 255".to_string(),
visgroup_id: None,
group_id: None,
visgroup_shown: true,
visgroup_auto_shown: true,
comments: None,
logical_pos: None,
}
}
}
impl TryFrom<VmfBlock> for Editor {
type Error = VmfError;
fn try_from(mut block: VmfBlock) -> VmfResult<Self> {
let kv = &mut block.key_values;
Ok(Self {
color: take_key_or_default(kv, "color", "255 255 255".to_string()),
visgroup_id: take_and_parse_key::<i32>(kv, "visgroupid").ok(),
group_id: take_and_parse_key::<i32>(kv, "groupid").ok(),
visgroup_shown: get_key_ref(kv, "visgroupshown").is_ok_and(|v| v == "1"),
visgroup_auto_shown: get_key_ref(kv, "visgroupautoshown").is_ok_and(|v| v == "1"),
comments: kv.swap_remove("comments"),
logical_pos: kv.swap_remove("logicalpos"),
})
}
}
impl From<Editor> for VmfBlock {
fn from(val: Editor) -> VmfBlock {
let mut key_values = IndexMap::new();
key_values.insert("color".to_string(), val.color);
if let Some(visgroup_id) = val.visgroup_id {
key_values.insert("visgroupid".to_string(), visgroup_id.to_string());
}
if let Some(group_id) = val.group_id {
key_values.insert("groupid".to_string(), group_id.to_string());
}
key_values.insert(
"visgroupshown".to_string(),
val.visgroup_shown.to_01_string(),
);
key_values.insert(
"visgroupautoshown".to_string(),
val.visgroup_auto_shown.to_01_string(),
);
if let Some(comments) = val.comments {
key_values.insert("comments".to_string(), comments);
}
if let Some(logical_pos) = val.logical_pos {
key_values.insert("logicalpos".to_string(), logical_pos);
}
VmfBlock {
name: "editor".to_string(),
key_values,
blocks: Vec::new(),
}
}
}
impl VmfSerializable for Editor {
fn to_vmf_string(&self, indent_level: usize) -> String {
let indent = "\t".repeat(indent_level);
let mut output = String::with_capacity(128);
output.push_str(&format!("{0}editor\n{0}{{\n", indent));
output.push_str(&format!("{}\t\"color\" \"{}\"\n", indent, self.color));
if let Some(visgroup_id) = self.visgroup_id {
output.push_str(&format!("{}\t\"visgroupid\" \"{}\"\n", indent, visgroup_id));
}
if let Some(group_id) = self.group_id {
output.push_str(&format!("{}\t\"groupid\" \"{}\"\n", indent, group_id));
}
output.push_str(&format!(
"{}\t\"visgroupshown\" \"{}\"\n",
indent,
self.visgroup_shown.to_01_string()
));
output.push_str(&format!(
"{}\t\"visgroupautoshown\" \"{}\"\n",
indent,
self.visgroup_auto_shown.to_01_string()
));
if let Some(comments) = &self.comments {
output.push_str(&format!("{}\t\"comments\" \"{}\"\n", indent, comments));
}
if let Some(logical_pos) = &self.logical_pos {
output.push_str(&format!("{}\t\"logicalpos\" \"{}\"\n", indent, logical_pos));
}
output.push_str(&format!("{}}}\n", indent));
output
}
}