implement more CLI interface and utility functions
This commit is contained in:
parent
6030fc29ce
commit
e5919850fd
1 changed files with 56 additions and 24 deletions
76
src/main.rs
76
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<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");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue