-- | @pipes@ utilities for encoding and decoding values as byte streams
--
-- The tutorial at the bottom of this module illustrates how to use this
-- library.
--
-- In this module, the following type synonym compatible with the @lens@,
-- @lens-family@ and @lens-family-core@ libraries is used but not exported:
--
-- @
-- type Lens' a b = forall f . 'Functor' f => (b -> f b) -> (a -> f a)
-- @

{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}
{-# LANGUAGE RankNTypes         #-}

module Pipes.Binary (
  -- * Encoding
    encode
  -- ** Explicit 'Put'
  , encodePut

  -- * Decoding
  , decode
  , decoded
  -- ** Including lengths
  , decodeL
  , decodedL
  -- ** Explicit 'Get'
  , decodeGet
  , decodeGetL

  -- * Types
  , DecodingError(..)

  -- * Exports
  -- $exports
  , module Data.Binary
  , module Data.Binary.Get
  , module Data.Binary.Put
  , module Data.ByteString
  , module Pipes.Parse

  -- * Tutorial
  -- $tutorial
  ) where

import           Control.Exception                (Exception)
import           Control.Monad.Trans.Error        (Error)
import qualified Control.Monad.Trans.State.Strict as S
import           Data.Binary                      (Binary (..))
import qualified Data.Binary
import           Data.Binary.Get                  (ByteOffset, Get)
import qualified Data.Binary.Get                  as Get
import           Data.Binary.Put                  (Put)
import qualified Data.Binary.Put                  as Put
import           Data.ByteString                  (ByteString)
import qualified Data.ByteString                  as BS
import           Data.Data                        (Data, Typeable)
import           GHC.Generics                     (Generic)
import           Pipes
import qualified Pipes.ByteString
import           Pipes.Parse                      (Parser)

--------------------------------------------------------------------------------

type Lens' a b = forall f . Functor f => (b -> f b) -> (a -> f a)

--------------------------------------------------------------------------------

-- | Convert a value to a byte stream.
--
-- @
-- 'encode' :: ('Monad' m, 'Binary' a) => a -> 'Producer'' 'ByteString' m ()
-- @
--
-- Keep in mind that a single encode value might be split into many 'ByteString'
-- chunks, that is, the lenght of the obtained 'Producer' might be greater than
-- 1.
--
-- /Hint:/ You can easily turn this 'Producer'' into a 'Pipe' that encodes
-- 'Binary' instances as they flow downstream using:
--
-- @
-- 'for' 'cat' 'encode' :: ('Monad' m, 'Binary' a) => 'Pipe' a 'ByteString' m r
-- @
encode :: (Monad m, Binary a) => a -> Proxy x' x () ByteString m ()
encode :: a -> Proxy x' x () ByteString m ()
encode = Put -> Proxy x' x () ByteString m ()
forall (m :: * -> *) x' x.
Monad m =>
Put -> Proxy x' x () ByteString m ()
encodePut (Put -> Proxy x' x () ByteString m ())
-> (a -> Put) -> a -> Proxy x' x () ByteString m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Put
forall t. Binary t => t -> Put
put
{-# INLINABLE encode #-}
{-# RULES "p >-> for cat encode" forall p .
    p >-> for cat encode = for p (\a -> encodePut (put a))
  #-}

-- | Like 'encode', except this uses an explicit 'Put'.
--
-- @
-- 'encodePut' :: ('Monad' m) => 'Put' -> 'Producer'' 'ByteString' m ()
-- @
encodePut :: (Monad m) => Put -> Proxy x' x () ByteString m ()
encodePut :: Put -> Proxy x' x () ByteString m ()
encodePut = \Put
p -> ByteString -> Producer' ByteString m ()
forall (m :: * -> *).
Monad m =>
ByteString -> Producer' ByteString m ()
Pipes.ByteString.fromLazy (Put -> ByteString
Put.runPut Put
p)
{-# INLINABLE encodePut #-}
{-# RULES "p >-> for cat encodePut" forall p.
    p >-> for cat encodePut = for p encodePut
  #-}

--------------------------------------------------------------------------------

-- | Parse a value from a byte stream.
decode :: (Monad m, Binary a) => Parser ByteString m (Either DecodingError a)
decode :: Parser ByteString m (Either DecodingError a)
decode = do
    Either DecodingError (ByteOffset, a)
x <- StateT
  (Producer ByteString m x) m (Either DecodingError (ByteOffset, a))
forall (m :: * -> *) a.
(Monad m, Binary a) =>
Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeL
    Either DecodingError a
-> StateT (Producer ByteString m x) m (Either DecodingError a)
forall (m :: * -> *) a. Monad m => a -> m a
return (case Either DecodingError (ByteOffset, a)
x of
       Left   DecodingError
e     -> DecodingError -> Either DecodingError a
forall a b. a -> Either a b
Left  DecodingError
e
       Right (ByteOffset
_, a
a) -> a -> Either DecodingError a
forall a b. b -> Either a b
Right a
a)
{-# INLINABLE decode #-}

-- | /Improper lens/ that turns a stream of bytes into a stream of decoded
-- values.
--
-- By /improper lens/ we mean that in practice you can't expect the
-- /Monad Morphism Laws/ to be true when using 'decoded' with
-- 'Control.Lens.zoom'.
--
-- @
-- 'Control.Lens.zoom' 'decoded' ('return' r) /= 'return' r
-- 'Control.Lens.zoom' 'decoded' (m >>= f)  /= 'Control.Lens.zoom' 'decoded' m >>= 'Control.Lens.zoom' 'decoded' . f
-- @
decoded
  :: (Monad m, Binary a)
  => Lens' (Producer ByteString m r)
           (Producer a m (Either (DecodingError, Producer ByteString m r) r))
decoded :: Lens'
  (Producer ByteString m r)
  (Producer a m (Either (DecodingError, Producer ByteString m r) r))
decoded Producer a m (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        a m (Either (DecodingError, Producer ByteString m r) r))
k Producer ByteString m r
p = (Producer a m (Either (DecodingError, Producer ByteString m r) r)
 -> Producer ByteString m r)
-> f (Producer
        a m (Either (DecodingError, Producer ByteString m r) r))
-> f (Producer ByteString m r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Producer a m (Either (DecodingError, Producer ByteString m r) r)
-> Producer ByteString m r
forall (m :: * -> *) a x' x a b.
(Monad m, Binary a) =>
Proxy x' x () a m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode (Producer a m (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        a m (Either (DecodingError, Producer ByteString m r) r))
k (Producer ByteString m r
-> Producer a m (Either (DecodingError, Producer ByteString m r) r)
forall (m :: * -> *) a x x' x.
(Monad m, Binary a) =>
Producer ByteString m x
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
_decode Producer ByteString m r
p))
  where
    _decode :: Producer ByteString m x
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
_decode Producer ByteString m x
p0 = do
      Either x (ByteString, Producer ByteString m x)
x <- m (Either x (ByteString, Producer ByteString m x))
-> Proxy
     x' x () a m (Either x (ByteString, Producer ByteString m x))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Producer ByteString m x
-> m (Either x (ByteString, Producer ByteString m x))
forall (m :: * -> *) r.
Monad m =>
Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
nextSkipEmpty Producer ByteString m x
p0)
      case Either x (ByteString, Producer ByteString m x)
x of
         Left x
r         -> Either (DecodingError, Producer ByteString m x) x
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
forall (m :: * -> *) a. Monad m => a -> m a
return (x -> Either (DecodingError, Producer ByteString m x) x
forall a b. b -> Either a b
Right x
r)
         Right (ByteString
bs, Producer ByteString m x
p1) -> do
            (Either DecodingError a
ea, Producer ByteString m x
p2) <- m (Either DecodingError a, Producer ByteString m x)
-> Proxy
     x' x () a m (Either DecodingError a, Producer ByteString m x)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Either DecodingError a, Producer ByteString m x)
 -> Proxy
      x' x () a m (Either DecodingError a, Producer ByteString m x))
-> m (Either DecodingError a, Producer ByteString m x)
-> Proxy
     x' x () a m (Either DecodingError a, Producer ByteString m x)
forall a b. (a -> b) -> a -> b
$ StateT (Producer ByteString m x) m (Either DecodingError a)
-> Producer ByteString m x
-> m (Either DecodingError a, Producer ByteString m x)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
S.runStateT StateT (Producer ByteString m x) m (Either DecodingError a)
forall (m :: * -> *) a.
(Monad m, Binary a) =>
Parser ByteString m (Either DecodingError a)
decode (ByteString -> Proxy X () () ByteString m ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield ByteString
bs Proxy X () () ByteString m ()
-> Producer ByteString m x -> Producer ByteString m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer ByteString m x
p1)
            case Either DecodingError a
ea of
               Left  DecodingError
e -> Either (DecodingError, Producer ByteString m x) x
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
forall (m :: * -> *) a. Monad m => a -> m a
return ((DecodingError, Producer ByteString m x)
-> Either (DecodingError, Producer ByteString m x) x
forall a b. a -> Either a b
Left (DecodingError
e, Producer ByteString m x
p2))
               Right a
a -> a -> Proxy x' x () a m ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield a
a Proxy x' x () a m ()
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer ByteString m x
-> Proxy
     x' x () a m (Either (DecodingError, Producer ByteString m x) x)
_decode Producer ByteString m x
p2
    _encode :: Proxy x' x () a m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode Proxy x' x () a m (Either (a, Proxy x' x () ByteString m b) b)
p0 = do
      Either (a, Proxy x' x () ByteString m b) b
er <- Proxy x' x () a m (Either (a, Proxy x' x () ByteString m b) b)
-> (a -> Proxy x' x () ByteString m ())
-> Proxy
     x' x () ByteString m (Either (a, Proxy x' x () ByteString m b) b)
forall (m :: * -> *) x' x b' b a' c' c.
Functor m =>
Proxy x' x b' b m a'
-> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
for Proxy x' x () a m (Either (a, Proxy x' x () ByteString m b) b)
p0 a -> Proxy x' x () ByteString m ()
forall (m :: * -> *) a x' x.
(Monad m, Binary a) =>
a -> Proxy x' x () ByteString m ()
encode
      case Either (a, Proxy x' x () ByteString m b) b
er of
         Left (a
_, Proxy x' x () ByteString m b
p1) -> Proxy x' x () ByteString m b
p1
         Right b
r      -> b -> Proxy x' x () ByteString m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
{-# INLINABLE decoded #-}

--------------------------------------------------------------------------------

-- | Like 'decode', but also returns the length of input consumed in order to
-- to decode the value.
decodeL
  :: (Monad m, Binary a)
  => Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeL :: Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeL = Get a -> Parser ByteString m (Either DecodingError (ByteOffset, a))
forall (m :: * -> *) a.
Monad m =>
Get a -> Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeGetL Get a
forall t. Binary t => Get t
get
{-# INLINABLE decodeL #-}

-- | Like 'decoded', except this tags each decoded value with the length of
-- input consumed in order to decode it.
decodedL
  :: (Monad m, Binary a)
  => Lens' (Producer ByteString m r)
           (Producer (ByteOffset, a) m
                     (Either (DecodingError, Producer ByteString m r) r))
decodedL :: Lens'
  (Producer ByteString m r)
  (Producer
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m r) r))
decodedL Producer
  (ByteOffset, a)
  m
  (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        (ByteOffset, a)
        m
        (Either (DecodingError, Producer ByteString m r) r))
k Producer ByteString m r
p = (Producer
   (ByteOffset, a)
   m
   (Either (DecodingError, Producer ByteString m r) r)
 -> Producer ByteString m r)
-> f (Producer
        (ByteOffset, a)
        m
        (Either (DecodingError, Producer ByteString m r) r))
-> f (Producer ByteString m r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Producer
  (ByteOffset, a)
  m
  (Either (DecodingError, Producer ByteString m r) r)
-> Producer ByteString m r
forall (m :: * -> *) a x' x a a b.
(Monad m, Binary a) =>
Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode (Producer
  (ByteOffset, a)
  m
  (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        (ByteOffset, a)
        m
        (Either (DecodingError, Producer ByteString m r) r))
k (Producer ByteString m r
-> Producer
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m r) r)
forall (m :: * -> *) a x x' x.
(Monad m, Binary a) =>
Producer ByteString m x
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
_decode Producer ByteString m r
p))
  where
    _decode :: Producer ByteString m x
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
_decode Producer ByteString m x
p0 = do
      Either x (ByteString, Producer ByteString m x)
x <- m (Either x (ByteString, Producer ByteString m x))
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either x (ByteString, Producer ByteString m x))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Producer ByteString m x
-> m (Either x (ByteString, Producer ByteString m x))
forall (m :: * -> *) r.
Monad m =>
Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
nextSkipEmpty Producer ByteString m x
p0)
      case Either x (ByteString, Producer ByteString m x)
x of
         Left x
r         -> Either (DecodingError, Producer ByteString m x) x
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
forall (m :: * -> *) a. Monad m => a -> m a
return (x -> Either (DecodingError, Producer ByteString m x) x
forall a b. b -> Either a b
Right x
r)
         Right (ByteString
bs, Producer ByteString m x
p1) -> do
            (Either DecodingError (ByteOffset, a)
ea, Producer ByteString m x
p2) <- m (Either DecodingError (ByteOffset, a), Producer ByteString m x)
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either DecodingError (ByteOffset, a), Producer ByteString m x)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Either DecodingError (ByteOffset, a), Producer ByteString m x)
 -> Proxy
      x'
      x
      ()
      (ByteOffset, a)
      m
      (Either DecodingError (ByteOffset, a), Producer ByteString m x))
