winery-0: app/Main.hs
{-# LANGUAGE LambdaCase #-}
module Main where
import Control.Monad
import qualified Data.ByteString as B
import Data.Text.Prettyprint.Doc
import Data.Text.Prettyprint.Doc.Render.Terminal
import Data.Winery.Term
import Data.Winery
import System.Console.GetOpt
import System.Environment
import System.Exit
import System.IO
data Options = Options
{ streamInput :: Bool
, separateSchema :: Maybe (Maybe FilePath)
, printSchema :: Bool
}
defaultOptions :: Options
defaultOptions = Options
{ streamInput = False
, printSchema = False
, separateSchema = Nothing
}
options :: [OptDescr (Options -> Options)]
options =
[ Option "s" ["stream"] (NoArg $ \o -> o { streamInput = True }) "stream input"
, Option "S" ["separate-schema"] (OptArg (\s o -> o { separateSchema = Just s }) "PATH") "the schema is separated"
, Option "" ["print-schema"] (NoArg $ \o -> o { printSchema = True }) "print the schema"
]
getRight :: Either StrategyError a -> IO a
getRight (Left err) = do
hPutDoc stderr err
exitFailure
getRight (Right a) = return a
main = getOpt Permute options <$> getArgs >>= \case
(fs, _, []) -> do
let o = foldl (flip id) defaultOptions fs
printer <- case separateSchema o of
Just mpath -> do
bs <- maybe (readLn >>= B.hGet stdin) B.readFile mpath
sch <- getRight $ deserialise bs
when (printSchema o) $ putDoc $ pretty sch <> hardline
dec <- getRight $ getDecoderBy decodeTerm sch
return $ \bs -> putDoc $ pretty (dec bs) <> hardline
Nothing -> return $ \bs -> do
(s, t) <- getRight $ deserialiseTerm bs
when (printSchema o) $ putDoc $ pretty s <> hardline
putDoc $ pretty t <> hardline
case streamInput o of
False -> B.hGetContents stdin >>= printer
True -> forever $ do
n <- readLn
B.hGet stdin n >>= printer
(_, _, es) -> do
name <- getProgName
die $ unlines es ++ usageInfo name options