module AOC.Run.Interactive (
execSolution
, execSolutionWith
, testSolution
, viewPrompt
, waitForPrompt
, submitSolution
, execSolution_
, execSolutionWith_
, testSolution_
, viewPrompt_
, waitForPrompt_
, submitSolution_
, loadInput
, loadTests
, mkSpec
) where
import AOC.Challenge
import AOC.Run
import AOC.Run.Config
import AOC.Run.Load
import AOC.Util
import Advent
import Control.Monad.Except
import Data.Finite
import Data.Text (Text)
import Text.Printf
execSolution :: ChallengeSpec -> IO String
execSolution cs = eitherIO $ do
cfg <- liftIO $ configFile defConfPath
out <- mainRun cfg . defaultMRO $ TSDayPart cs
res <- maybeToEither ["Result not found in result map (Internal Error)"] $
lookupSolution cs out
liftEither $ snd res
execSolutionWith
:: ChallengeSpec
-> String
-> IO String
execSolutionWith cs inp = eitherIO $ do
cfg <- liftIO $ configFile defConfPath
out <- mainRun cfg $ (defaultMRO (TSDayPart cs))
{ _mroInput = \_ _ -> pure $ Just inp
}
res <- maybeToEither ["Result not found in result map (Internal Error)"] $
lookupSolution cs out
liftEither $ snd res
testSolution :: ChallengeSpec -> IO (Maybe Bool)
testSolution cs = eitherIO $ do
cfg <- liftIO $ configFile defConfPath
out <- mainRun cfg $ (defaultMRO (TSDayPart cs))
{ _mroTest = True
}
res <- maybeToEither ["Result not found in result map (Internal Error)"] $
lookupSolution cs out
pure $ fst res
viewPrompt :: ChallengeSpec -> IO Text
viewPrompt cs@CS{..} = eitherIO $ do
cfg <- liftIO $ configFile defConfPath
out <- mainView cfg . defaultMVO $ TSDayPart cs
maybeToEither ["Prompt not found in result map (Internal Error)"] $
lookupSolution cs out
waitForPrompt :: ChallengeSpec -> IO Text
waitForPrompt cs@CS{..} = eitherIO $ do
cfg <- liftIO $ configFile defConfPath
out <- mainView cfg $ (defaultMVO (TSDayPart cs))
{ _mvoWait = True
}
maybeToEither ["Prompt not found in result map (Internal Error)"] $
lookupSolution cs out
submitSolution :: ChallengeSpec -> IO (Text, SubmitRes)
submitSolution cs = eitherIO $ do
cfg <- liftIO $ configFile defConfPath
mainSubmit cfg . defaultMSO $ cs
execSolution_ :: ChallengeSpec -> IO ()
execSolution_ = void . execSolution
execSolutionWith_
:: ChallengeSpec
-> String
-> IO ()
execSolutionWith_ cs = void . execSolutionWith cs
testSolution_ :: ChallengeSpec -> IO ()
testSolution_ = void . testSolution
viewPrompt_ :: ChallengeSpec -> IO ()
viewPrompt_ = void . viewPrompt
waitForPrompt_ :: ChallengeSpec -> IO ()
waitForPrompt_ = void . waitForPrompt
submitSolution_ :: ChallengeSpec -> IO ()
submitSolution_ = void . submitSolution
loadInput :: ChallengeSpec -> IO String
loadInput cs = eitherIO $ do
CD{..} <- liftIO $ do
Cfg{..} <- configFile defConfPath
challengeData _cfgSession _cfgYear cs
liftEither _cdInput
loadTests :: ChallengeSpec -> IO [(String, TestMeta)]
loadTests cs = do
Cfg{..} <- configFile defConfPath
_cdTests <$> challengeData _cfgSession _cfgYear cs
mkSpec :: Integer -> Part -> ChallengeSpec
mkSpec i c = maybe e (`CS` c) . packFinite $ i - 1
where
e = errorWithoutStackTrace $ printf "Day out of range: %d" i
eitherIO :: ExceptT [String] IO a -> IO a
eitherIO act = runExceptT act >>= \case
Right x -> pure x
Left es -> fail $ unlines es