{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- |
-- Module      :  Network.Ipfs.Client
-- Copyright   :  Aleksandr Krupenkin 2016-2021
-- License     :  Apache-2.0
--
-- Maintainer  :  mail@akru.me
-- Stability   :  experimental
-- Portability :  unknown
--
-- IPFS daemon HTTP client.
--

module Network.Ipfs.Client where

import           Control.Monad.Except
import           Control.Monad.Reader
import           Network.HTTP.Client  as Net hiding (Proxy)
import           Servant.Client

newtype IpfsT m a = IpfsT { IpfsT m a
-> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
unIpfs :: ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a }
  deriving ( a -> IpfsT m b -> IpfsT m a
(a -> b) -> IpfsT m a -> IpfsT m b
(forall a b. (a -> b) -> IpfsT m a -> IpfsT m b)
-> (forall a b. a -> IpfsT m b -> IpfsT m a) -> Functor (IpfsT m)
forall a b. a -> IpfsT m b -> IpfsT m a
forall a b. (a -> b) -> IpfsT m a -> IpfsT m b
forall (m :: * -> *) a b. Functor m => a -> IpfsT m b -> IpfsT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> IpfsT m a -> IpfsT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> IpfsT m b -> IpfsT m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> IpfsT m b -> IpfsT m a
fmap :: (a -> b) -> IpfsT m a -> IpfsT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> IpfsT m a -> IpfsT m b
Functor
           , Functor (IpfsT m)
a -> IpfsT m a
Functor (IpfsT m)
-> (forall a. a -> IpfsT m a)
-> (forall a b. IpfsT m (a -> b) -> IpfsT m a -> IpfsT m b)
-> (forall a b c.
    (a -> b -> c) -> IpfsT m a -> IpfsT m b -> IpfsT m c)
-> (forall a b. IpfsT m a -> IpfsT m b -> IpfsT m b)
-> (forall a b. IpfsT m a -> IpfsT m b -> IpfsT m a)
-> Applicative (IpfsT m)
IpfsT m a -> IpfsT m b -> IpfsT m b
IpfsT m a -> IpfsT m b -> IpfsT m a
IpfsT m (a -> b) -> IpfsT m a -> IpfsT m b
(a -> b -> c) -> IpfsT m a -> IpfsT m b -> IpfsT m c
forall a. a -> IpfsT m a
forall a b. IpfsT m a -> IpfsT m b -> IpfsT m a
forall a b. IpfsT m a -> IpfsT m b -> IpfsT m b
forall a b. IpfsT m (a -> b) -> IpfsT m a -> IpfsT m b
forall a b c. (a -> b -> c) -> IpfsT m a -> IpfsT m b -> IpfsT m c
forall (m :: * -> *). Monad m => Functor (IpfsT m)
forall (m :: * -> *) a. Monad m => a -> IpfsT m a
forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> IpfsT m b -> IpfsT m a
forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> IpfsT m b -> IpfsT m b
forall (m :: * -> *) a b.
Monad m =>
IpfsT m (a -> b) -> IpfsT m a -> IpfsT m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> IpfsT m a -> IpfsT m b -> IpfsT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: IpfsT m a -> IpfsT m b -> IpfsT m a
$c<* :: forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> IpfsT m b -> IpfsT m a
*> :: IpfsT m a -> IpfsT m b -> IpfsT m b
$c*> :: forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> IpfsT m b -> IpfsT m b
liftA2 :: (a -> b -> c) -> IpfsT m a -> IpfsT m b -> IpfsT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> IpfsT m a -> IpfsT m b -> IpfsT m c
<*> :: IpfsT m (a -> b) -> IpfsT m a -> IpfsT m b
$c<*> :: forall (m :: * -> *) a b.
Monad m =>
IpfsT m (a -> b) -> IpfsT m a -> IpfsT m b
pure :: a -> IpfsT m a
$cpure :: forall (m :: * -> *) a. Monad m => a -> IpfsT m a
$cp1Applicative :: forall (m :: * -> *). Monad m => Functor (IpfsT m)
Applicative
           , Applicative (IpfsT m)
a -> IpfsT m a
Applicative (IpfsT m)
-> (forall a b. IpfsT m a -> (a -> IpfsT m b) -> IpfsT m b)
-> (forall a b. IpfsT m a -> IpfsT m b -> IpfsT m b)
-> (forall a. a -> IpfsT m a)
-> Monad (IpfsT m)
IpfsT m a -> (a -> IpfsT m b) -> IpfsT m b
IpfsT m a -> IpfsT m b -> IpfsT m b
forall a. a -> IpfsT m a
forall a b. IpfsT m a -> IpfsT m b -> IpfsT m b
forall a b. IpfsT m a -> (a -> IpfsT m b) -> IpfsT m b
forall (m :: * -> *). Monad m => Applicative (IpfsT m)
forall (m :: * -> *) a. Monad m => a -> IpfsT m a
forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> IpfsT m b -> IpfsT m b
forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> (a -> IpfsT m b) -> IpfsT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> IpfsT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> IpfsT m a
>> :: IpfsT m a -> IpfsT m b -> IpfsT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> IpfsT m b -> IpfsT m b
>>= :: IpfsT m a -> (a -> IpfsT m b) -> IpfsT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
IpfsT m a -> (a -> IpfsT m b) -> IpfsT m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (IpfsT m)
Monad
           , Monad (IpfsT m)
Monad (IpfsT m)
-> (forall a. IO a -> IpfsT m a) -> MonadIO (IpfsT m)
IO a -> IpfsT m a
forall a. IO a -> IpfsT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (IpfsT m)
forall (m :: * -> *) a. MonadIO m => IO a -> IpfsT m a
liftIO :: IO a -> IpfsT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> IpfsT m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (IpfsT m)
MonadIO
           , MonadReader (Manager, BaseUrl, String)
           , MonadError ClientError
           )

instance MonadTrans IpfsT where
  lift :: m a -> IpfsT m a
lift = ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
-> IpfsT m a
forall (m :: * -> *) a.
ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
-> IpfsT m a
IpfsT (ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
 -> IpfsT m a)
-> (m a
    -> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a)
-> m a
-> IpfsT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT ClientError m a
-> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ExceptT ClientError m a
 -> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a)
-> (m a -> ExceptT ClientError m a)
-> m a
-> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ExceptT ClientError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

type Ipfs a = IpfsT IO a

-- | 'IpfsT' monad runner.
runIpfs' :: BaseUrl -> Ipfs a -> IO ()
runIpfs' :: BaseUrl -> Ipfs a -> IO ()
runIpfs' BaseUrl
url Ipfs a
ipfs = do
  Manager
manager' <- IO Manager -> IO Manager
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Manager -> IO Manager) -> IO Manager -> IO Manager
forall a b. (a -> b) -> a -> b
$ ManagerSettings -> IO Manager
newManager ManagerSettings
defaultManagerSettings
  Either ClientError a
ret <- ExceptT ClientError IO a -> IO (Either ClientError a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ReaderT (Manager, BaseUrl, String) (ExceptT ClientError IO) a
-> (Manager, BaseUrl, String) -> ExceptT ClientError IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (Ipfs a
-> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError IO) a
forall (m :: * -> *) a.
IpfsT m a
-> ReaderT (Manager, BaseUrl, String) (ExceptT ClientError m) a
unIpfs Ipfs a
ipfs) (Manager
manager', BaseUrl
url, BaseUrl -> String
showBaseUrl BaseUrl
url))
  case Either ClientError a
ret of
    Left ClientError
err -> String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Error: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ ClientError -> String
forall a. Show a => a -> String
show ClientError
err
    Right a
_  -> String -> IO ()
putStr String
""

-- | 'IpfsT' monad runner with default arguments.
runIpfs :: Ipfs a -> IO ()
runIpfs :: Ipfs a -> IO ()
runIpfs = BaseUrl -> Ipfs a -> IO ()
forall a. BaseUrl -> Ipfs a -> IO ()
runIpfs' (Scheme -> String -> Int -> String -> BaseUrl
BaseUrl Scheme
Http String
"localhost" Int
5001 String
"/api/v0")