-> m (Either DecodingError (ByteOffset, a),
      Producer ByteString m x)
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either DecodingError (ByteOffset, a), Producer ByteString m x)
forall a b. (a -> b) -> a -> b
$ StateT
  (Producer ByteString m x) m (Either DecodingError (ByteOffset, a))
-> Producer ByteString m x
-> m (Either DecodingError (ByteOffset, a),
      Producer ByteString m x)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
S.runStateT StateT
  (Producer ByteString m x) m (Either DecodingError (ByteOffset, a))
forall (m :: * -> *) a.
(Monad m, Binary a) =>
Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeL (ByteString -> Proxy X () () ByteString m ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield ByteString
bs Proxy X () () ByteString m ()
-> Producer ByteString m x -> Producer ByteString m x
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer ByteString m x
p1)
            case Either DecodingError (ByteOffset, a)
ea of
               Left  DecodingError
e -> Either (DecodingError, Producer ByteString m x) x
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
forall (m :: * -> *) a. Monad m => a -> m a
return ((DecodingError, Producer ByteString m x)
-> Either (DecodingError, Producer ByteString m x) x
forall a b. a -> Either a b
Left (DecodingError
e, Producer ByteString m x
p2))
               Right (ByteOffset, a)
a -> (ByteOffset, a) -> Proxy x' x () (ByteOffset, a) m ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield (ByteOffset, a)
a Proxy x' x () (ByteOffset, a) m ()
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Producer ByteString m x
-> Proxy
     x'
     x
     ()
     (ByteOffset, a)
     m
     (Either (DecodingError, Producer ByteString m x) x)
