diff options
Diffstat (limited to 'cmd/Main.hs')
-rw-r--r-- | cmd/Main.hs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/cmd/Main.hs b/cmd/Main.hs new file mode 100644 index 0000000..bbc45cb --- /dev/null +++ b/cmd/Main.hs @@ -0,0 +1,76 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE QuasiQuotes #-} + +module Main + ( main + ) where + +import Control.Arrow ((&&&)) +import Control.Monad (when) +import Data.Version (showVersion) +import GHC.Generics (Generic) +import System.Environment (getArgs) +import System.Exit (die) + +import Data.Aeson (FromJSON, eitherDecode, encode) +import qualified Data.ByteString.Lazy as L +import qualified Data.HashMap.Strict as HM +import qualified System.Console.Docopt.NoTH as O +import Text.InterpolatedString.Perl6 (qc) + +import Malodivo.Budget (manyToOne) +import Malodivo.Types.Bill (Bill) +import Malodivo.Types.District (District) + +import Paths_malodivo (version) -- from cabal + +usage :: String +usage = + "malodivo " ++ + showVersion version ++ + " - budget planning tool for the Kingdom of Malodivo" ++ + [qc| + +This utility reads input JSON data from standard input +and writes output JSON data to standard output. + +Usage: malodivo [options] < input.json > output.json + +Options: + + -h, --help Show this message and exit + + +|] + +data DistrictInfo = DistrictInfo + { name :: District + , availableFunds :: Integer + } deriving (Generic, FromJSON) + +data SimpleInput = SimpleInput + { bills :: [Bill] + , districts :: [DistrictInfo] + } deriving (Generic, FromJSON) + +process :: IO () +process = do + input <- L.getContents + case eitherDecode input of + Left err -> die err + Right si -> do + let nbills = length . bills $ si + funds = + HM.fromListWith (+) . map (name &&& availableFunds) $ districts si + when (nbills /= 1) $ die "We needs exactly one bill in input" + when (HM.null funds) $ die "We needs at least one district" + L.putStr . encode $ manyToOne funds (head . bills $ si) + +main :: IO () +main = do + doco <- O.parseUsageOrExit usage + args <- O.parseArgsOrExit doco =<< getArgs + if args `O.isPresent` O.longOption "help" + then putStrLn $ O.usage doco + else process |