{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ScopedTypeVariables #-}

module DSV.FileStrictMap
  ( mapDsvFileStrictWithoutHeader
  , mapDsvFileStrictIgnoringHeader
  , mapDsvFileStrictUsingHeader
  ) where

import DSV.ByteString
import DSV.DelimiterType
import DSV.Fold
import DSV.Header
import DSV.IO
import DSV.ParseStop
import DSV.Parsing
import DSV.Pipes
import DSV.Prelude
import DSV.Vector

-- pipes
import qualified Pipes.Prelude as P

mapDsvFileStrictWithoutHeader ::
    forall m row .
    MonadIO m
    => Delimiter
        -- ^ What character separates input values, e.g. 'comma' or 'tab'
    -> FilePath
        -- ^ The path of a DSV file to read
    -> (Vector ByteString -> IO row)
        -- ^ Conversion function by which you specify how to interpret one row of bytes from the DSV file
    -> m (ParseStop, Vector row)

mapDsvFileStrictWithoutHeader :: Delimiter
-> FilePath
-> (Vector ByteString -> IO row)
-> m (ParseStop, Vector row)
mapDsvFileStrictWithoutHeader Delimiter
d FilePath
fp Vector ByteString -> IO row
f =
    IO (ParseStop, Vector row) -> m (ParseStop, Vector row)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ParseStop, Vector row) -> m (ParseStop, Vector row))
-> IO (ParseStop, Vector row) -> m (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$ SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row)
forall (m :: * -> *) r.
(MonadMask m, MonadIO m) =>
SafeT m r -> m r
runSafeT (SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row))
-> SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$
      do
        FoldM (SafeT IO) row (Vector row)
-> Producer row (SafeT IO) ParseStop
-> SafeT IO (ParseStop, Vector row)
forall a b (m :: * -> *) r.
Monad m =>
FoldM m a b -> Producer a m r -> m (r, b)
foldProducerM FoldM (SafeT IO) row (Vector row)
forall (v :: * -> *) (m :: * -> *) a.
(PrimMonad m, Vector v a) =>
FoldM m a (v a)
foldVectorM (Producer row (SafeT IO) ParseStop
 -> SafeT IO (ParseStop, Vector row))
-> Producer row (SafeT IO) ParseStop
-> SafeT IO (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$
            FilePath
-> IOMode
-> (Handle -> Producer row (SafeT IO) ParseStop)
-> Producer row (SafeT IO) ParseStop
forall (m :: * -> *) r.
MonadSafe m =>
FilePath -> IOMode -> (Handle -> m r) -> m r
withFile FilePath
fp IOMode
ReadMode ((Handle -> Producer row (SafeT IO) ParseStop)
 -> Producer row (SafeT IO) ParseStop)
-> (Handle -> Producer row (SafeT IO) ParseStop)
-> Producer row (SafeT IO) ParseStop
forall a b. (a -> b) -> a -> b
$ \Handle
h ->
                Delimiter
-> Handle -> Producer (Vector ByteString) (SafeT IO) ParseStop
forall (m :: * -> *).
MonadIO m =>
Delimiter -> Handle -> Producer (Vector ByteString) m ParseStop
handleDsvRowProducer Delimiter
d Handle
h Producer (Vector ByteString) (SafeT IO) ParseStop
-> Proxy () (Vector ByteString) () row (SafeT IO) ParseStop
-> Producer row (SafeT IO) ParseStop
forall (m :: * -> *) a' a b r c' c.
Monad m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (Vector ByteString -> SafeT IO row)
-> Proxy () (Vector ByteString) () row (SafeT IO) ParseStop
forall (m :: * -> *) a b r. Monad m => (a -> m b) -> Pipe a b m r
P.mapM (IO row -> SafeT IO row
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO row -> SafeT IO row)
-> (Vector ByteString -> IO row)
-> Vector ByteString
-> SafeT IO row
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Vector ByteString -> IO row
f)

mapDsvFileStrictIgnoringHeader ::
    forall m row .
    MonadIO m
    => Delimiter
        -- ^ What character separates input values, e.g. 'comma' or 'tab'
    -> FilePath
        -- ^ The path of a DSV file to read
    -> (Vector ByteString -> IO row)
        -- ^ Conversion function by which you specify how to interpret one row of bytes from the DSV file
    -> m (ParseStop, Vector row)

mapDsvFileStrictIgnoringHeader :: Delimiter
-> FilePath
-> (Vector ByteString -> IO row)
-> m (ParseStop, Vector row)
mapDsvFileStrictIgnoringHeader Delimiter
d FilePath
fp Vector ByteString -> IO row
f =
    IO (ParseStop, Vector row) -> m (ParseStop, Vector row)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ParseStop, Vector row) -> m (ParseStop, Vector row))
