Created
April 19, 2021 12:12
-
-
Save BashkaMen/15783eebe000af81844d68bb23edbe85 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Application.ES | |
open System | |
open FsToolkit.ErrorHandling | |
let inline ( ^ ) f x = f x | |
type CommandMeta<'id, 'command> = { AggId: 'id; Command: 'command } | |
type EventMeta<'id, 'payload> = { AggId: 'id; Created: DateTime; Payload: 'payload } | |
let mkEvent id created x = { AggId = id; Created = created; Payload = x } | |
let mkCmd id cmd = { AggId = id; Command = cmd } | |
type GameEventId = GameEventId | |
type TournamentId = TournamentId | |
type CategoryId = CategoryId | |
type MLString = { Ru: string; Uk: string; En: string } | |
type Limit = | |
| Amount of int | |
| Percent of int | |
| NoLimit | |
type Tournament = { Id: Guid; Name: MLString; } | |
type Category = { Id: Guid; Name: MLString; } | |
type P1P2 = | |
| P1 of float | |
| P2 of float | |
type Market = | |
| Win of P1P2 | |
type TradingState = Open | Closed | Paused | |
type UserId = UserId of Guid | |
type Bet = { Player: UserId; Amount: float; Market: Market } | |
type MarketEvent = | |
| Added of Market | |
| Removed of Market | |
| Changed of Market | |
type Event = | |
| GameEventCreated of {| Name: MLString; Tournament: Tournament; Category: Category |} | |
| Market of MarketEvent | |
| LimitChanged of Limit | |
| TradingStateChanged of TradingState | |
| BetPlaced of Bet | |
type MarketName = MarketName of string | |
type Markets = Markets of Map<MarketName, Market> | |
let marketName = function | |
| Win _ -> MarketName "П1 - П2" | |
let marketsProj state events = | |
let folder (Markets state) event = | |
match event.Payload with | |
| Market (Added market) -> state |> Map.add (marketName market) market | |
| Market (Removed market) -> state |> Map.remove (marketName market) | |
| Market (Changed market) -> state |> Map.add (marketName market) market | |
| _ -> state | |
|> Markets | |
List.fold folder state events | |
let tradingStateProj state events = | |
let folder state event = | |
match event.Payload with | |
| TradingStateChanged ts -> ts | |
| _ -> state | |
List.fold folder state events | |
let bets state events = | |
let folder state event = | |
match event.Payload with | |
| BetPlaced bet -> bet::state | |
| _ -> state | |
List.fold folder state events | |
let sumOfBets state events = | |
bets [] events | |
|> List.sumBy ^ fun x -> x.Amount | |
|> fun sum -> state + sum | |
type IEventStore<'id, 'event> = | |
abstract Append : int64 -> EventMeta<'id, 'event> list -> Async<Result<int64, string>> | |
abstract GetFrom : int64 -> 'id -> Async<EventMeta<'id, 'event> list> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment