{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}
module Funflow.Flow
( Flow,
ExtendedFlow,
RequiredStrands,
RequiredCore,
IsFlow,
toFlow,
pureFlow,
ioFlow,
dockerFlow,
putDirFlow,
getDirFlow,
throwStringFlow,
returnFlow,
)
where
import Control.Arrow (Arrow, ArrowChoice, returnA)
import Control.Exception.Safe (SomeException, StringException, throwString)
import Control.Kernmantle.Caching (ProvidesCaching)
import Control.Kernmantle.Error (ThrowEffect, TryEffect)
import Control.Kernmantle.Rope (AnyRopeWith, HasKleisli, strand)
import Control.Monad.IO.Class (MonadIO)
import Data.CAS.ContentStore as CS
import Docker.API.Client (DockerClientError)
import Funflow.Tasks.Docker (DockerTask (DockerTask), DockerTaskConfig, DockerTaskInput)
import Funflow.Tasks.Simple (SimpleTask (IOTask, PureTask))
import Funflow.Tasks.Store (StoreTask (GetDir, PutDir))
import Funflow.Type.Family.List (type (++))
import Path (Abs, Dir, Path)
type RequiredStrands =
'[ '("simple", SimpleTask),
'("store", StoreTask),
'("docker", DockerTask)
]
type RequiredCore m =
'[
Arrow,
ArrowChoice,
ThrowEffect SomeException,
TryEffect SomeException,
ThrowEffect StringException,
TryEffect StringException,
ThrowEffect DockerClientError,
TryEffect DockerClientError,
HasKleisli m,
ProvidesCaching
]
type Flow input output = ExtendedFlow '[] input output
type ExtendedFlow additionalStrands input output =
forall m.
(MonadIO m) =>
AnyRopeWith
(additionalStrands ++ RequiredStrands)
(RequiredCore m)
input
output
class IsFlow binEff where
toFlow :: binEff i o -> Flow i o
instance IsFlow SimpleTask where
toFlow :: SimpleTask i o -> Flow i o
toFlow = Label "simple" -> SimpleTask :-> Rope r mantle core
forall (l :: Symbol) (eff :: * -> * -> *) (r :: RopeRec)
(m :: [Strand]) (c :: * -> * -> *).
InRope l eff (Rope r m c) =>
Label l -> eff :-> Rope r m c
strand IsLabel "simple" (Label "simple")
Label "simple"
#simple
pureFlow :: (i -> o) -> Flow i o
pureFlow :: (i -> o) -> Flow i o
pureFlow = SimpleTask i o -> Rope r mantle core i o
forall (binEff :: * -> * -> *) i o.
IsFlow binEff =>
binEff i o -> Flow i o
toFlow (SimpleTask i o -> Rope r mantle core i o)
-> ((i -> o) -> SimpleTask i o)
-> (i -> o)
-> Rope r mantle core i o
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i -> o) -> SimpleTask i o
forall i o. (i -> o) -> SimpleTask i o
PureTask
ioFlow :: (i -> IO o) -> Flow i o
ioFlow :: (i -> IO o) -> Flow i o
ioFlow = SimpleTask i o -> Rope r mantle core i o
forall (binEff :: * -> * -> *) i o.
IsFlow binEff =>
binEff i o -> Flow i o
toFlow (SimpleTask i o -> Rope r mantle core i o)
-> ((i -> IO o) -> SimpleTask i o)
-> (i -> IO o)
-> Rope r mantle core i o
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i -> IO o) -> SimpleTask i o
forall i o. (i -> IO o) -> SimpleTask i o
IOTask
instance IsFlow DockerTask where
toFlow :: DockerTask i o -> Flow i o
toFlow = Label "docker" -> DockerTask :-> Rope r mantle core
forall (l :: Symbol) (eff :: * -> * -> *) (r :: RopeRec)
(m :: [Strand]) (c :: * -> * -> *).
InRope l eff (Rope r m c) =>
Label l -> eff :-> Rope r m c
strand IsLabel "docker" (Label "docker")
Label "docker"
#docker
dockerFlow :: DockerTaskConfig -> Flow DockerTaskInput CS.Item
dockerFlow :: DockerTaskConfig -> Flow DockerTaskInput Item
dockerFlow = DockerTask DockerTaskInput Item
-> Rope r mantle core DockerTaskInput Item
forall (binEff :: * -> * -> *) i o.
IsFlow binEff =>
binEff i o -> Flow i o
toFlow (DockerTask DockerTaskInput Item
-> Rope r mantle core DockerTaskInput Item)
-> (DockerTaskConfig -> DockerTask DockerTaskInput Item)
-> DockerTaskConfig
-> Rope r mantle core DockerTaskInput Item
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DockerTaskConfig -> DockerTask DockerTaskInput Item
DockerTask
instance IsFlow StoreTask where
toFlow :: StoreTask i o -> Flow i o
toFlow = Label "store" -> StoreTask :-> Rope r mantle core
forall (l :: Symbol) (eff :: * -> * -> *) (r :: RopeRec)
(m :: [Strand]) (c :: * -> * -> *).
InRope l eff (Rope r m c) =>
Label l -> eff :-> Rope r m c
strand IsLabel "store" (Label "store")
Label "store"
#store
putDirFlow :: Flow (Path Abs Dir) CS.Item
putDirFlow :: AnyRopeWith
('[] ++ RequiredStrands) (RequiredCore m) (Path Abs Dir) Item
putDirFlow = StoreTask (Path Abs Dir) Item -> Flow (Path Abs Dir) Item
forall (binEff :: * -> * -> *) i o.
IsFlow binEff =>
binEff i o -> Flow i o
toFlow StoreTask (Path Abs Dir) Item
PutDir
getDirFlow :: Flow (CS.Item) (Path Abs Dir)
getDirFlow :: AnyRopeWith
('[] ++ RequiredStrands) (RequiredCore m) Item (Path Abs Dir)
getDirFlow = StoreTask Item (Path Abs Dir) -> Flow Item (Path Abs Dir)
forall (binEff :: * -> * -> *) i o.
IsFlow binEff =>
binEff i o -> Flow i o
toFlow StoreTask Item (Path Abs Dir)
GetDir
throwStringFlow :: Flow String ()
throwStringFlow :: AnyRopeWith ('[] ++ RequiredStrands) (RequiredCore m) String ()
throwStringFlow = (String -> IO ()) -> Flow String ()
forall i o. (i -> IO o) -> Flow i o
ioFlow ((String -> IO ()) -> Flow String ())
-> (String -> IO ()) -> Flow String ()
forall a b. (a -> b) -> a -> b
$ \String
message -> String -> IO ()
forall (m :: * -> *) a.
(MonadThrow m, HasCallStack) =>
String -> m a
throwString String
message
returnFlow :: Flow a a
returnFlow :: AnyRopeWith ('[] ++ RequiredStrands) (RequiredCore m) a a
returnFlow = Rope r mantle core a a
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA