use crate::chunk_discovery::{ChunkDiscovery, discover_chunks};
use crate::error::WmoError;
use crate::file_type::{WmoFileType, detect_file_type};
use crate::group_parser::{WmoGroup, parse_group_file};
use crate::root_parser::{WmoRoot, parse_root_file};
use std::io::{Read, Seek, SeekFrom};
#[derive(Debug, Clone)]
pub enum ParsedWmo {
Root(WmoRoot),
Group(WmoGroup),
}
impl ParsedWmo {
pub fn file_type(&self) -> WmoFileType {
match self {
ParsedWmo::Root(_) => WmoFileType::Root,
ParsedWmo::Group(_) => WmoFileType::Group,
}
}
pub fn version(&self) -> u32 {
match self {
ParsedWmo::Root(r) => r.version,
ParsedWmo::Group(g) => g.version,
}
}
}
#[derive(Debug, Clone)]
pub struct ParseResult {
pub wmo: ParsedWmo,
pub discovery: ChunkDiscovery,
}
impl ParseResult {
pub fn metadata(&self) -> Option<&ChunkDiscovery> {
Some(&self.discovery)
}
}
pub fn parse_wmo<R: Read + Seek>(reader: &mut R) -> Result<ParsedWmo, WmoError> {
let discovery = discover_chunks(reader).map_err(|e| {
WmoError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Failed to discover chunks: {}", e),
))
})?;
let file_type = detect_file_type(&discovery);
reader.seek(SeekFrom::Start(0))?;
match file_type {
WmoFileType::Root => {
let root = parse_root_file(reader, discovery)
.map_err(|e| WmoError::InvalidFormat(format!("Failed to parse root: {}", e)))?;
Ok(ParsedWmo::Root(root))
}
WmoFileType::Group => {
let group = parse_group_file(reader, discovery)
.map_err(|e| WmoError::InvalidFormat(format!("Failed to parse group: {}", e)))?;
Ok(ParsedWmo::Group(group))
}
}
}
pub fn parse_wmo_with_metadata<R: Read + Seek>(reader: &mut R) -> Result<ParseResult, WmoError> {
let discovery = discover_chunks(reader).map_err(|e| {
WmoError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Failed to discover chunks: {}", e),
))
})?;
let discovery_clone = discovery.clone();
let file_type = detect_file_type(&discovery);
reader.seek(SeekFrom::Start(0))?;
let wmo = match file_type {
WmoFileType::Root => {
let root = parse_root_file(reader, discovery)
.map_err(|e| WmoError::InvalidFormat(format!("Failed to parse root: {}", e)))?;
ParsedWmo::Root(root)
}
WmoFileType::Group => {
let group = parse_group_file(reader, discovery)
.map_err(|e| WmoError::InvalidFormat(format!("Failed to parse group: {}", e)))?;
ParsedWmo::Group(group)
}
};
Ok(ParseResult {
wmo,
discovery: discovery_clone,
})
}
pub fn discover_wmo_chunks<R: Read + Seek>(reader: &mut R) -> Result<ChunkDiscovery, WmoError> {
discover_chunks(reader).map_err(|e| {
WmoError::Io(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Failed to discover chunks: {}", e),
))
})
}