From 15601e54a3333399cf0f9d0fce561712dbdc7c56 Mon Sep 17 00:00:00 2001 From: Kubat <maelle.martin@proton.me> Date: Fri, 18 Apr 2025 20:36:17 +0200 Subject: [PATCH] Just trying an API for the Spell/SpellFactory --- Cargo.lock | 1 + grimoire_engine_types/Cargo.toml | 1 + grimoire_engine_types/src/error.rs | 2 ++ grimoire_engine_types/src/lib.rs | 3 ++ grimoire_engine_types/src/spell.rs | 54 ++++++++++++++++++++++++++++++ grimoire_engine_types/src/state.rs | 2 ++ 6 files changed, 63 insertions(+) create mode 100644 grimoire_engine_types/src/error.rs create mode 100644 grimoire_engine_types/src/spell.rs create mode 100644 grimoire_engine_types/src/state.rs diff --git a/Cargo.lock b/Cargo.lock index 894aafd..9366642 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -366,6 +366,7 @@ dependencies = [ "log", "paste", "serde", + "thiserror", ] [[package]] diff --git a/grimoire_engine_types/Cargo.toml b/grimoire_engine_types/Cargo.toml index 637d58e..a7c6bce 100644 --- a/grimoire_engine_types/Cargo.toml +++ b/grimoire_engine_types/Cargo.toml @@ -15,3 +15,4 @@ paste.workspace = true serde.workspace = true hashbrown.workspace = true log.workspace = true +thiserror.workspace = true diff --git a/grimoire_engine_types/src/error.rs b/grimoire_engine_types/src/error.rs new file mode 100644 index 0000000..482b170 --- /dev/null +++ b/grimoire_engine_types/src/error.rs @@ -0,0 +1,2 @@ +#[derive(Debug, thiserror::Error)] +pub enum SpellError {} diff --git a/grimoire_engine_types/src/lib.rs b/grimoire_engine_types/src/lib.rs index e69de29..46bc08d 100644 --- a/grimoire_engine_types/src/lib.rs +++ b/grimoire_engine_types/src/lib.rs @@ -0,0 +1,3 @@ +pub mod spell; +pub mod state; +pub mod error; diff --git a/grimoire_engine_types/src/spell.rs b/grimoire_engine_types/src/spell.rs new file mode 100644 index 0000000..8db3e85 --- /dev/null +++ b/grimoire_engine_types/src/spell.rs @@ -0,0 +1,54 @@ +use crate::{error::SpellError, state::State}; + +pub trait Spell { + fn cast(&self, state: State) -> Result<State, SpellError>; + + fn uncast(&self, state: State) -> Result<State, SpellError>; +} + +pub struct SpellArguments {} + +pub trait BuildableSpell: Spell + TryFrom<SpellArguments, Error = SpellError> { + fn name() -> &'static str; + + fn aliases() -> &'static [&'static str] { + &[] + } + + fn name_list() -> impl Iterator<Item = &'static str> { + [Self::name()] + .into_iter() + .chain(Self::aliases().iter().copied()) + } + + fn create(arguments: SpellArguments) -> Result<Box<dyn Spell>, SpellError>; +} + +type SpellBuilderFunction = fn(SpellArguments) -> Result<Box<dyn Spell>, SpellError>; + +#[derive(Debug, Default)] +pub struct SpellFactory { + dispatch: hashbrown::HashMap<&'static str, SpellBuilderFunction>, +} + +impl SpellFactory { + pub fn register<Spell: BuildableSpell + 'static>(&mut self) -> Result<(), SpellError> { + Spell::name_list() + .find(|spell_name| self.dispatch.contains_key(spell_name)) + .map(|_name| -> Result<(), SpellError> { todo!("error") }) + .unwrap_or(Ok(()))?; + + Spell::name_list().for_each(|name| _ = self.dispatch.insert(name, Spell::create)); + + Ok(()) + } + + pub fn try_build_spell( + &self, + name: &str, + arguments: SpellArguments, + ) -> Result<Box<dyn Spell>, SpellError> { + let builder_function = self.dispatch.get(name).ok_or_else(|| todo!("error"))?; + builder_function(arguments) + } +} diff --git a/grimoire_engine_types/src/state.rs b/grimoire_engine_types/src/state.rs new file mode 100644 index 0000000..815e4be --- /dev/null +++ b/grimoire_engine_types/src/state.rs @@ -0,0 +1,2 @@ +pub struct State { +} -- GitLab