{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Require.File where
import Relude
import qualified Data.Text.IO as TIO
newtype Name = Name Text
data Input = Input
{ Input -> Name
inputName :: Name,
Input -> Text
inputContent :: Text
}
newtype LineNumber = LineNumber Int
deriving (Int -> LineNumber
LineNumber -> Int
LineNumber -> [LineNumber]
LineNumber -> LineNumber
LineNumber -> LineNumber -> [LineNumber]
LineNumber -> LineNumber -> LineNumber -> [LineNumber]
(LineNumber -> LineNumber)
-> (LineNumber -> LineNumber)
-> (Int -> LineNumber)
-> (LineNumber -> Int)
-> (LineNumber -> [LineNumber])
-> (LineNumber -> LineNumber -> [LineNumber])
-> (LineNumber -> LineNumber -> [LineNumber])
-> (LineNumber -> LineNumber -> LineNumber -> [LineNumber])
-> Enum LineNumber
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: LineNumber -> LineNumber -> LineNumber -> [LineNumber]
$cenumFromThenTo :: LineNumber -> LineNumber -> LineNumber -> [LineNumber]
enumFromTo :: LineNumber -> LineNumber -> [LineNumber]
$cenumFromTo :: LineNumber -> LineNumber -> [LineNumber]
enumFromThen :: LineNumber -> LineNumber -> [LineNumber]
$cenumFromThen :: LineNumber -> LineNumber -> [LineNumber]
enumFrom :: LineNumber -> [LineNumber]
$cenumFrom :: LineNumber -> [LineNumber]
fromEnum :: LineNumber -> Int
$cfromEnum :: LineNumber -> Int
toEnum :: Int -> LineNumber
$ctoEnum :: Int -> LineNumber
pred :: LineNumber -> LineNumber
$cpred :: LineNumber -> LineNumber
succ :: LineNumber -> LineNumber
$csucc :: LineNumber -> LineNumber
Enum)
data LineTag = LineTag !Name !LineNumber
initialLineTag :: Input -> LineTag
initialLineTag :: Input -> LineTag
initialLineTag Input
inp = Name -> LineNumber -> LineTag
LineTag (Input -> Name
inputName Input
inp) (Int -> LineNumber
LineNumber Int
1)
advanceLineTag :: LineTag -> LineTag
advanceLineTag :: LineTag -> LineTag
advanceLineTag (LineTag Name
fn LineNumber
ln) = Name -> LineNumber -> LineTag
LineTag Name
fn (LineNumber -> LineNumber
forall a. Enum a => a -> a
succ LineNumber
ln)
read :: Name -> IO Input
read :: Name -> IO Input
read Name
f = Name -> Text -> Input
Input Name
f (Text -> Input) -> IO Text -> IO Input
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO Text
forall (m :: * -> *). MonadIO m => FilePath -> m Text
readFileText (Name -> FilePath
nameToPath Name
f)
writeLines :: Name -> [Text] -> IO ()
writeLines :: Name -> [Text] -> IO ()
writeLines Name
name [Text]
theLines = FilePath -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile (Name -> FilePath
nameToPath Name
name) IOMode
WriteMode ((Handle -> IO ()) -> IO ()) -> (Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Handle
h ->
(Text -> IO ()) -> [Text] -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Handle -> Text -> IO ()
TIO.hPutStrLn Handle
h) [Text]
theLines
inputLines :: Input -> [(LineTag, Text)]
inputLines :: Input -> [(LineTag, Text)]
inputLines Input
fi = [LineTag] -> [Text] -> [(LineTag, Text)]
forall a b. [a] -> [b] -> [(a, b)]
zip [LineTag]
lineTags [Text]
contents
where
lineTags :: [LineTag]
lineTags = (LineTag -> LineTag) -> LineTag -> [LineTag]
forall a. (a -> a) -> a -> [a]
iterate LineTag -> LineTag
advanceLineTag (Input -> LineTag
initialLineTag Input
fi)
contents :: [Text]
contents = Text -> [Text]
forall t. IsText t "lines" => t -> [t]
lines (Input -> Text
inputContent Input
fi)
nameToPath :: Name -> FilePath
nameToPath :: Name -> FilePath
nameToPath (Name Text
fp) = Text -> FilePath
forall a. ToString a => a -> FilePath
toString Text
fp