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;
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<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());
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::<Option<HashMap<&str, &str>>>()
.unwrap();
.collect::<Option<Vec<(&str, &str)>>>()
.unwrap()
}
let mut bf = BufWriter::new(stdout().lock());
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 type_name = if ent.type_idx != 0xFFFF {
entlist.get_type_name(ent.type_idx).str.as_str()
} else {
"<no type>"
};
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<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) {
@ -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);
}
}
}