{-# LANGUAGE CPP, NoImplicitPrelude #-}
module System.IO.Compat (
  module Base
, getContents'
, hGetContents'
, readFile'
) where

import System.IO as Base

#if !(MIN_VERSION_base(4,15,0))
import Prelude.Compat

-- | The 'getContents'' operation returns all user input as a single string,
-- which is fully read before being returned
-- (same as 'hGetContents'' 'stdin').
--
-- /Since: 4.15.0.0/

getContents'    :: IO String
getContents' :: IO String
getContents'    =  Handle -> IO String
hGetContents' Handle
stdin

-- | The 'readFile'' function reads a file and
-- returns the contents of the file as a string.
-- The file is fully read before being returned, as with 'getContents''.
--
-- /Since: 4.15.0.0/

readFile'       :: FilePath -> IO String
readFile' :: String -> IO String
readFile' String
name  =  String -> IOMode -> IO Handle
openFile String
name IOMode
ReadMode IO Handle -> (Handle -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Handle -> IO String
hGetContents'

-- | The 'hGetContents'' operation reads all input on the given handle
-- before returning it as a 'String' and closing the handle.
--
-- /Since: 4.15.0.0/

hGetContents'   :: Handle -> IO String
hGetContents' :: Handle -> IO String
hGetContents' Handle
h =  Handle -> IO String
hGetContents Handle
h IO String -> (String -> IO String) -> IO String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \String
s -> String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s Int -> IO String -> IO String
`seq` String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
s
 -- NB: The actual implementation of hGetContents' in `base` uses a lot of
 -- low-level code from GHC.IO.Handle.Text. What's worse, a lot of this
 -- low-level code isn't exported, so we'd have to reimplement large chunks
 -- of it in base-compat if we wanted to backport it. For now, I've opted for
 -- the simpler approach of simply defining hGetContents' in terms of
 -- hGetContents, which is the approach that the `extra` and `strict` libraries
 -- use. (Indeed, the code above is taken from `strict`.)
#endif