module Network.QUIC.Stream.Frag where

import Data.Sequence (
    Seq,
    ViewL (..),
    ViewR (..),
    dropWhileL,
    viewl,
    viewr,
    (<|),
 )

class Frag a where
    currOff :: a -> Int
    nextOff :: a -> Int
    shrink :: Int -> a -> a

instance Frag a => Frag (Seq a) where
    currOff :: Seq a -> Int
currOff Seq a
s = case forall a. Seq a -> ViewL a
viewl Seq a
s of
        ViewL a
EmptyL -> forall a. HasCallStack => [Char] -> a
error [Char]
"Seq is empty (1)"
        a
x :< Seq a
_ -> forall a. Frag a => a -> Int
currOff a
x
    nextOff :: Seq a -> Int
nextOff Seq a
s = case forall a. Seq a -> ViewR a
viewr Seq a
s of
        ViewR a
EmptyR -> forall a. HasCallStack => [Char] -> a
error [Char]
"Seq is empty (2)"
        Seq a
_ :> a
x -> forall a. Frag a => a -> Int
nextOff a
x
    shrink :: Int -> Seq a -> Seq a
shrink = forall a. Frag a => Int -> Seq a -> Seq a
shrinkSeq

shrinkSeq :: Frag a => Int -> Seq a -> Seq a
shrinkSeq :: forall a. Frag a => Int -> Seq a -> Seq a
shrinkSeq Int
n Seq a
s0 = case forall a. Seq a -> ViewL a
viewl Seq a
s of
    ViewL a
EmptyL -> forall a. HasCallStack => [Char] -> a
error [Char]
"shrinkSeq"
    a
x :< Seq a
xs
        | forall a. Frag a => a -> Int
nextOff a
x forall a. Eq a => a -> a -> Bool
== Int
n -> Seq a
xs
        | Bool
otherwise -> forall a. Frag a => Int -> a -> a
shrink Int
n a
x forall a. a -> Seq a -> Seq a
<| Seq a
xs
  where
    s :: Seq a
s = forall a. (a -> Bool) -> Seq a -> Seq a
dropWhileL (\a
y -> Bool -> Bool
not (forall a. Frag a => a -> Int
currOff a
y forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= forall a. Frag a => a -> Int
nextOff a
y)) Seq a
s0

data F = F Int Int deriving (Int -> F -> ShowS
[F] -> ShowS
F -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [F] -> ShowS
$cshowList :: [F] -> ShowS
show :: F -> [Char]
$cshow :: F -> [Char]
showsPrec :: Int -> F -> ShowS
$cshowsPrec :: Int -> F -> ShowS
Show)

instance Frag F where
    currOff :: F -> Int
currOff (F Int
s Int
_) = Int
s
    nextOff :: F -> Int
nextOff (F Int
_ Int
e) = Int
e
    shrink :: Int -> F -> F
shrink Int
n (F Int
s Int
e) = if Int
s forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
n forall a. Ord a => a -> a -> Bool
<= Int
e then Int -> Int -> F
F Int
n Int
e else forall a. HasCallStack => [Char] -> a
error [Char]
"shrink"