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

View File

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

View File

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