{-# OPTIONS_GHC -fno-warn-orphans #-}

-- | Utility functions that may be ultimately moved to some library.
module JsonToType.Util( withFileOrHandle
                               , withFileOrDefaultHandle
                               ) where

import           Data.Hashable
import qualified Data.Set as Set
import           System.IO                 (withFile, IOMode(..), Handle, stdin, stdout)

-- | Generic function for opening file if the filename is not empty nor "-",
--   or using given handle otherwise (probably stdout, stderr, or stdin).
-- TODO: Should it become utility function?
withFileOrHandle :: FilePath -> IOMode -> Handle -> (Handle -> IO r) -> IO r
withFileOrHandle :: forall r. FilePath -> IOMode -> Handle -> (Handle -> IO r) -> IO r
withFileOrHandle        FilePath
""       IOMode
_         Handle
handle Handle -> IO r
action =                      Handle -> IO r
action Handle
handle
withFileOrHandle        FilePath
"-"      IOMode
_         Handle
handle Handle -> IO r
action =                      Handle -> IO r
action Handle
handle
withFileOrHandle        FilePath
name     IOMode
ioMode    Handle
_      Handle -> IO r
action = FilePath -> IOMode -> (Handle -> IO r) -> IO r
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
name IOMode
ioMode Handle -> IO r
action

-- | Generic function for choosing either file with given name or stdin/stdout as input/output.
-- It accepts the function that takes the corresponding handle.
-- Stdin/stdout is selected by "-".
withFileOrDefaultHandle :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFileOrDefaultHandle :: forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFileOrDefaultHandle FilePath
"-"      IOMode
ReadMode         Handle -> IO r
action = Handle -> IO r
action Handle
stdin
withFileOrDefaultHandle FilePath
"-"      IOMode
WriteMode        Handle -> IO r
action = Handle -> IO r
action Handle
stdout
withFileOrDefaultHandle FilePath
"-"      IOMode
otherMode        Handle -> IO r
_      = FilePath -> IO r
forall a. HasCallStack => FilePath -> a
error (FilePath -> IO r) -> FilePath -> IO r
forall a b. (a -> b) -> a -> b
$ FilePath
"Incompatible io mode ("
                                                                FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ IOMode -> FilePath
forall a. Show a => a -> FilePath
show IOMode
otherMode
                                                                FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
") for `-` in withFileOrDefaultHandle."
withFileOrDefaultHandle FilePath
filename IOMode
ioMode           Handle -> IO r
action = FilePath -> IOMode -> (Handle -> IO r) -> IO r
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
filename IOMode
ioMode Handle -> IO r
action