_decode Producer ByteString m x
p2
    _encode :: Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
p0 = do
      Either (a, Proxy x' x () ByteString m b) b
er <- Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
-> ((a, a) -> Proxy x' x () ByteString m ())
-> Proxy
     x' x () ByteString m (Either (a, Proxy x' x () ByteString m b) b)
forall (m :: * -> *) x' x b' b a' c' c.
Functor m =>
Proxy x' x b' b m a'
-> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
for Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
p0 (\(a
_, a
a) -> a -> Proxy x' x () ByteString m ()
forall (m :: * -> *) a x' x.
(Monad m, Binary a) =>
a -> Proxy x' x () ByteString m ()
encode a
a)
      case Either (a, Proxy x' x () ByteString m b) b
er of
         Left (a
_, Proxy x' x () ByteString m b
p1) -> Proxy x' x () ByteString m b
p1
         Right b
r      -> b -> Proxy x' x () ByteString m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
{-# INLINABLE decodedL #-}

--------------------------------------------------------------------------------

-- | Like 'decode', except this requires an explicit 'Get' instead of any
-- 'Binary' instance.
decodeGet :: (Monad m) => Get a -> Parser ByteString m (Either DecodingError a)
decodeGet :: Get a -> Parser ByteString m (Either DecodingError a)
decodeGet Get a
m = do
    Either DecodingError (ByteOffset, a)
x <- Get a -> Parser ByteString m (Either DecodingError (ByteOffset, a))
forall (m :: * -> *) a.
Monad m =>
Get a -> Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeGetL Get a
m
    Either DecodingError a
-> StateT (Producer ByteString m x) m (Either DecodingError a)
forall (m :: * -> *) a. Monad m => a -> m a
return (case Either DecodingError (ByteOffset, a)
x of
       Left   DecodingError
e     -> DecodingError -> Either DecodingError a
forall a b. a -> Either a b
Left  DecodingError
e
       Right (ByteOffset
_, a
a) -> a -> Either DecodingError a
forall a b. b -> Either a b
Right a
a)
{-# INLINABLE decodeGet #-}

-- | Like 'decodeL', except this requires an explicit 'Get' instead of any
-- 'Binary' instance.
decodeGetL
  :: (Monad m)
  => Get a -> Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeGetL :: Get a -> Parser ByteString m (Either DecodingError (ByteOffset, a))
decodeGetL Get a
m = (Proxy X () () ByteString m x
 -> m (Either DecodingError (ByteOffset, a),
       Proxy X () () ByteString m x))
-> StateT
     (Proxy X () () ByteString m x)
     m
     (Either DecodingError (ByteOffset, a))
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
S.StateT ((Proxy X () () ByteString m x -> Proxy X () () ByteString m x)
-> Decoder a
-> Proxy X () () ByteString m x
-> m (Either DecodingError (ByteOffset, a),
      Proxy X () () ByteString m x)
forall (m :: * -> *) a b.
Monad m =>
(Proxy X () () ByteString m a -> Proxy X () () ByteString m a)
-> Decoder b
-> Proxy X () () ByteString m a
-> m (Either DecodingError (ByteOffset, b),
      Proxy X () () ByteString m a)
go Proxy X () () ByteString m x -> Proxy X () () ByteString m x
forall a. a -> a
id (Get a -> Decoder a
forall a. Get a -> Decoder a
Get.runGetIncremental Get a
m))
  where
    go :: (Proxy X () () ByteString m a -> Proxy X () () ByteString m a)
-> Decoder b
-> Proxy X () () ByteString m a
-> m (Either DecodingError (ByteOffset, b),
      Proxy X () () ByteString m a)
go Proxy X () () ByteString m a -> Proxy X () () ByteString m a
diffP Decoder b
decoder Proxy X () () ByteString m a
p0 = case Decoder b
decoder of
      Get.Fail ByteString
_ ByteOffset
off String
str -> (Either DecodingError (ByteOffset, b),
 Proxy X () () ByteString m a)
-> m (Either DecodingError (ByteOffset, b),
      Proxy X () () ByteString m a)
forall (m :: * -> *) a. Monad m => a -> m a
return (DecodingError -> Either DecodingError (ByteOffset, b)
forall a b. a -> Either a b
Left (ByteOffset -> String -> DecodingError
DecodingError ByteOffset
off String
str), Proxy X () () ByteString m a -> Proxy X () () ByteString m a
diffP Proxy X () () ByteString m a
p0)
      Get.Done ByteString
bs ByteOffset
off  b
a -> (Either DecodingError (ByteOffset, b),
 Proxy X () () ByteString m a)
-> m (Either DecodingError (ByteOffset, b),
      Proxy X () () ByteString m a)
forall (m :: * -> *) a. Monad m => a -> m a
return ((ByteOffset, b) -> Either DecodingError (ByteOffset, b)
forall a b. b -> Either a b
Right (ByteOffset
off, b
a), ByteString -> Proxy X () () ByteString m ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield ByteString
bs Proxy X () () ByteString m ()
-> Proxy X () () ByteString m a -> Proxy X () () ByteString m a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Proxy X () () ByteString m a
p0)
      Get.Partial Maybe ByteString -> Decoder b
k      -> do
         Either a (ByteString, Proxy X () () ByteString m a)
x <- Proxy X () () ByteString m a
-> m (Either a (ByteString, Proxy X () () ByteString m a))
forall (m :: * -> *) r.
Monad m =>
Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
nextSkipEmpty Proxy X () () ByteString m a
p0
         case Either a (ByteString, Proxy X () () ByteString m a)
x of
            Left   a
e       -> (Proxy X () () ByteString m a -> Proxy X () () ByteString m a)
-> Decoder b
-> Proxy X () () ByteString m a
-> m (Either DecodingError (ByteOffset, b),
      Proxy X () () ByteString m a)
go Proxy X () () ByteString m a -> Proxy X () () ByteString m a
diffP (Maybe ByteString -> Decoder b
k Maybe ByteString
forall a. Maybe a
Nothing) (a -> Proxy X () () ByteString m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
e)
            Right (ByteString
bs, Proxy X () () ByteString m a
p1) -> (Proxy X () () ByteString m a -> Proxy X () () ByteString m a)
-> Decoder b
-> Proxy X () () ByteString m a
-> m (Either DecodingError (ByteOffset, b),
      Proxy X () () ByteString m a)
go (Proxy X () () ByteString m a -> Proxy X () () ByteString m a
diffP (Proxy X () () ByteString m a -> Proxy X () () ByteString m a)
-> (Proxy X () () ByteString m a -> Proxy X () () ByteString m a)
-> Proxy X () () ByteString m a
-> Proxy X () () ByteString m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Proxy X () () ByteString m ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield ByteString
bs Proxy X () () ByteString m ()
-> Proxy X () () ByteString m a -> Proxy X () () ByteString m a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>)) (Maybe ByteString -> Decoder b
k (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
bs)) Proxy X () () ByteString m a
p1
{-# INLINABLE decodeGetL #-}

--------------------------------------------------------------------------------

-- | A 'Get' decoding error, as provided by 'Get.Fail'.
data DecodingError = DecodingError
  { DecodingError -> ByteOffset
deConsumed :: {-# UNPACK #-} !ByteOffset
    -- ^ Number of bytes consumed before the error
  , DecodingError -> String
deMessage  :: !String
    -- ^ Error message
  } deriving (Int -> DecodingError -> ShowS
[DecodingError] -> ShowS
DecodingError -> String
(Int -> DecodingError -> ShowS)
-> (DecodingError -> String)
-> ([DecodingError] -> ShowS)
-> Show DecodingError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DecodingError] -> ShowS
$cshowList :: [DecodingError] -> ShowS
show :: DecodingError -> String
$cshow :: DecodingError -> String
showsPrec :: Int -> DecodingError -> ShowS
$cshowsPrec :: Int -> DecodingError -> ShowS
Show, ReadPrec [DecodingError]
ReadPrec DecodingError
Int -> ReadS DecodingError
ReadS [DecodingError]
(Int -> ReadS DecodingError)
-> ReadS [DecodingError]
-> ReadPrec DecodingError
-> ReadPrec [DecodingError]
-> Read DecodingError
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DecodingError]
$creadListPrec :: ReadPrec [DecodingError]
readPrec :: ReadPrec DecodingError
$creadPrec :: ReadPrec DecodingError
readList :: ReadS [DecodingError]
$creadList :: ReadS [DecodingError]
readsPrec :: Int -> ReadS DecodingError
$creadsPrec :: Int -> ReadS DecodingError
Read, DecodingError -> DecodingError -> Bool
(DecodingError -> DecodingError -> Bool)
-> (DecodingError -> DecodingError -> Bool) -> Eq DecodingError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DecodingError -> DecodingError -> Bool
$c/= :: DecodingError -> DecodingError -> Bool
== :: DecodingError -> DecodingError -> Bool
$c== :: DecodingError -> DecodingError -> Bool
Eq, Typeable DecodingError
DataType
Constr
Typeable DecodingError
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DecodingError -> c DecodingError)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DecodingError)
-> (DecodingError -> Constr)
-> (DecodingError -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DecodingError))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DecodingError))
-> ((forall b. Data b => b -> b) -> DecodingError -> DecodingError)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DecodingError -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DecodingError -> r)
-> (forall u. (forall d. Data d => d -> u) -> DecodingError -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> DecodingError -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DecodingError -> m DecodingError)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DecodingError -> m DecodingError)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DecodingError -> m DecodingError)
-> Data DecodingError
DecodingError -> DataType
DecodingError -> Constr
(forall b. Data b => b -> b) -> DecodingError -> DecodingError
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DecodingError -> c DecodingError
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DecodingError
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> DecodingError -> u
forall u. (forall d. Data d => d -> u) -> DecodingError -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DecodingError -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DecodingError -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DecodingError
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DecodingError -> c DecodingError
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DecodingError)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DecodingError)
$cDecodingError :: Constr
$tDecodingError :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
gmapMp :: (forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
gmapM :: (forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DecodingError -> m DecodingError
gmapQi :: Int -> (forall d. Data d => d -> u) -> DecodingError -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DecodingError -> u
gmapQ :: (forall d. Data d => d -> u) -> DecodingError -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DecodingError -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DecodingError -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DecodingError -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DecodingError -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DecodingError -> r
gmapT :: (forall b. Data b => b -> b) -> DecodingError -> DecodingError
$cgmapT :: (forall b. Data b => b -> b) -> DecodingError -> DecodingError
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DecodingError)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DecodingError)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c DecodingError)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DecodingError)
dataTypeOf :: DecodingError -> DataType
$cdataTypeOf :: DecodingError -> DataType
toConstr :: DecodingError -> Constr
$ctoConstr :: DecodingError -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DecodingError
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DecodingError
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DecodingError -> c DecodingError
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DecodingError -> c DecodingError
$cp1Data :: Typeable DecodingError
Data, Typeable, (forall x. DecodingError -> Rep DecodingError x)
-> (forall x. Rep DecodingError x -> DecodingError)
-> Generic DecodingError
forall x. Rep DecodingError x -> DecodingError
forall x. DecodingError -> Rep DecodingError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DecodingError x -> DecodingError
$cfrom :: forall x. DecodingError -> Rep DecodingError x
Generic)

