implement more CLI interface and utility functions

This commit is contained in:
mykola2312 2023-09-10 19:04:24 +03:00
parent 6030fc29ce
commit e5919850fd

View file

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