add market and odds endpoints
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use chrono::{DateTime, Duration as ChronoDuration, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::events::{MarketSnapshot, OutcomeSnapshot};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct OutcomeOddsSnapshot {
|
||||
pub id: Uuid,
|
||||
pub odds_version_id: Uuid,
|
||||
pub outcome_id: Uuid,
|
||||
pub decimal_odds: f64,
|
||||
pub fractional_num: i32,
|
||||
pub fractional_den: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct OddsVersionSnapshot {
|
||||
pub id: Uuid,
|
||||
pub market_id: Uuid,
|
||||
pub version_no: i32,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub is_current: bool,
|
||||
pub odds: Vec<OutcomeOddsSnapshot>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct MarketsStore {
|
||||
inner: Arc<RwLock<MarketsState>>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MarketsState {
|
||||
markets_by_event_id: HashMap<Uuid, Vec<MarketSnapshot>>,
|
||||
markets_by_id: HashMap<Uuid, MarketSnapshot>,
|
||||
current_odds_by_market_id: HashMap<Uuid, OddsVersionSnapshot>,
|
||||
}
|
||||
|
||||
impl MarketsStore {
|
||||
pub fn new() -> Self {
|
||||
Self::with_sample_data()
|
||||
}
|
||||
|
||||
pub fn with_sample_data() -> Self {
|
||||
let event_id = Uuid::parse_str("11111111-1111-1111-1111-111111111111").expect("valid uuid");
|
||||
let market_id = Uuid::parse_str("22222222-2222-2222-2222-222222222222").expect("valid uuid");
|
||||
let odds_version_id = Uuid::parse_str("66666666-6666-6666-6666-666666666666").expect("valid uuid");
|
||||
let preview_lock_at = Utc::now() + ChronoDuration::minutes(10);
|
||||
let created_at = Utc::now();
|
||||
|
||||
let home_outcome_id = Uuid::parse_str("44444444-4444-4444-4444-444444444444").expect("valid uuid");
|
||||
let away_outcome_id = Uuid::parse_str("55555555-5555-5555-5555-555555555555").expect("valid uuid");
|
||||
|
||||
let market = MarketSnapshot {
|
||||
id: market_id,
|
||||
event_id,
|
||||
question_key: "market.sample.winner".to_string(),
|
||||
market_type: "winner".to_string(),
|
||||
status: "open".to_string(),
|
||||
lock_at: preview_lock_at,
|
||||
settlement_rule_key: "settle_on_match_winner".to_string(),
|
||||
outcomes: vec![
|
||||
OutcomeSnapshot {
|
||||
id: home_outcome_id,
|
||||
market_id,
|
||||
outcome_code: "home".to_string(),
|
||||
label_key: "outcome.home".to_string(),
|
||||
sort_order: 1,
|
||||
},
|
||||
OutcomeSnapshot {
|
||||
id: away_outcome_id,
|
||||
market_id,
|
||||
outcome_code: "away".to_string(),
|
||||
label_key: "outcome.away".to_string(),
|
||||
sort_order: 2,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
let odds_version = OddsVersionSnapshot {
|
||||
id: odds_version_id,
|
||||
market_id,
|
||||
version_no: 1,
|
||||
created_at,
|
||||
is_current: true,
|
||||
odds: vec![
|
||||
OutcomeOddsSnapshot {
|
||||
id: Uuid::parse_str("77777777-7777-7777-7777-777777777777").expect("valid uuid"),
|
||||
odds_version_id,
|
||||
outcome_id: home_outcome_id,
|
||||
decimal_odds: 1.85,
|
||||
fractional_num: 17,
|
||||
fractional_den: 20,
|
||||
},
|
||||
OutcomeOddsSnapshot {
|
||||
id: Uuid::parse_str("88888888-8888-8888-8888-888888888888").expect("valid uuid"),
|
||||
odds_version_id,
|
||||
outcome_id: away_outcome_id,
|
||||
decimal_odds: 2.05,
|
||||
fractional_num: 21,
|
||||
fractional_den: 20,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
let mut markets_by_event_id = HashMap::new();
|
||||
markets_by_event_id.insert(event_id, vec![market.clone()]);
|
||||
|
||||
let mut markets_by_id = HashMap::new();
|
||||
markets_by_id.insert(market_id, market);
|
||||
|
||||
let mut current_odds_by_market_id = HashMap::new();
|
||||
current_odds_by_market_id.insert(market_id, odds_version);
|
||||
|
||||
Self {
|
||||
inner: Arc::new(RwLock::new(MarketsState {
|
||||
markets_by_event_id,
|
||||
markets_by_id,
|
||||
current_odds_by_market_id,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn markets_for_event(&self, event_id: Uuid) -> Option<Vec<MarketSnapshot>> {
|
||||
let state = self.inner.read().await;
|
||||
let Some(markets) = state.markets_by_event_id.get(&event_id) else {
|
||||
return None;
|
||||
};
|
||||
Some(markets.clone())
|
||||
}
|
||||
|
||||
pub async fn market(&self, market_id: Uuid) -> Option<MarketSnapshot> {
|
||||
let state = self.inner.read().await;
|
||||
let Some(market) = state.markets_by_id.get(&market_id) else {
|
||||
return None;
|
||||
};
|
||||
Some(market.clone())
|
||||
}
|
||||
|
||||
pub async fn current_odds(&self, market_id: Uuid) -> Option<OddsVersionSnapshot> {
|
||||
let state = self.inner.read().await;
|
||||
let Some(odds) = state.current_odds_by_market_id.get(&market_id) else {
|
||||
return None;
|
||||
};
|
||||
Some(odds.clone())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user