instance Exception DecodingError
instance Error     DecodingError

--------------------------------------------------------------------------------
-- Internal stuff

-- | Like 'Pipes.next', except it skips leading 'BS.null' chunks.
nextSkipEmpty
  :: Monad m
  => Producer ByteString m r
  -> m (Either r (ByteString, Producer ByteString m r))
nextSkipEmpty :: Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
nextSkipEmpty = Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
forall (m :: * -> *) r.
Monad m =>
Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
go where
    go :: Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
go Producer ByteString m r
p0 = do
      Either r (ByteString, Producer ByteString m r)
x <- Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
forall (m :: * -> *) a r.
Monad m =>
Producer a m r -> m (Either r (a, Producer a m r))
next Producer ByteString m r
p0
      case Either r (ByteString, Producer ByteString m r)
x of
         Left  r
_        -> Either r (ByteString, Producer ByteString m r)
-> m (Either r (ByteString, Producer ByteString m r))
forall (m :: * -> *) a. Monad m => a -> m a
return Either r (ByteString, Producer ByteString m r)
x
         Right (ByteString
a,Producer ByteString m r
p1)
          | ByteString -> Bool
BS.null ByteString
a   -> Producer ByteString m r
-> m (Either r (ByteString, Producer ByteString m r))
go Producer ByteString m r
p1
          | Bool
