1pub mod anm;
3pub mod bsi;
5pub mod cdrom;
6pub mod cht;
8pub mod combat_ini;
10pub mod cpf;
12pub mod fnt;
14pub mod fnt_export;
16pub mod fnt_ttf;
18pub mod fog_ini;
20pub mod glide_splash;
22pub mod glide_splash_dll;
24pub mod gxa;
26pub mod indexed_image;
28mod ini;
29pub mod item_ini;
31pub mod keys_ini;
33pub mod lbm;
35pub mod menu_ini;
36pub mod menu_movies;
37pub mod menu_settings;
38pub mod model3d;
40pub mod palette;
42pub mod palette_export;
44pub mod pcx;
46pub mod player_ini;
47pub mod png;
49pub mod pvo;
51pub mod registry;
53pub mod rgm;
55pub mod rob;
57pub mod rtx;
59pub mod savegame;
61pub mod sfx;
63pub mod smacker;
64pub mod software_texture;
65pub mod soup_def;
66pub mod soup_ini;
67pub mod surface_ini;
68pub mod system_ini;
70pub mod wld;
72pub mod world_ini;
74
75use std::path::Path;
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, clap::ValueEnum)]
78pub enum FileType {
80 Texture,
81 Shade,
82 Haze,
83 Bsi, Cht, Col, Model3d, Model3dc, Rob, Rgm, Pvo, Wld, Fnt, Gxa, Sfx, Rtx, Pcx, Lbm, Anm, }
100
101const ALL_FILE_TYPES: [FileType; 19] = [
102 FileType::Texture,
103 FileType::Shade,
104 FileType::Haze,
105 FileType::Bsi,
106 FileType::Cht,
107 FileType::Col,
108 FileType::Model3d,
109 FileType::Model3dc,
110 FileType::Rob,
111 FileType::Rgm,
112 FileType::Pvo,
113 FileType::Wld,
114 FileType::Fnt,
115 FileType::Gxa,
116 FileType::Sfx,
117 FileType::Rtx,
118 FileType::Pcx,
119 FileType::Lbm,
120 FileType::Anm,
121];
122
123impl FileType {
124 #[must_use]
125 pub const fn all() -> &'static [Self] {
126 &ALL_FILE_TYPES
127 }
128
129 #[must_use]
130 pub const fn display_name(self) -> &'static str {
131 match self {
132 Self::Texture => "Software Texture",
133 Self::Shade => "Shade Lookup",
134 Self::Haze => "Haze Lookup",
135 Self::Bsi => "Texture BSI",
136 Self::Cht => "Cheat States",
137 Self::Col => "Palette",
138 Self::Model3d => "Model",
139 Self::Model3dc => "Animated Model",
140 Self::Rob => "ROB World",
141 Self::Rgm => "Map Data",
142 Self::Pvo => "PVO Data",
143 Self::Wld => "World Geometry",
144 Self::Fnt => "Font",
145 Self::Gxa => "GXA Bitmap",
146 Self::Sfx => "Sound Effects",
147 Self::Rtx => "Dialogue Audio",
148 Self::Pcx => "PCX Image",
149 Self::Lbm => "IFF Bitmap",
150 Self::Anm => "Deluxe Paint Animation",
151 }
152 }
153
154 #[must_use]
155 pub const fn extensions(self) -> &'static [&'static str] {
156 match self {
157 Self::Texture => &[".texture"],
158 Self::Shade => &[".shade"],
159 Self::Haze => &[".haze"],
160 Self::Bsi => &[".bsi"],
161 Self::Cht => &[".cht"],
162 Self::Col => &[".col"],
163 Self::Model3d => &[".3d"],
164 Self::Model3dc => &[".3dc"],
165 Self::Rob => &[".rob"],
166 Self::Rgm => &[".rgm"],
167 Self::Pvo => &[".pvo"],
168 Self::Wld => &[".wld"],
169 Self::Fnt => &[".fnt"],
170 Self::Gxa => &[".gxa"],
171 Self::Sfx => &[".sfx"],
172 Self::Rtx => &[".rtx"],
173 Self::Pcx => &[".pcx"],
174 Self::Lbm => &[".lbm"],
175 Self::Anm => &[".anm"],
176 }
177 }
178
179 #[must_use]
181 pub fn from_extension(ext: &str) -> Option<Self> {
182 let lower = ext.to_ascii_lowercase();
183 Self::all().iter().copied().find(|ft| {
184 ft.extensions()
185 .iter()
186 .any(|e| e.trim_start_matches('.') == lower)
187 })
188 }
189
190 pub fn from_path<P: AsRef<Path>>(path: P) -> Option<Self> {
192 let p = path.as_ref();
193 if let Some(ext) = p.extension().and_then(|e| e.to_str())
194 && let Some(ft) = Self::from_extension(ext)
195 {
196 return Some(ft);
197 }
198 let stem = p.file_stem()?.to_str()?.to_ascii_uppercase();
199 match stem.as_str() {
200 "TEXBSI" => Some(Self::Bsi),
201 "TEXTURE" => Some(Self::Texture),
202 "SHADE" => Some(Self::Shade),
203 "HAZE" => Some(Self::Haze),
204 _ => None,
205 }
206 }
207}
208
209impl std::str::FromStr for FileType {
210 type Err = String;
211
212 fn from_str(s: &str) -> Result<Self, Self::Err> {
213 Self::from_extension(s.trim()).ok_or_else(|| {
214 let supported = Self::all()
215 .iter()
216 .flat_map(|ft| {
217 ft.extensions()
218 .iter()
219 .map(|ext| ext.trim_start_matches('.').to_string())
220 })
221 .collect::<Vec<_>>()
222 .join(", ");
223 format!("Unknown file type: {s}. Supported types: {supported}")
224 })
225 }
226}
227
228pub mod world_lighting;