1use crate::chunk_discovery::{ChunkDiscovery, discover_chunks};
2use crate::error::WmoError;
3use crate::file_type::{WmoFileType, detect_file_type};
4use crate::group_parser::{WmoGroup, parse_group_file};
5use crate::root_parser::{WmoRoot, parse_root_file};
6use std::io::{Read, Seek, SeekFrom};
7
8#[derive(Debug, Clone)]
10pub enum ParsedWmo {
11 Root(WmoRoot),
13 Group(WmoGroup),
15}
16
17impl ParsedWmo {
18 pub fn file_type(&self) -> WmoFileType {
20 match self {
21 ParsedWmo::Root(_) => WmoFileType::Root,
22 ParsedWmo::Group(_) => WmoFileType::Group,
23 }
24 }
25
26 pub fn version(&self) -> u32 {
28 match self {
29 ParsedWmo::Root(r) => r.version,
30 ParsedWmo::Group(g) => g.version,
31 }
32 }
33}
34
35#[derive(Debug, Clone)]
37pub struct ParseResult {
38 pub wmo: ParsedWmo,
40 pub discovery: ChunkDiscovery,
42}
43
44impl ParseResult {
45 pub fn metadata(&self) -> Option<&ChunkDiscovery> {
47 Some(&self.discovery)
48 }
49}
50
51pub fn parse_wmo<R: Read + Seek>(reader: &mut R) -> Result<ParsedWmo, WmoError> {
81 let discovery = discover_chunks(reader).map_err(|e| {
83 WmoError::Io(std::io::Error::new(
84 std::io::ErrorKind::InvalidData,
85 format!("Failed to discover chunks: {}", e),
86 ))
87 })?;
88
89 let file_type = detect_file_type(&discovery);
91
92 reader.seek(SeekFrom::Start(0))?;
94
95 match file_type {
97 WmoFileType::Root => {
98 let root = parse_root_file(reader, discovery)
99 .map_err(|e| WmoError::InvalidFormat(format!("Failed to parse root: {}", e)))?;
100 Ok(ParsedWmo::Root(root))
101 }
102 WmoFileType::Group => {
103 let group = parse_group_file(reader, discovery)
104 .map_err(|e| WmoError::InvalidFormat(format!("Failed to parse group: {}", e)))?;
105 Ok(ParsedWmo::Group(group))
106 }
107 }
108}
109
110pub fn parse_wmo_with_metadata<R: Read + Seek>(reader: &mut R) -> Result<ParseResult, WmoError> {
114 let discovery = discover_chunks(reader).map_err(|e| {
116 WmoError::Io(std::io::Error::new(
117 std::io::ErrorKind::InvalidData,
118 format!("Failed to discover chunks: {}", e),
119 ))
120 })?;
121
122 let discovery_clone = discovery.clone();
124
125 let file_type = detect_file_type(&discovery);
127
128 reader.seek(SeekFrom::Start(0))?;
130
131 let wmo = match file_type {
133 WmoFileType::Root => {
134 let root = parse_root_file(reader, discovery)
135 .map_err(|e| WmoError::InvalidFormat(format!("Failed to parse root: {}", e)))?;
136 ParsedWmo::Root(root)
137 }
138 WmoFileType::Group => {
139 let group = parse_group_file(reader, discovery)
140 .map_err(|e| WmoError::InvalidFormat(format!("Failed to parse group: {}", e)))?;
141 ParsedWmo::Group(group)
142 }
143 };
144
145 Ok(ParseResult {
146 wmo,
147 discovery: discovery_clone,
148 })
149}
150
151pub fn discover_wmo_chunks<R: Read + Seek>(reader: &mut R) -> Result<ChunkDiscovery, WmoError> {
155 discover_chunks(reader).map_err(|e| {
156 WmoError::Io(std::io::Error::new(
157 std::io::ErrorKind::InvalidData,
158 format!("Failed to discover chunks: {}", e),
159 ))
160 })
161}