{-# LANGUAGE RankNTypes #-}

-- | This module exports facilities similar to those exported by the
-- "Pipes.Aeson" module, except they do not restrict the 'Ae.Value's
-- that might be encoded or decoded to be just valid top-level values. That is,
-- not only 'Ae.Object's or 'Ae.Array's, according to to the RFC-4627 JSON
-- standard.

module Pipes.Aeson.Unchecked
  ( -- * Encoding
    encode
    -- * Decoding
  , decode
  , decoded
    -- ** Including lenghts
  , decodeL
  , decodedL
  ) where

import           Control.Monad        (liftM)
import qualified Data.Aeson           as Ae
import qualified Data.Aeson.Parser    as Ae (value')
import qualified Data.ByteString      as B
import           Pipes
import qualified Pipes.Aeson.Internal as I
import qualified Pipes.ByteString     as PB
import qualified Pipes.Parse          as Pipes

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

-- | Like 'Pipes.Aeson.encode', except it accepts any 'Ae.ToJSON' instance,
-- not just 'Ae.Array' or 'Ae.Object'.
encode :: (Monad m, Ae.ToJSON a) => a -> Producer' B.ByteString m ()
encode :: a -> Producer' ByteString m ()
encode = ByteString -> Proxy x' x () ByteString m ()
forall (m :: * -> *).
Monad m =>
ByteString -> Producer' ByteString m ()
PB.fromLazy (ByteString -> Proxy x' x () ByteString m ())
-> (a -> ByteString) -> a -> Proxy x' x () ByteString m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ByteString
forall a. ToJSON a => a -> ByteString
Ae.encode
{-# INLINABLE encode #-}
{-# RULES "p >-> for cat encode" forall p .
    p >-> for cat encode = for p (\a -> PB.fromLazy (Ae.encode a))
  #-}

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

-- | Like 'Pipes.Aeson.decode', except it will decode any 'Ae.FromJSON'
-- instance, not just 'Ae.Array' or 'Ae.Object'.
decode
  :: (Monad m, Ae.FromJSON a)
  => Pipes.Parser B.ByteString m (Maybe (Either I.DecodingError a)) -- ^
decode :: Parser ByteString m (Maybe (Either DecodingError a))
decode = (Either DecodingError (Int, a) -> Either DecodingError a)
-> Maybe (Either DecodingError (Int, a))
-> Maybe (Either DecodingError a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Int, a) -> a)
-> Either DecodingError (Int, a) -> Either DecodingError a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, a) -> a
forall a b. (a, b) -> b
snd) (Maybe (Either DecodingError (Int, a))
 -> Maybe (Either DecodingError a))
-> StateT
     (Producer ByteString m x) m (Maybe (Either DecodingError (Int, a)))
-> StateT
     (Producer ByteString m x) m (Maybe (Either DecodingError a))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` StateT
  (Producer ByteString m x) m (Maybe (Either DecodingError (Int, a)))
forall (m :: * -> *) a.
(Monad m, FromJSON a) =>
Parser ByteString m (Maybe (Either DecodingError (Int, a)))
decodeL
{-# INLINABLE decode #-}


-- | Like 'decode', except it also returns the length of JSON input that was
-- consumed in order to obtain the value, not including the length of whitespace
-- between each parsed JSON input.
decodeL
  :: (Monad m, Ae.FromJSON a)
  => Pipes.Parser B.ByteString m (Maybe (Either I.DecodingError (Int, a))) -- ^
decodeL :: Parser ByteString m (Maybe (Either DecodingError (Int, a)))
decodeL = Parser ByteString Value
-> Parser ByteString m (Maybe (Either DecodingError (Int, a)))
forall (m :: * -> *) a.
(Monad m, FromJSON a) =>
Parser ByteString Value
-> Parser ByteString m (Maybe (Either DecodingError (Int, a)))
I.decodeL Parser ByteString Value
Ae.value'
{-# INLINABLE decodeL #-}

-- | Like 'Pipes.Aeson.decoded', except it will decode and decode any
-- 'Ae.FromJSON' and 'Ae.ToJSON' instance, not just 'Ae.Array' or 'Ae.Object'.
decoded
  :: (Monad m, Ae.FromJSON a, Ae.ToJSON a)
  => Lens' (Producer B.ByteString m r)
           (Producer a m (Either (I.DecodingError, Producer B.ByteString m r) r))
     -- ^
decoded :: Lens'
  (Producer ByteString m r)
  (Producer a m (Either (DecodingError, Producer ByteString m r) r))
decoded k :: Producer a m (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        a m (Either (DecodingError, Producer ByteString m r) r))
k p :: 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 x' x a b.
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 (Parser ByteString m (Maybe (Either DecodingError a))
-> Producer ByteString m r
-> Producer a m (Either (DecodingError, Producer ByteString m r) r)
forall (m :: * -> *) e a r.
Monad m =>
Parser ByteString m (Maybe (Either e a))
-> Producer ByteString m r
-> Producer a m (Either (e, Producer ByteString m r) r)
I.consecutively Parser ByteString m (Maybe (Either DecodingError a))
forall (m :: * -> *) a.
(Monad m, FromJSON a) =>
Parser ByteString m (Maybe (Either DecodingError a))
decode Producer ByteString m r
p))
  where
    _encode :: Proxy x' x () a m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode = \p0 :: 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 :: a
a -> a -> Producer' ByteString m ()
forall (m :: * -> *) a.
(Monad m, ToJSON a) =>
a -> Producer' ByteString m ()
encode a
a)
      case Either (a, Proxy x' x () ByteString m b) b
er of
         Left (_, p1 :: Proxy x' x () ByteString m b
p1) -> Proxy x' x () ByteString m b
p1
         Right r :: b
r      -> b -> Proxy x' x () ByteString m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
    {-# INLINE _encode #-}
{-# INLINABLE decoded #-}


-- | Like 'decoded', except it also tags each decoded entity with the length of
-- JSON input that was consumed in order to obtain the value, not including the
-- length of whitespace between each parsed JSON input.
decodedL
  :: (Monad m, Ae.FromJSON a, Ae.ToJSON a)
  => Lens' (Producer B.ByteString m r)
           (Producer (Int, a) m (Either (I.DecodingError, Producer B.ByteString m r) r))
     -- ^
decodedL :: Lens'
  (Producer ByteString m r)
  (Producer
     (Int, a) m (Either (DecodingError, Producer ByteString m r) r))
decodedL k :: Producer
  (Int, a) m (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        (Int, a) m (Either (DecodingError, Producer ByteString m r) r))
k p :: Producer ByteString m r
p = (Producer
   (Int, a) m (Either (DecodingError, Producer ByteString m r) r)
 -> Producer ByteString m r)
-> f (Producer
        (Int, 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
  (Int, a) m (Either (DecodingError, Producer ByteString m r) r)
-> Producer ByteString m r
forall x' x a a b.
Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode (Producer
  (Int, a) m (Either (DecodingError, Producer ByteString m r) r)
-> f (Producer
        (Int, a) m (Either (DecodingError, Producer ByteString m r) r))
k (Parser ByteString m (Maybe (Either DecodingError (Int, a)))
-> Producer ByteString m r
-> Producer
     (Int, a) m (Either (DecodingError, Producer ByteString m r) r)
forall (m :: * -> *) e a r.
Monad m =>
Parser ByteString m (Maybe (Either e a))
-> Producer ByteString m r
-> Producer a m (Either (e, Producer ByteString m r) r)
I.consecutively Parser ByteString m (Maybe (Either DecodingError (Int, a)))
forall (m :: * -> *) a.
(Monad m, FromJSON a) =>
Parser ByteString m (Maybe (Either DecodingError (Int, a)))
decodeL Producer ByteString m r
p))
  where
    _encode :: Proxy x' x () (a, a) m (Either (a, Proxy x' x () ByteString m b) b)
-> Proxy x' x () ByteString m b
_encode = \p0 :: 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 -> Producer' ByteString m ()
forall (m :: * -> *) a.
(Monad m, ToJSON a) =>
a -> Producer' ByteString m ()
encode a
a)
      case Either (a, Proxy x' x () ByteString m b) b
er of
         Left (_, p1 :: Proxy x' x () ByteString m b
p1) -> Proxy x' x () ByteString m b
p1
         Right r :: b
r      -> b -> Proxy x' x () ByteString m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
    {-# INLINE _encode #-}
{-# INLINABLE decodedL #-}


--------------------------------------------------------------------------------
-- Internal tools --------------------------------------------------------------

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