module Test.Dahdit.Daytripper
  ( Cmp
  , expectCodec
  , expectCodecOk
  , expectCodecErr
  , expectBytes
  , expectText
  , expectStatic
  )
where

import Dahdit (Binary, ByteCount (..), GetError, StaticByteSized (..), decodeEnd, encode)
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.Either (isLeft, isRight)
import Data.Proxy (Proxy (..))
import Data.Text (Text)
import Data.Text.Encoding qualified as TE
import Data.Word (Word8)
import Test.Daytripper (Expect, MonadExpect (..), expectDuring, mkExpect)

type Cmp m a = Maybe a -> Either GetError a -> m ()

expectCodec :: (MonadExpect m, Binary a) => Cmp m a -> Expect m a ByteString (Either GetError a)
expectCodec :: forall (m :: * -> *) a.
(MonadExpect m, Binary a) =>
Cmp m a -> Expect m a ByteString (Either GetError a)
expectCodec = forall (m :: * -> *) a b c.
MonadExpect m =>
(a -> m b)
-> (b -> m c) -> (Maybe a -> c -> m ()) -> Expect m a b c
mkExpect a -> m ByteString
enc ByteString -> m (Either GetError a)
dec
 where
  enc :: a -> m ByteString
enc = forall (m :: * -> *) a. MonadExpect m => IO a -> m a
expectLiftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a z (m :: * -> *).
(Binary a, BinaryPutTarget z m) =>
a -> m z
encode
  dec :: ByteString -> m (Either GetError a)
dec = forall (m :: * -> *) a. MonadExpect m => IO a -> m a
expectLiftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a z (m :: * -> *).
(Binary a, BinaryGetTarget z m) =>
z -> m (Either GetError a, ByteCount)
decodeEnd

expectCodecOk :: (MonadExpect m, Binary a, Eq a, Show a) => Expect m a ByteString (Either GetError a)
expectCodecOk :: forall (m :: * -> *) a.
(MonadExpect m, Binary a, Eq a, Show a) =>
Expect m a ByteString (Either GetError a)
expectCodecOk = forall (m :: * -> *) a.
(MonadExpect m, Binary a) =>
Cmp m a -> Expect m a ByteString (Either GetError a)
expectCodec (forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *). MonadExpect m => String -> Bool -> m ()
expectAssertBool String
"expected ok" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Either a b -> Bool
isRight) (\a
a Either GetError a
x -> forall (m :: * -> *) a.
(MonadExpect m, Eq a, Show a) =>
a -> a -> m ()
expectAssertEq Either GetError a
x (forall a b. b -> Either a b
Right a
a)))

expectCodecErr :: (MonadExpect m, Binary a) => Expect m a ByteString (Either GetError a)
expectCodecErr :: forall (m :: * -> *) a.
(MonadExpect m, Binary a) =>
Expect m a ByteString (Either GetError a)
expectCodecErr = forall (m :: * -> *) a.
(MonadExpect m, Binary a) =>
Cmp m a -> Expect m a ByteString (Either GetError a)
expectCodec (forall a b. a -> b -> a
const (forall (m :: * -> *). MonadExpect m => String -> Bool -> m ()
expectAssertBool String
"expected error" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Either a b -> Bool
isLeft))

expectBytes :: (MonadExpect m) => [Word8] -> Expect m a ByteString c -> Expect m a ByteString c
expectBytes :: forall (m :: * -> *) a c.
MonadExpect m =>
[Word8] -> Expect m a ByteString c -> Expect m a ByteString c
expectBytes [Word8]
ws = forall (m :: * -> *) a b c.
Monad m =>
(Maybe a -> b -> m ()) -> Expect m a b c -> Expect m a b c
expectDuring (\Maybe a
_ ByteString
bs -> forall (m :: * -> *) a.
(MonadExpect m, Eq a, Show a) =>
a -> a -> m ()
expectAssertEq ByteString
bs ([Word8] -> ByteString
BS.pack [Word8]
ws))

expectText :: (MonadExpect m) => Text -> Expect m a ByteString c -> Expect m a ByteString c
expectText :: forall (m :: * -> *) a c.
MonadExpect m =>
Text -> Expect m a ByteString c -> Expect m a ByteString c
expectText Text
t = forall (m :: * -> *) a b c.
Monad m =>
(Maybe a -> b -> m ()) -> Expect m a b c -> Expect m a b c
expectDuring (\Maybe a
_ ByteString
bs -> forall (m :: * -> *) a.
(MonadExpect m, Eq a, Show a) =>
a -> a -> m ()
expectAssertEq ByteString
bs (Text -> ByteString
TE.encodeUtf8 Text
t))

proxyBefore :: Expect m a b c -> Proxy a
proxyBefore :: forall (m :: * -> *) a b c. Expect m a b c -> Proxy a
proxyBefore Expect m a b c
_ = forall {k} (t :: k). Proxy t
Proxy

expectStatic :: (MonadExpect m, StaticByteSized a) => Expect m a ByteString c -> Expect m a ByteString c
expectStatic :: forall (m :: * -> *) a c.
(MonadExpect m, StaticByteSized a) =>
Expect m a ByteString c -> Expect m a ByteString c
expectStatic Expect m a ByteString c
ex =
  let len :: Int
len = ByteCount -> Int
unByteCount (forall a. StaticByteSized a => Proxy a -> ByteCount
staticByteSize (forall (m :: * -> *) a b c. Expect m a b c -> Proxy a
proxyBefore Expect m a ByteString c
ex))
  in  forall (m :: * -> *) a b c.
Monad m =>
(Maybe a -> b -> m ()) -> Expect m a b c -> Expect m a b c
expectDuring (\Maybe a
_ ByteString
bs -> forall (m :: * -> *) a.
(MonadExpect m, Eq a, Show a) =>
a -> a -> m ()
expectAssertEq (ByteString -> Int
BS.length ByteString
bs) Int
len) Expect m a ByteString c
ex