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 xs <- StateT s m s
forall (m :: * -> *) s. Monad m => StateT s m s
State.get
         (c,cs) <- lift (getWord8 xs)
         State.put cs
         return c