Skip to content
Snippets Groups Projects
Editor.hs 1.44 KiB
Newer Older
{-# LANGUAGE FlexibleInstances, NamedFieldPuns, OverloadedStrings #-}
      Editable(..)
    , (<>.)
    , apply
    , fileFilter
    , xargs
  ) where

import Control.Monad.IO.Class (MonadIO(..))
import Data.ByteString.Lazy as BS (ByteString, pack, unpack)
import Data.Text as Text (Text, intercalate, lines, pack, unpack)
import Data.Text.IO as Text (readFile, writeFile)
import System.FilePath (replaceDirectory, replaceExtension)

class Editable a where
  enter :: Text -> a
  leave :: a -> Text

instance Editable [Text] where
  enter = Text.lines
  leave = Text.intercalate "\n"

instance Editable String where
  enter = Text.unpack
  leave = Text.pack

type Editor m = FilePath -> FilePath -> m ()

fileFilter :: (Editable a, Editable b, MonadIO m) =>
  (FilePath -> FilePath) -> (a -> m b) -> Editor m
fileFilter fixFormat transform target input =
  >>= transform . enter
  >>= liftIO . Text.writeFile output . leave
  where
    output = fixFormat $ replaceDirectory input target
(<>.) :: (Editable a, Editable b, MonadIO m) => (a -> m b) -> String -> Editor m
(<>.) transform extension = fileFilter (`replaceExtension` extension) transform
apply :: (Editable a, Editable b, MonadIO m) => (a -> m b) -> Editor m
apply = fileFilter id
xargs :: (Editable a, Editable b, MonadIO m) => (a -> m b) -> FilePath -> m ()
xargs transform target =
  Prelude.lines <$> liftIO getContents >>= mapM_ (apply transform target)