module Data.Accessor.ByteSource where

import qualified Control.Monad.Trans.State as State
import Control.Monad.Trans.State (StateT, )
import Control.Monad.Trans.Class (lift, )
import Data.Word (Word8, )


class ByteCompatible byte where
   toByte :: byte -> Word8

instance ByteCompatible Word8 where
   toByte :: Word8 -> Word8
toByte = Word8 -> Word8
forall a. a -> a
id


class ByteStream s where
   getWord8 :: MonadFail m => s -> m (Word8, s)

instance ByteCompatible byte => ByteStream [byte] where
   getWord8 :: forall (m :: * -> *). MonadFail m => [byte] -> m (Word8, [byte])
getWord8 [byte]
xs =
      case [byte]
xs of
         (byte
c:[byte]
cs) -> (Word8, [byte]) -> m (Word8, [byte])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (byte -> Word8
forall byte. ByteCompatible byte => byte -> Word8
toByte byte
c, [byte]
cs)
         [byte]
_ -> String -> m (Word8, [byte])
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ByteStream: no more byte available"


class Monad source => ByteSource source where
   readWord8 :: source Word8

instance (ByteStream s, MonadFail m) => ByteSource (StateT s m) where
   readWord8 :: StateT s m Word8
readWord8 =
      do s
xs <- StateT s m s
forall (m :: * -> *) s. Monad m => StateT s m s
State.get
         (Word8
c,s
cs) <- m (Word8, s) -> StateT s m (Word8, s)
forall (m :: * -> *) a. Monad m => m a -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (s -> m (Word8, s)
forall s (m :: * -> *).
(ByteStream s, MonadFail m) =>
s -> m (Word8, s)
forall (m :: * -> *). MonadFail m => s -> m (Word8, s)
getWord8 s
xs)
         s -> StateT s m ()
forall (m :: * -> *) s. Monad m => s -> StateT s m ()
State.put s
cs
         Word8 -> StateT s m Word8
forall a. a -> StateT s m a
forall (m :: * -> *) a. Monad m => a -> m a
return Word8
c