From 81b0437bb7623d90e512d9d9947c5e3f7719c886 Mon Sep 17 00:00:00 2001 From: Alexander Kobjolke Date: Sun, 13 Aug 2023 10:55:57 +0200 Subject: [PATCH] Implement a tiny cat version We only support a single file which gets written to stdout. Non-existing files or other errors are printed to stderr and the program terminates. --- app/hcat.hs | 2 +- src/HCat.hs | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/hcat.hs b/app/hcat.hs index eef1e4d..c1b3966 100644 --- a/app/hcat.hs +++ b/app/hcat.hs @@ -3,4 +3,4 @@ module Main (main) where import HCat qualified main :: IO () -main = HCat.runHCat +main = HCat.defaultMain diff --git a/src/HCat.hs b/src/HCat.hs index 86d3f01..6be48ae 100644 --- a/src/HCat.hs +++ b/src/HCat.hs @@ -1,6 +1,32 @@ module HCat ( runHCat, + defaultMain, ) where +import System.Environment qualified as Env +import System.IO (hPutStrLn, stderr) + +import Control.Exception qualified as Exception +import System.IO.Error qualified as IOError + +parseArgs :: [String] -> Either String FilePath +parseArgs args = case args of + [] -> Left "No filename given!" + [arg] -> Right arg + _ -> Left "Only a single file is supported" + runHCat :: IO () -runHCat = pure () +runHCat = do + fileNameOrError <- parseArgs <$> Env.getArgs + fileName <- eitherToError fileNameOrError + readFile fileName >>= putStr + +eitherToError :: Show a => Either a b -> IO b +eitherToError = either (Exception.throwIO . IOError.userError . show) return + +handleError :: IOError -> IO () +handleError e = do + hPutStrLn stderr $ "I ran into an issue: " <> show e + +defaultMain :: IO () +defaultMain = Exception.catch runHCat handleError