bytepatch-0.2.1: app/Main.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Main ( main ) where
import Config
import qualified Options
import BytePatch.Pretty
import BytePatch.Pretty.PatchRep
import BytePatch.JSON()
import qualified BytePatch.Linear.Patch as Linear
import qualified BytePatch.Linear.Gen as Linear
import Control.Monad.IO.Class
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import qualified Data.Yaml as Yaml
import Data.Aeson ( FromJSON )
import Data.Text ( Text )
import BytePatch.Pretty.HexByteString
main :: IO ()
main = Options.parse >>= run
run :: MonadIO m => Config -> m ()
run cfg = do
return ()
tryReadPatchscript @HexByteString (cfgPatchscript cfg) >>= \case
Nothing -> quit "couldn't parse patchscript"
Just ps ->
case normalizeSimple ps of
Nothing -> quit "failed while normalizing patchscript"
Just p ->
case Linear.gen p of
(_, genErrs@(_:_)) -> quit' "patchscript generation failed" genErrs
(ps', []) -> do
bs <- readStream' io
case Linear.patchPure (cfgPatchCfg cfg) ps' bs of
Left patchErr -> quit' "patching failed" patchErr
Right bs' -> writeStream' io (BL.toStrict bs')
where
io = cfgStreamInOut cfg
readStream :: MonadIO m => CStream -> m BS.ByteString
readStream stream = liftIO $
case stream of
CStreamStd -> BS.getContents
CStreamFile fp -> BS.readFile fp
readStream' :: MonadIO m => CStreamInOut -> m BS.ByteString
readStream' = readStream . fst . unCStreamInOut
writeStream :: MonadIO m => CStream -> BS.ByteString -> m ()
writeStream stream bs = liftIO $
case stream of
CStreamStd -> BS.putStr bs
CStreamFile fp -> BS.writeFile fp bs
writeStream' :: MonadIO m => CStreamInOut -> BS.ByteString -> m ()
writeStream' stream = writeStream (snd (unCStreamInOut stream))
quit' :: (MonadIO m, Show a) => String -> a -> m ()
quit' msg a = liftIO $ do
putStrLn $ "bytepatch: error: " <> msg
print a
quit :: MonadIO m => String -> m ()
quit = liftIO . putStrLn
tryReadPatchscript :: forall a m. (PatchRep a, FromJSON a, MonadIO m) => FilePath -> m (Maybe [CommonMultiEdits a])
tryReadPatchscript = tryDecodeYaml
tryDecodeYaml :: (FromJSON a, MonadIO m) => FilePath -> m (Maybe a)
tryDecodeYaml fp = do
bs <- liftIO $ BS.readFile fp
case Yaml.decodeEither' bs of
Left _ -> return Nothing
Right parsed -> return $ Just parsed