use super::types::BookMarketState;
use crate::book::protocol::reject::RejectReason;
use crate::types::MarketKind;
#[allow(dead_code)]
pub fn validate_transition(
from: BookMarketState,
to: BookMarketState,
market_kind: MarketKind,
) -> Result<(), RejectReason> {
if market_kind == MarketKind::PreEventOnly && to == BookMarketState::TurnInPlayEnabled {
return Err(RejectReason::MarketInPlayNotSupported);
}
if from.is_terminal() && !matches!(to, BookMarketState::Settled | BookMarketState::Voided) {
return Err(RejectReason::MarketTerminal);
}
Ok(())
}
#[allow(dead_code)]
pub fn can_trade(state: BookMarketState) -> Result<(), RejectReason> {
if !state.is_matchable() {
return Err(RejectReason::MarketNotOpen);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pre_event_only_cannot_go_in_play() {
let result = validate_transition(
BookMarketState::Open,
BookMarketState::TurnInPlayEnabled,
MarketKind::PreEventOnly,
);
assert_eq!(result, Err(RejectReason::MarketInPlayNotSupported));
}
#[test]
fn in_play_capable_can_go_in_play() {
let result = validate_transition(
BookMarketState::Open,
BookMarketState::TurnInPlayEnabled,
MarketKind::InPlayCapable,
);
assert!(result.is_ok());
}
#[test]
fn terminal_state_rejects_open() {
let result = validate_transition(
BookMarketState::Settled,
BookMarketState::Open,
MarketKind::InPlayCapable,
);
assert_eq!(result, Err(RejectReason::MarketTerminal));
}
#[test]
fn can_trade_when_open() {
assert!(can_trade(BookMarketState::Open).is_ok());
assert!(can_trade(BookMarketState::TurnInPlayEnabled).is_ok());
}
#[test]
fn cannot_trade_when_closed() {
assert_eq!(
can_trade(BookMarketState::Closed),
Err(RejectReason::MarketNotOpen)
);
assert_eq!(
can_trade(BookMarketState::Suspended),
Err(RejectReason::MarketNotOpen)
);
}
}