Code cleanup

master
hheik 2025-05-09 15:40:41 +03:00
parent 70e1e9d747
commit 23e7ea5f06
4 changed files with 60 additions and 53 deletions

View File

@ -1,6 +1,7 @@
use parser::{SliceParseError, TagParseError};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use self::parser::{FilePosition, ParseError, ParseQuery}; use self::parser::{FilePosition, ParseError, SliceParse};
pub mod parser; pub mod parser;
@ -18,8 +19,13 @@ pub struct Tag {
} }
impl Tag { impl Tag {
fn parse_value<T: ParseQuery>(&self) -> Result<T, ParseError> { fn parse_value<T: SliceParse>(&self) -> Result<T, ParseError> {
T::parse(&self.values).map_err(|_| ParseError::ValueParseError(self.clone())) T::parse(&self.values).map_err(|err| {
ParseError::TagParseError(match err {
SliceParseError::ParseError => TagParseError::ParseError(self.clone()),
SliceParseError::MissingValue => TagParseError::MissingValue(self.clone()),
})
})
} }
} }

View File

@ -2,13 +2,13 @@ use std::{borrow::BorrowMut, io::Read, str::FromStr};
use crate::definitions::{CreatureDef, SiteDef, Tag, TopLevelTag}; use crate::definitions::{CreatureDef, SiteDef, Tag, TopLevelTag};
pub trait ParseQuery: Sized { pub trait SliceParse: Sized {
fn parse(values: &Vec<String>) -> Result<Self, ()>; fn parse(values: &[String]) -> Result<Self, SliceParseError>;
} }
trait Parseable: Sized + FromStr { trait Parseable: Sized + FromStr {
fn parse(string: &str) -> Result<Self, ()> { fn parse(string: &str) -> Option<Self> {
string.parse().map_err(|_| ()) string.parse().ok()
} }
} }
@ -25,22 +25,20 @@ impl Parseable for bool {}
macro_rules! parse_query_impl { macro_rules! parse_query_impl {
($t:ident) => { ($t:ident) => {
impl<$t: Parseable> ParseQuery for $t { impl<$t: Parseable> SliceParse for $t {
fn parse(values: &Vec<String>) -> Result<Self, ()> { fn parse(values: &[String]) -> Result<Self, SliceParseError> {
let mut iter = values.iter(); let mut iter = values.iter();
Ok( $t::parse(iter.next().ok_or(SliceParseError::MissingValue)?).ok_or(SliceParseError::ParseError)
$t::parse(iter.next().ok_or(())?)?
)
} }
} }
}; };
($x:ident, $($t:ident),+) => { ($x:ident, $($t:ident),+) => {
impl<$x: Parseable, $($t: Parseable),+> ParseQuery for ($x, $($t),+) { impl<$x: Parseable, $($t: Parseable),+> SliceParse for ($x, $($t),+) {
fn parse(values: &Vec<String>) -> Result<Self, ()> { fn parse(values: &[String]) -> Result<Self, SliceParseError> {
let mut iter = values.iter(); let mut iter = values.iter();
Ok(( Ok((
$x::parse(iter.next().ok_or(())?)?, $x::parse(iter.next().ok_or(SliceParseError::MissingValue)?).ok_or(SliceParseError::ParseError)?,
$($t::parse(iter.next().ok_or(())?)?,)+ $($t::parse(iter.next().ok_or(SliceParseError::MissingValue)?).ok_or(SliceParseError::ParseError)?,)+
)) ))
} }
} }
@ -68,11 +66,22 @@ impl Default for FilePosition {
pub enum ParseError { pub enum ParseError {
LexerError(LexerError), LexerError(LexerError),
SyntaxError(String), SyntaxError(String),
ValueParseError(Tag), TagParseError(TagParseError),
NoDefinitionsError, NoDefinitionsError,
UnexpectedError, UnexpectedError,
} }
pub enum SliceParseError {
MissingValue,
ParseError,
}
#[derive(Debug)]
pub enum TagParseError {
MissingValue(Tag),
ParseError(Tag),
}
#[derive(Debug)] #[derive(Debug)]
pub enum LexerError { pub enum LexerError {
Io(std::io::Error), Io(std::io::Error),
@ -138,9 +147,7 @@ impl DefinitionParser {
let mut tags = vec![]; let mut tags = vec![];
let mut tag_builder: Option<Tag> = None; let mut tag_builder: Option<Tag> = None;
let mut buffer = String::new(); let mut buffer = String::new();
source source.read_to_string(&mut buffer).map_err(LexerError::Io)?;
.read_to_string(&mut buffer)
.map_err(|err| LexerError::Io(err))?;
let mut file_position = FilePosition::default(); let mut file_position = FilePosition::default();
for c in buffer.chars() { for c in buffer.chars() {
if c == '\n' { if c == '\n' {

View File

@ -6,38 +6,32 @@ use sim::{Site, World};
pub mod definitions; pub mod definitions;
pub mod sim; pub mod sim;
const SAVE_FILE: &'static str = "world.bin"; const SAVE_FILE: &str = "world.bin";
fn main() { fn main() {
let mut parse_error_files = vec![]; let mut parse_error_files = vec![];
let mut site_definitions = HashMap::new(); let mut site_definitions = HashMap::new();
let mut creature_definitions = HashMap::new(); let mut creature_definitions = HashMap::new();
for entry in std::fs::read_dir(resources_path()).unwrap() { for entry in std::fs::read_dir(resources_path()).unwrap().flatten() {
match entry { if entry.file_name().to_string_lossy().ends_with(".def") {
Ok(entry) => { let source = BufReader::new(std::fs::File::open(entry.path()).unwrap());
if entry.file_name().to_string_lossy().ends_with(".def") { match DefinitionParser::parse(source) {
let source = BufReader::new(std::fs::File::open(entry.path()).unwrap()); Ok(defs) => {
match DefinitionParser::parse(source) { for def in defs.0 {
Ok(defs) => { if let Some(prev) = site_definitions.insert(def.id.clone(), def) {
for def in defs.0 { eprintln!("Duplicate site definition '{}'", prev.id);
if let Some(prev) = site_definitions.insert(def.id.clone(), def) {
eprintln!("Duplicate site definition '{}'", prev.id);
}
}
for def in defs.1 {
if let Some(prev) = creature_definitions.insert(def.id.clone(), def)
{
eprintln!("Duplicate site definition '{}'", prev.id);
}
}
} }
Err(err) => { }
parse_error_files.push((err, entry.path())); for def in defs.1 {
if let Some(prev) = creature_definitions.insert(def.id.clone(), def) {
eprintln!("Duplicate site definition '{}'", prev.id);
} }
} }
} }
Err(err) => {
parse_error_files.push((err, entry.path()));
}
} }
_ => (),
} }
} }
@ -53,7 +47,7 @@ fn main() {
Ok(data) => bincode::deserialize(&data).unwrap(), Ok(data) => bincode::deserialize(&data).unwrap(),
Err(_) => { Err(_) => {
let mut world = World::default(); let mut world = World::default();
let mut site = Site::from_def(&site_def); let mut site = Site::from_def(site_def);
site.populate_randomly(&creature_definitions.values().collect::<Vec<_>>()); site.populate_randomly(&creature_definitions.values().collect::<Vec<_>>());
world.sites.push(site); world.sites.push(site);
std::fs::write("world.bin", bincode::serialize(&world).unwrap()).unwrap(); std::fs::write("world.bin", bincode::serialize(&world).unwrap()).unwrap();
@ -68,7 +62,7 @@ fn main() {
let mut input = String::new(); let mut input = String::new();
loop { loop {
std::io::stdin().read_line(&mut input).unwrap(); std::io::stdin().read_line(&mut input).unwrap();
if vec!["q", "quit", "exit"] if ["q", "quit", "exit"]
.iter() .iter()
.any(|quit_cmd| input.trim() == *quit_cmd) .any(|quit_cmd| input.trim() == *quit_cmd)
{ {

View File

@ -160,13 +160,13 @@ impl Display for Site {
for creature in area.population.iter() { for creature in area.population.iter() {
write!(f, "\n\t\t{}", creature)?; write!(f, "\n\t\t{}", creature)?;
} }
if area.population.len() > 0 { if !area.population.is_empty() {
write!(f, "\n\t")?; write!(f, "\n\t")?;
} }
write!(f, "]")?; write!(f, "]")?;
} }
if !self.areas.is_empty() { if !self.areas.is_empty() {
write!(f, "\n")?; writeln!(f)?;
} }
write!(f, "]") write!(f, "]")
} }
@ -383,12 +383,12 @@ pub fn resolve_combat(combatants: &[Creature], max_rounds: u16) -> Option<Combat
let c2 = &combatants[index_2]; let c2 = &combatants[index_2];
let is_enemy = c1.definition.id != c2.definition.id; let is_enemy = c1.definition.id != c2.definition.id;
if is_enemy { if is_enemy {
if !participants.contains_key(&c1.uuid) { participants
participants.insert(c1.uuid, CombatState::from_creature(c1.clone())); .entry(c1.uuid)
} .or_insert(CombatState::from_creature(c1.clone()));
if !participants.contains_key(&c2.uuid) { participants
participants.insert(c2.uuid, CombatState::from_creature(c2.clone())); .entry(c2.uuid)
} .or_insert(CombatState::from_creature(c2.clone()));
participants participants
.get_mut(&c1.uuid) .get_mut(&c1.uuid)
.unwrap() .unwrap()
@ -409,7 +409,7 @@ pub fn resolve_combat(combatants: &[Creature], max_rounds: u16) -> Option<Combat
} }
// Time for violence // Time for violence
let mut order: Vec<Uuid> = participants.iter().map(|(uuid, _)| *uuid).collect(); let mut order: Vec<Uuid> = participants.keys().copied().collect();
fastrand::shuffle(&mut order); fastrand::shuffle(&mut order);
let mut kills: Vec<_> = vec![]; let mut kills: Vec<_> = vec![];
let mut attacks: Vec<_> = vec![]; let mut attacks: Vec<_> = vec![];