otherwise   -> Either r (ByteString, Producer ByteString m r)
-> m (Either r (ByteString, Producer ByteString m r))
forall (m :: * -> *) a. Monad m => a -> m a
return Either r (ByteString, Producer ByteString m r)
x
{-# INLINABLE nextSkipEmpty #-}

--------------------------------------------------------------------------------

-- $exports
--
--  The following types are re-exported from this module for your convenience:
--
--  [From "Data.Binary"] 'Binary'
--
--  [From "Data.Binary.Put"] 'Put'
--
--  [From "Data.Binary.Get"] 'Get', 'ByteOffset'
--
--  [From "Data.ByteString"] 'ByteString'
--
--  [From "Pipes.Parse"] 'Parser'

--------------------------------------------------------------------------------

{- $tutorial

    Use 'encode' to convert values to byte streams

> -- example.hs
>
> import Pipes
> import qualified Pipes.Prelude as P
> import Pipes.Binary
>
> readInts :: Int -> Producer Int IO ()
> readInts n = P.readLn >-> P.take n
>
> encodedValues :: Producer ByteString IO ()
> encodedValues = do
>     for (readInts 3) encode  -- Encode 3 Ints read from user input
>     encode 'C'               -- Encode a 'Char'
>     encode True              -- Encode a 'Bool'

    Use 'decode' to parse a single decoded value or 'decoded' to access a stream
    of decoded values:

> -- example.hs
>
> import Data.ByteString (ByteString)
> import Pipes.Parse
> import Prelude hiding (splitAt)
>
> -- We need to import 'zoom', which can be found in many packages and all work
> -- equally fine for our purposes. Read "Pipes.Parse.Tutorial" for details.
> --
> -- * From the package @lens-family-core@: 'Lens.Family.State.Strict.zoom'
> -- * From the package @lens-family@:      'Lens.Family2.State.Strict.zoom'
> -- * From the package @lens@:             'Control.Lens.Zoom.zoom'
> import Lens.Family.State.Strict (zoom)
>
> decoder :: Parser ByteString IO ()
> decoder = do
>     xs <- zoom (decoded . splitAt 3) drawAll      -- Decode up to three 'Int's
>     lift $ print (xs :: [Int])
>     y  <- decode                                  -- Decode a single 'Char'
>     lift $ print (y :: Either DecodingError Char)
>     z  <- zoom decoded draw                       -- Same as 'decode', but
>     lift $ print (z :: Maybe Bool)                -- with a 'Maybe'
>
> main = evalStateT decoder encodedValues

    Here are some example inputs:

> $ ./example
> 1<Enter>
> 2<Enter>
> 3<Enter>
> [1,2,3]
> Right 'C'
> Just True
> $ ./example
> <Ctrl-D>
> []
> Right 'C'
> Just True

-}