{-# LANGUAGE ScopedTypeVariables #-}

module QBar.Blocks.Utils where

import Control.Exception (IOException, catch)
import qualified Data.Attoparsec.Text.Lazy as AT
import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy.IO as TIO
import Numeric (showFFloat)

formatFloatN :: RealFloat a => Int -> a -> T.Text
formatFloatN = formatFloatN' 0

formatFloatN' :: RealFloat a => Int -> Int -> a -> T.Text
formatFloatN' padWithZeros decimalPlaces f = T.justifyRight (fromIntegral padWithZeros) '0' . T.pack $ showFFloat (Just decimalPlaces) f ""

ensure :: (a -> Bool) -> a -> Maybe a
ensure f a
  | f a = Just a
  | otherwise = Nothing

tryMaybe :: IO a -> IO (Maybe a)
tryMaybe a = tryMaybe' (Just <$> a)

tryMaybe' :: IO (Maybe a) -> IO (Maybe a)
tryMaybe' a = catch a (\(_ :: IOException) -> return Nothing)

parseFile :: FilePath -> AT.Parser a -> IO (Maybe a)
parseFile path parser = tryMaybe' $ do
  fileContents <- TIO.readFile path
  return . AT.maybeResult $ AT.parse parser fileContents