use std::collections::BTreeMap;
use crate::Result;
use crate::player::{ObjRef, Player};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ObjectEntry {
pub object: ObjRef,
pub class_id: i32,
pub class: Option<String>,
pub name: Option<String>,
pub size: u32,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct Listing {
pub entries: Vec<ObjectEntry>,
pub unnamed: BTreeMap<String, u64>,
}
pub fn list(player: &Player, classes: Option<&[&str]>) -> Result<Listing> {
let mut listing = Listing::default();
for (file, f) in &player.files {
for o in &f.objects {
let object = ObjRef {
file: file.clone(),
path_id: o.path_id,
};
let class = player.class_name(&object).map(str::to_owned);
if let Some(wanted) = classes
&& !class.as_deref().is_some_and(|c| wanted.contains(&c))
{
continue;
}
let name = match class.as_deref() {
None => {
crate::bump(
&mut listing.unnamed,
"class unknown to the type tree package".into(),
);
None
}
Some(_) => match player.field(&object, "m_Name") {
Ok(Some(v)) => v.as_str().map(str::to_owned),
Ok(None) => {
crate::bump(&mut listing.unnamed, "class has no m_Name".into());
None
}
Err(e) => {
crate::bump(&mut listing.unnamed, e.to_string());
None
}
},
};
listing.entries.push(ObjectEntry {
object,
class_id: o.class_id,
class,
name,
size: o.size,
});
}
}
Ok(listing)
}