diff --git a/src/main.rs b/src/main.rs index 9f88b16..69b78d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use std::path::Path; mod fot; use fot::attributes::*; +use fot::entity::Entity; use fot::entitylist::EntityList; use fot::save::Save; @@ -39,13 +40,17 @@ enum Commands { ListEntities, /// Find entities, kv = key1=value,key2=value2 FindEntities { - kv: String, + find: String, + }, + ListValues { + ids: Option, + find: Option, }, } -fn list_entities(entlist: &EntityList) { +fn log_entities<'a>(entlist: &EntityList, iter: impl IntoIterator) { let mut bf = BufWriter::new(stdout().lock()); - for (id, ent) in entlist { + for (id, ent) in iter { let type_name = if ent.type_idx != 0xFFFF { entlist.get_type_name(ent.type_idx).str.as_str() } else { @@ -55,21 +60,28 @@ fn list_entities(entlist: &EntityList) { } } -fn find_entities(entlist: &EntityList, line: String) { - let kv = line - .split(",") +fn parse_kv(kv: &String) -> Vec<(&str, &str)> { + kv.split(",") .map(|kv| kv.split_once("=")) - .collect::>>() - .unwrap(); - - let mut bf = BufWriter::new(stdout().lock()); - for (id, ent) in entlist { - let type_name = if ent.type_idx != 0xFFFF { - entlist.get_type_name(ent.type_idx).str.as_str() - } else { - "" - }; + .collect::>>() + .unwrap() +} +fn from_ids(entlist: &EntityList, line: String) -> HashMap { + line.split(",") + .map(|id| { + ( + id.parse::().expect("parse id"), + entlist.get_entity(id.parse().expect("parse id")), + ) + }) + .collect::>() +} + +fn find_entities(entlist: &EntityList, line: String) -> HashMap { + let kv = parse_kv(&line); + let mut entities: HashMap = HashMap::new(); + for (id, ent) in entlist { let esh = match &ent.esh { Some(esh) => esh, None => continue, @@ -77,14 +89,30 @@ fn find_entities(entlist: &EntityList, line: String) { for (name, value) in &esh.props { let key = name.str.as_str(); - if kv.contains_key(key) { - let svalue = value.to_string(); - if svalue == kv[key] { - write!(bf, "{}\t{}\n", id, type_name).expect("failed to write stdout"); + let svalue = value.to_string(); + for (k, v) in &kv { + if key == *k && svalue == *v { + entities.insert(id, ent); } } } } + + entities +} + +fn get_entities( + entlist: &EntityList, + ids: Option, + find: Option, +) -> HashMap { + if let Some(ids) = ids { + from_ids(entlist, ids) + } else if let Some(find) = find { + find_entities(entlist, find) + } else { + panic!("No entity selector provided!") + } } fn do_save(cli: Cli) { @@ -92,13 +120,17 @@ fn do_save(cli: Cli) { Ok(save) => save, Err(fe) => panic!("{}", fe), }; + let entlist = &save.world.entlist; match cli.command { Commands::ListEntities => { - list_entities(&save.world.entlist); - }, - Commands::FindEntities { kv } => { - find_entities(&save.world.entlist, kv); + log_entities(entlist, entlist.into_iter()); + } + Commands::FindEntities { find } => { + log_entities(entlist, find_entities(entlist, find)); + } + Commands::ListValues { ids, find } => { + let entities = get_entities(entlist, ids, find); } } }