-> IO (ParseStop, Vector row) -> m (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$ SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row)
forall (m :: * -> *) r.
(MonadMask m, MonadIO m) =>
SafeT m r -> m r
runSafeT (SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row))
-> SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$
      do
        FoldM (SafeT IO) row (Vector row)
-> Producer row (SafeT IO) ParseStop
-> SafeT IO (ParseStop, Vector row)
forall a b (m :: * -> *) r.
Monad m =>
FoldM m a b -> Producer a m r -> m (r, b)
foldProducerM (Natural
-> FoldM (SafeT IO) row (Vector row)
-> FoldM (SafeT IO) row (Vector row)
forall (m :: * -> *) a b.
Monad m =>
Natural -> FoldM m a b -> FoldM m a b
foldDropM Natural
1 FoldM (SafeT IO) row (Vector row)
forall (v :: * -> *) (m :: * -> *) a.
(PrimMonad m, Vector v a) =>
FoldM m a (v a)
foldVectorM) (Producer row (SafeT IO) ParseStop
 -> SafeT IO (ParseStop, Vector row))
-> Producer row (SafeT IO) ParseStop
-> SafeT IO (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$
            FilePath
-> IOMode
-> (Handle -> Producer row (SafeT IO) ParseStop)
-> Producer row (SafeT IO) ParseStop
forall (m :: * -> *) r.
MonadSafe m =>
FilePath -> IOMode -> (Handle -> m r) -> m r
withFile FilePath
fp IOMode
ReadMode ((Handle -> Producer row (SafeT IO) ParseStop)
 -> Producer row (SafeT IO) ParseStop)
-> (Handle -> Producer row (SafeT IO) ParseStop)
-> Producer row (SafeT IO) ParseStop
forall a b. (a -> b) -> a -> b
$ \Handle
h ->
                Delimiter
-> Handle -> Producer (Vector ByteString) (SafeT IO) ParseStop
forall (m :: * -> *).
MonadIO m =>
Delimiter -> Handle -> Producer (Vector ByteString) m ParseStop
handleDsvRowProducer Delimiter
d Handle
h Producer (Vector ByteString) (SafeT IO) ParseStop
-> Proxy () (Vector ByteString) () row (SafeT IO) ParseStop
-> Producer row (SafeT IO) ParseStop
forall (m :: * -> *) a' a b r c' c.
Monad m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (Vector ByteString -> SafeT IO row)
-> Proxy () (Vector ByteString) () row (SafeT IO) ParseStop
forall (m :: * -> *) a b r. Monad m => (a -> m b) -> Pipe a b m r
P.mapM (IO row -> SafeT IO row
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO row -> SafeT IO row)
-> (Vector ByteString -> IO row)
-> Vector ByteString
-> SafeT IO row
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Vector ByteString -> IO row
f)

mapDsvFileStrictUsingHeader ::
    forall m row .
    MonadIO m
    => Delimiter
        -- ^ What character separates input values, e.g. 'comma' or 'tab'
    -> FilePath
        -- ^ The path of a DSV file to read
    -> (Vector ByteString -> IO (Vector ByteString -> IO row))
        -- ^ Function which interprets the header (the first @Vector ByteString@) and returns a conversion function (@Vector ByteString -> IO row@) by which you specify how to interpret one row of bytes from the DSV file
    -> m (ParseStop, Vector row)

mapDsvFileStrictUsingHeader :: Delimiter
-> FilePath
-> (Vector ByteString -> IO (Vector ByteString -> IO row))
-> m (ParseStop, Vector row)
mapDsvFileStrictUsingHeader Delimiter
d FilePath
fp Vector ByteString -> IO (Vector ByteString -> IO row)
f =
    IO (ParseStop, Vector row) -> m (ParseStop, Vector row)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ParseStop, Vector row) -> m (ParseStop, Vector row))
