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 = 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) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall byte. ByteCompatible byte => byte -> Word8
toByte byte
c, [byte]
cs)
         [byte]
_ -> 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 <- forall (m :: * -> *) s. Monad m => StateT s m s
State.get
         (Word8
c,s
cs) <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall s (m :: * -> *).
(ByteStream s, MonadFail m) =>
s -> m (Word8, s)
getWord8 s
xs)
         forall (m :: * -> *) s. Monad m => s -> StateT s m ()
State.put s
cs
         forall (m :: * -> *) a. Monad m => a -> m a
return Word8
c