card-game 0.2.0

Framework for building card games
Documentation
use card_stack::priority::GetState;
use state_validation::{StateFilter, ValidAction, ValidationError, Validator};

pub struct HistoricalContext<History: ActionHistory, State> {
    history: History,
    state: State,
}

impl<History: ActionHistory, State> HistoricalContext<History, State> {
    pub fn new(history: History, state: State) -> Self {
        HistoricalContext { history, state }
    }
    pub fn validate<Input, Filter: StateFilter<State, Input>>(
        self,
        input: Input,
    ) -> Result<ValidContext<History, State, Input, Filter>, ValidationError<State, Filter::Error>>
    {
        Ok(ValidContext {
            history: self.history,
            validator: Validator::try_new(self.state, input)?,
        })
    }
}

pub struct ValidContext<History: ActionHistory, State, Input, Filter: StateFilter<State, Input>> {
    history: History,
    validator: Validator<State, Input, Filter>,
}

impl<History: ActionHistory, State, Input, Filter: StateFilter<State, Input>>
    ValidContext<History, State, Input, Filter>
{
    pub fn action<
        Action: ValidAction<State, Input, Filter = Filter>
            + ActionInfo<State, Filter::ValidOutput, History::History>,
    >(
        mut self,
        action: Action,
    ) -> HistoricalContext<History, Action::Output> {
        self.history
            .push(action.info(self.validator.state(), self.validator.valid_output()));
        HistoricalContext::new(self.history, self.validator.execute(action))
    }
}

pub trait ActionHistory {
    type History;
    fn push(&mut self, history: Self::History);
}

pub trait ActionInfo<State, Input, Info> {
    fn info(&self, state: &State, input: &Input) -> Info;
}