-> IO (ParseStop, Vector row) -> m (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$ SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row)
forall (m :: * -> *) r.
(MonadMask m, MonadIO m) =>
SafeT m r -> m r
runSafeT (SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row))
-> SafeT IO (ParseStop, Vector row) -> IO (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$
      do
        FoldM (SafeT IO) row (Vector row)
-> Producer row (SafeT IO) ParseStop
-> SafeT IO (ParseStop, Vector row)
forall a b (m :: * -> *) r.
Monad m =>
FoldM m a b -> Producer a m r -> m (r, b)
foldProducerM FoldM (SafeT IO) row (Vector row)
forall (v :: * -> *) (m :: * -> *) a.
(PrimMonad m, Vector v a) =>
FoldM m a (v a)
foldVectorM (Producer row (SafeT IO) ParseStop
 -> SafeT IO (ParseStop, Vector row))
-> Producer row (SafeT IO) ParseStop
-> SafeT IO (ParseStop, Vector row)
forall a b. (a -> b) -> a -> b
$
            FilePath
-> IOMode
-> (Handle -> Producer row (SafeT IO) ParseStop)
-> Producer row (SafeT IO) ParseStop
forall (m :: * -> *) r.
MonadSafe m =>
FilePath -> IOMode -> (Handle -> m r) -> m r
withFile FilePath
fp IOMode
ReadMode ((Handle -> Producer row (SafeT IO) ParseStop)
 -> Producer row (SafeT IO) ParseStop)
-> (Handle -> Producer row (SafeT IO) ParseStop)
-> Producer row (SafeT IO) ParseStop
forall a b. (a -> b) -> a -> b
$ \Handle
h ->
                Delimiter
-> Handle -> Producer (Vector ByteString) (SafeT IO) ParseStop
forall (m :: * -> *).
MonadIO m =>
Delimiter -> Handle -> Producer (Vector ByteString) m ParseStop
handleDsvRowProducer Delimiter
d Handle
h Producer (Vector ByteString) (SafeT IO) ParseStop
-> Proxy () (Vector ByteString) () row (SafeT IO) ParseStop
-> Producer row (SafeT IO) ParseStop
forall (m :: * -> *) a' a b r c' c.
Monad m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (Vector ByteString -> SafeT IO (Vector ByteString -> SafeT IO row))
-> Proxy () (Vector ByteString) () row (SafeT IO) ParseStop
forall a b (m :: * -> *) r.
Monad m =>
(a -> m (a -> m b)) -> Pipe a b m r
applyHeaderPipeM ((Vector ByteString -> IO (Vector ByteString -> IO row))
-> Vector ByteString
-> SafeT IO (Vector ByteString -> SafeT IO row)
forall a.
(Vector ByteString -> IO (Vector ByteString -> IO a))
-> Vector ByteString -> SafeT IO (Vector ByteString -> SafeT IO a)
bigLift Vector ByteString -> IO (Vector ByteString -> IO row)
f)

bigLift ::
       (Vector ByteString ->       IO (Vector ByteString ->       IO a))
    -> (Vector ByteString -> SafeT IO (Vector ByteString -> SafeT IO a))

bigLift :: (Vector ByteString -> IO (Vector ByteString -> IO a))
-> Vector ByteString -> SafeT IO (Vector ByteString -> SafeT IO a)
bigLift = (IO (Vector ByteString -> SafeT IO a)
 -> SafeT IO (Vector ByteString -> SafeT IO a))
-> (Vector ByteString -> IO (Vector ByteString -> SafeT IO a))
-> Vector ByteString
-> SafeT IO (Vector ByteString -> SafeT IO a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IO (Vector ByteString -> SafeT IO a)
-> SafeT IO (Vector ByteString -> SafeT IO a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO ((Vector ByteString -> IO (Vector ByteString -> SafeT IO a))
 -> Vector ByteString -> SafeT IO (Vector ByteString -> SafeT IO a))
-> ((Vector ByteString -> IO (Vector ByteString -> IO a))
    -> Vector ByteString -> IO (Vector ByteString -> SafeT IO a))
-> (Vector ByteString -> IO (Vector ByteString -> IO a))
-> Vector ByteString
-> SafeT IO (Vector ByteString -> SafeT IO a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (((IO (Vector ByteString -> IO a)
 -> IO (Vector ByteString -> SafeT IO a))
-> (Vector ByteString -> IO (Vector ByteString -> IO a))
-> Vector ByteString
-> IO (Vector ByteString -> SafeT IO a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((IO (Vector ByteString -> IO a)
  -> IO (Vector ByteString -> SafeT IO a))
 -> (Vector ByteString -> IO (Vector ByteString -> IO a))
 -> Vector ByteString
 -> IO (Vector ByteString -> SafeT IO a))
-> ((IO a -> SafeT IO a)
    -> IO (Vector ByteString -> IO a)
    -> IO (Vector ByteString -> SafeT IO a))
-> (IO a -> SafeT IO a)
-> (Vector ByteString -> IO (Vector ByteString -> IO a))
-> Vector ByteString
-> IO (Vector ByteString -> SafeT IO a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Vector ByteString -> IO a) -> Vector ByteString -> SafeT IO a)
-> IO (Vector ByteString -> IO a)
-> IO (Vector ByteString -> SafeT IO a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Vector ByteString -> IO a) -> Vector ByteString -> SafeT IO a)
 -> IO (Vector ByteString -> IO a)
 -> IO (Vector ByteString -> SafeT IO a))
-> ((IO a -> SafeT IO a)
    -> (Vector ByteString -> IO a) -> Vector ByteString -> SafeT IO a)
-> (IO a -> SafeT IO a)
-> IO (Vector ByteString -> IO a)
-> IO (Vector ByteString -> SafeT IO a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (IO a -> SafeT IO a)
-> (Vector ByteString -> IO a) -> Vector ByteString -> SafeT IO a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) IO a -> SafeT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO)