packages feed

ipfs-1.3.2: library/Network/IPFS/Stat.hs

module Network.IPFS.Stat
  ( getStatRemote
  , getSizeRemote
  , getSize
  , module Network.IPFS.Stat.Types
  ) where

import           Data.ByteString.Lazy.Char8 as CL

import qualified RIO.ByteString.Lazy        as Lazy
import qualified RIO.List                   as List

import qualified Network.IPFS.Internal.UTF8 as UTF8
import           Network.IPFS.Local.Class   as IPFS
import           Network.IPFS.Prelude
import           Network.IPFS.Remote.Class  as Remote

import           Network.IPFS.Get.Error     as IPFS.Get
import qualified Network.IPFS.Process.Error as Process

import           Network.IPFS.Bytes.Types
import qualified Network.IPFS.Remote.Error  as Remote
import           Network.IPFS.Stat.Types
import           Network.IPFS.Types         as IPFS

getStatRemote :: MonadRemoteIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Stat)
getStatRemote cid =
  Remote.ipfsStat cid >>= \case
    Right statPayload           -> return $ Right statPayload
    Left (Remote.WebError err)  -> return . Left $ IPFS.Get.WebError err
    Left (Remote.SizeError err) -> return . Left $ IPFS.Get.SizeError err

getSizeRemote :: MonadRemoteIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Bytes)
getSizeRemote cid =
  getStatRemote cid >>= \case
    Left err ->
      return $ Left err

    Right Stat {cumulativeSize} ->
      case cumulativeSize of
        Left err   -> return $ Left $ IPFS.Get.SizeError err
        Right size -> return $ Right size

getSize :: MonadLocalIPFS m => IPFS.CID -> m (Either IPFS.Get.Error Integer)
getSize cid@(CID hash) = IPFS.runLocal ["object", "stat"] (Lazy.fromStrict <| encodeUtf8 hash) >>= \case
  Left err -> case err of
    Process.Timeout secs   -> return . Left $ TimedOut cid secs
    Process.UnknownErr raw -> return . Left . UnknownErr $ UTF8.textShow raw

  Right contents ->
    case parseSize contents of
      Nothing        -> return . Left . UnexpectedOutput $ "Could not parse CumulativeSize"
      Just (size, _) -> return $ Right size

parseSize :: Lazy.ByteString -> Maybe (Integer, Lazy.ByteString)
parseSize lbs = do
  finalLine <- List.lastMaybe $ CL.lines lbs
  finalWord <- List.lastMaybe $ CL.words finalLine
  CL.readInteger finalWord