use rustorio_engine::{
machine::{Machine, MachineNotEmptyError},
recipe::{Recipe, RecipeEx},
research::{TechRecipe, Technology, TechnologyEx, tech_recipe},
};
use crate::{
Bundle, Tick,
recipes::{AssemblerRecipe, FurnaceRecipe},
resources::{Copper, CopperWire, Iron},
};
#[derive(Debug)]
pub struct Assembler<R: AssemblerRecipe>(Machine<R>);
impl<R: AssemblerRecipe> Assembler<R> {
pub fn build(
tick: &Tick,
recipe: R,
copper_wires: Bundle<CopperWire, 12>,
iron: Bundle<Iron, 6>,
) -> Self {
let _ = (recipe, copper_wires, iron);
Self(Machine::new(tick))
}
pub fn change_recipe<R2: AssemblerRecipe>(
self,
recipe: R2,
) -> Result<Assembler<R2>, MachineNotEmptyError<Self>> {
match self.0.change_recipe(recipe) {
Ok(machine) => Ok(Assembler(machine)),
Err(err) => Err(err.map_machine(Assembler)),
}
}
pub fn inputs(&mut self, tick: &Tick) -> &mut <R as Recipe>::Inputs {
self.0.inputs(tick)
}
pub const fn input_amounts(&self) -> <R as Recipe>::InputAmountsType {
<R as Recipe>::INPUT_AMOUNTS
}
pub fn outputs(&mut self, tick: &Tick) -> &mut <R as Recipe>::Outputs {
self.0.outputs(tick)
}
pub const fn output_amounts(&self) -> <R as Recipe>::OutputAmountsType {
<R as Recipe>::OUTPUT_AMOUNTS
}
}
#[derive(Debug)]
pub struct Furnace<R: FurnaceRecipe>(Machine<R>);
impl<R: FurnaceRecipe> Furnace<R> {
pub fn build(tick: &Tick, recipe: R, iron: Bundle<Iron, 10>) -> Self {
let _ = (recipe, iron);
Self(Machine::new(tick))
}
pub fn change_recipe<R2: FurnaceRecipe>(
self,
recipe: R2,
) -> Result<Furnace<R2>, MachineNotEmptyError<Self>> {
match self.0.change_recipe(recipe) {
Ok(machine) => Ok(Furnace(machine)),
Err(err) => Err(err.map_machine(Furnace)),
}
}
pub fn inputs(&mut self, tick: &Tick) -> &mut <R as Recipe>::Inputs {
self.0.inputs(tick)
}
pub const fn input_amounts(&self) -> <R as Recipe>::InputAmountsType {
<R as Recipe>::INPUT_AMOUNTS
}
pub fn outputs(&mut self, tick: &Tick) -> &mut <R as Recipe>::Outputs {
self.0.outputs(tick)
}
pub const fn output_amounts(&self) -> <R as Recipe>::OutputAmountsType {
<R as Recipe>::OUTPUT_AMOUNTS
}
}
#[derive(Debug)]
pub struct Lab<T: Technology>(Machine<TechRecipe<T>>)
where
TechRecipe<T>: RecipeEx;
impl<T: Technology> Lab<T>
where
TechRecipe<T>: RecipeEx,
{
pub fn build(
tick: &Tick,
technology: &T,
iron: Bundle<Iron, 20>,
copper: Bundle<Copper, 15>,
) -> Self {
let _ = (technology, iron, copper);
Self(Machine::new(tick))
}
pub fn change_technology<T2: Technology>(
self,
technology: &T2,
) -> Result<Lab<T2>, MachineNotEmptyError<Self>>
where
TechRecipe<T2>: RecipeEx,
{
let _ = technology;
match self.0.change_recipe(tech_recipe()) {
Ok(machine) => Ok(Lab(machine)),
Err(err) => Err(err.map_machine(Lab)),
}
}
pub fn inputs(&mut self, tick: &Tick) -> &mut <TechRecipe<T> as Recipe>::Inputs {
self.0.inputs(tick)
}
pub const fn input_amounts(&self) -> <T as TechnologyEx>::InputAmountsType {
<T as TechnologyEx>::INPUT_AMOUNTS
}
pub fn outputs(&mut self, tick: &Tick) -> &mut <TechRecipe<T> as Recipe>::Outputs {
self.0.outputs(tick)
}
}