openmw_config/config/
encodingsetting.rs1use std::fmt;
5
6use crate::config::error::bail_config;
7use crate::{ConfigError, GameSetting, GameSettingMeta};
8
9#[derive(Debug, Copy, Clone, Eq, PartialEq)]
14#[non_exhaustive]
15pub enum EncodingType {
16 WIN1250,
18 WIN1251,
20 WIN1252,
22}
23
24impl std::fmt::Display for EncodingType {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 let value = match self {
27 EncodingType::WIN1250 => "win1250",
28 EncodingType::WIN1251 => "win1251",
29 EncodingType::WIN1252 => "win1252",
30 };
31
32 write!(f, "{value}")
33 }
34}
35
36#[derive(Debug, Clone)]
41pub struct EncodingSetting {
42 meta: GameSettingMeta,
43 encoding: EncodingType,
44}
45
46impl EncodingSetting {
47 #[must_use]
49 pub fn value(&self) -> EncodingType {
50 self.encoding
51 }
52
53 #[must_use]
55 pub fn meta(&self) -> &GameSettingMeta {
56 &self.meta
57 }
58}
59
60impl PartialEq for EncodingSetting {
61 fn eq(&self, other: &Self) -> bool {
62 self.encoding == other.encoding
63 }
64}
65
66impl GameSetting for EncodingSetting {
67 fn meta(&self) -> &GameSettingMeta {
68 &self.meta
69 }
70
71 fn meta_mut(&mut self) -> &mut GameSettingMeta {
72 &mut self.meta
73 }
74}
75
76impl fmt::Display for EncodingSetting {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 write!(f, "{}encoding={}", self.meta.comment, self.encoding)
79 }
80}
81
82impl<P: AsRef<std::path::Path>> TryFrom<(String, P, &mut String)> for EncodingSetting {
83 type Error = ConfigError;
84
85 fn try_from(
86 (value, source_config, comment): (String, P, &mut String),
87 ) -> Result<Self, Self::Error> {
88 let source_config = source_config.as_ref().to_path_buf();
89
90 let encoding = match value.as_str() {
91 "win1250" => EncodingType::WIN1250,
92 "win1251" => EncodingType::WIN1251,
93 "win1252" => EncodingType::WIN1252,
94 _ => bail_config!(bad_encoding, value, source_config),
95 };
96
97 let meta = GameSettingMeta {
98 source_config,
99 comment: comment.to_owned(),
100 };
101 comment.clear();
102
103 Ok(EncodingSetting { meta, encoding })
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 use std::path::PathBuf;
111
112 fn dummy_path() -> PathBuf {
113 PathBuf::from("/tmp/test.cfg")
114 }
115
116 fn dummy_comment() -> String {
117 "#OpenMW-Config Test Suite\n\n\n\n#EncodingSetting\n\n\n\n".into()
118 }
119
120 #[test]
121 fn test_valid_encodings() {
122 let encodings = vec![
123 ("win1250", EncodingType::WIN1250),
124 ("win1251", EncodingType::WIN1251),
125 ("win1252", EncodingType::WIN1252),
126 ];
127
128 for (input, expected_variant) in encodings {
129 let setting =
130 EncodingSetting::try_from((input.to_string(), dummy_path(), &mut dummy_comment()))
131 .unwrap();
132
133 assert_eq!(setting.encoding, expected_variant);
134 }
135 }
136
137 #[test]
138 fn test_invalid_encoding() {
139 let err =
140 EncodingSetting::try_from(("utf8".to_string(), dummy_path(), &mut dummy_comment()));
141
142 assert!(matches!(err, Err(ConfigError::BadEncoding { .. })));
143 }
144
145 #[test]
146 fn test_empty_encoding_string() {
147 let err = EncodingSetting::try_from((String::new(), dummy_path(), &mut dummy_comment()));
148 assert!(matches!(err, Err(ConfigError::BadEncoding { .. })));
149 }
150
151 #[test]
152 fn test_source_path_preservation() {
153 let path = PathBuf::from("/some/path/to/config.cfg");
154 let setting = EncodingSetting::try_from((
155 "win1251".to_string(),
156 path.as_path(),
157 &mut dummy_comment(),
158 ))
159 .unwrap();
160
161 assert_eq!(setting.meta.source_config, path);
162 }
163
164 #[test]
165 fn test_display_trait_output() {
166 let setting = EncodingSetting::try_from((
167 "win1250".to_string(),
168 dummy_path().as_path(),
169 &mut dummy_comment(),
170 ))
171 .unwrap();
172
173 let rendered = setting.to_string();
174 assert_eq!(
175 rendered.trim(),
176 format!("{}encoding=win1250", dummy_comment())
177 );
178 }
179}