{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Path.Text.UTF8
(
readFile
, tryReadFile
, ReadError (..)
, writeFile
, tryWriteFile
, WriteError
, IOError
, UnicodeException (DecodeError)
, parseAbsFile
, parseRelFile
) where
import Data.Either (Either (..))
import Data.Functor ((<$>))
import System.IO (IO)
import System.IO.Error (IOError)
import qualified Control.Exception.Safe as Exception
import qualified Data.ByteString as BS
import Data.Text (Text)
import qualified Data.Text.Encoding as TextEncoding
import Data.Text.Encoding.Error (UnicodeException (..))
import Path (Path, parseAbsFile, parseRelFile)
import qualified Path
data ReadError
= ReadErrorIO IOError
| ReadErrorDecode UnicodeException
type WriteError = IOError
readFile :: Path base Path.File -> IO Text
readFile path =
f <$> BS.readFile (Path.toFilePath path)
where
f bs = let !text = TextEncoding.decodeUtf8 bs in text
tryReadFile :: Path base Path.File -> IO (Either ReadError Text)
tryReadFile path =
f <$> Exception.tryIO (BS.readFile (Path.toFilePath path))
where
f (Left e) = Left (ReadErrorIO e)
f (Right bs) = first ReadErrorDecode (TextEncoding.decodeUtf8' bs)
writeFile :: Path base Path.File -> Text -> IO ()
writeFile path text =
BS.writeFile (Path.toFilePath path) (TextEncoding.encodeUtf8 text)
tryWriteFile :: Path base Path.File -> Text -> IO (Either WriteError ())
tryWriteFile path text =
Exception.tryIO (writeFile path text)
first :: (a -> a') -> Either a b -> Either a' b
first f (Left x) = Left (f x)
first _ (Right x) = Right x