module Relay.ReceiverHalf
( ReceiverHalf (..),
emptyReceiver,
receive,
)
where
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Relay.Session (Nat)
data ReceiverHalf a = ReceiverHalf
{ forall a. ReceiverHalf a -> Nat
expected :: Nat,
forall a. ReceiverHalf a -> Map Nat a
pending :: Map Nat a
}
deriving (Int -> ReceiverHalf a -> ShowS
[ReceiverHalf a] -> ShowS
ReceiverHalf a -> String
(Int -> ReceiverHalf a -> ShowS)
-> (ReceiverHalf a -> String)
-> ([ReceiverHalf a] -> ShowS)
-> Show (ReceiverHalf a)
forall a. Show a => Int -> ReceiverHalf a -> ShowS
forall a. Show a => [ReceiverHalf a] -> ShowS
forall a. Show a => ReceiverHalf a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> ReceiverHalf a -> ShowS
showsPrec :: Int -> ReceiverHalf a -> ShowS
$cshow :: forall a. Show a => ReceiverHalf a -> String
show :: ReceiverHalf a -> String
$cshowList :: forall a. Show a => [ReceiverHalf a] -> ShowS
showList :: [ReceiverHalf a] -> ShowS
Show, ReceiverHalf a -> ReceiverHalf a -> Bool
(ReceiverHalf a -> ReceiverHalf a -> Bool)
-> (ReceiverHalf a -> ReceiverHalf a -> Bool)
-> Eq (ReceiverHalf a)
forall a. Eq a => ReceiverHalf a -> ReceiverHalf a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => ReceiverHalf a -> ReceiverHalf a -> Bool
== :: ReceiverHalf a -> ReceiverHalf a -> Bool
$c/= :: forall a. Eq a => ReceiverHalf a -> ReceiverHalf a -> Bool
/= :: ReceiverHalf a -> ReceiverHalf a -> Bool
Eq)
emptyReceiver :: ReceiverHalf a
emptyReceiver :: forall a. ReceiverHalf a
emptyReceiver = ReceiverHalf {expected :: Nat
expected = Nat
1, pending :: Map Nat a
pending = Map Nat a
forall k a. Map k a
Map.empty}
receive :: Nat -> a -> ReceiverHalf a -> (ReceiverHalf a, [a])
receive :: forall a. Nat -> a -> ReceiverHalf a -> (ReceiverHalf a, [a])
receive Nat
n a
v ReceiverHalf a
rh
| Nat
n Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
< ReceiverHalf a -> Nat
forall a. ReceiverHalf a -> Nat
expected ReceiverHalf a
rh = (ReceiverHalf a
rh, [])
| Nat
n Nat -> Nat -> Bool
forall a. Ord a => a -> a -> Bool
> ReceiverHalf a -> Nat
forall a. ReceiverHalf a -> Nat
expected ReceiverHalf a
rh = (ReceiverHalf a
rh {pending = Map.insert n v (pending rh)}, [])
| Bool
otherwise = ReceiverHalf a -> [a] -> (ReceiverHalf a, [a])
forall {a}. ReceiverHalf a -> [a] -> (ReceiverHalf a, [a])
flush ReceiverHalf a
rh {expected = expected rh + 1} [a
v]
where
flush :: ReceiverHalf a -> [a] -> (ReceiverHalf a, [a])
flush ReceiverHalf a
rh' [a]
acc =
case Map Nat a -> Maybe ((Nat, a), Map Nat a)
forall k a. Map k a -> Maybe ((k, a), Map k a)
Map.minViewWithKey (ReceiverHalf a -> Map Nat a
forall a. ReceiverHalf a -> Map Nat a
pending ReceiverHalf a
rh') of
Just ((Nat
k, a
a), Map Nat a
rest)
| Nat
k Nat -> Nat -> Bool
forall a. Eq a => a -> a -> Bool
== ReceiverHalf a -> Nat
forall a. ReceiverHalf a -> Nat
expected ReceiverHalf a
rh' ->
ReceiverHalf a -> [a] -> (ReceiverHalf a, [a])
flush ReceiverHalf a
rh' {expected = k + 1, pending = rest} ([a]
acc [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a
a])
Maybe ((Nat, a), Map Nat a)
_ -> (ReceiverHalf a
rh', [a]
acc)