spectacle-1.0.0: src/Language/Spectacle/Interaction.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
-- | CLI interaction.
--
-- @since 1.0.0
module Language.Spectacle.Interaction
( -- * CLI
interaction,
handleInteraction,
)
where
import Control.Monad (when)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Reader (asks)
import Data.Either (isRight)
import Data.Hashable (Hashable)
import Data.Text.Prettyprint.Doc (line)
import Data.Functor.Tree (Tree)
import Data.Type.Rec (HasDict)
import Data.World (World)
import Language.Spectacle.Interaction.CLI (CLI, ContextCLI (ctxOpts), cliPutDoc, cliResultDoc, runCLI)
import Language.Spectacle.Interaction.Diagram (diagramFull, runDiagram)
import Language.Spectacle.Interaction.Options (OptsCLI (optsLogGraph, optsOnlyTrace))
import qualified Language.Spectacle.Interaction.Options as Opts
import Language.Spectacle.Interaction.Paths (toPointSet)
import Language.Spectacle.Model (modelcheck, modeltrace)
import Language.Spectacle.Model.ModelError (ModelError, ppModelError)
import Language.Spectacle.Specification (Specification)
-- ---------------------------------------------------------------------------------------------------------------------
interaction :: (HasDict Hashable ctx, HasDict Show ctx) => Specification ctx acts form -> IO ()
interaction spec = do
opts <- Opts.execOptsCLI
result <-
if optsOnlyTrace opts
then modeltrace spec
else modelcheck spec
runCLI (handleInteraction result) opts
handleInteraction :: HasDict Show ctx => Either (ModelError ctx) [Tree (World ctx)] -> CLI ()
handleInteraction result =
let status = isRight result
in case result of
Left err -> do
cliPutDoc =<< cliResultDoc status
cliPutDoc (ppModelError err)
cliPutDoc line
Right trees -> do
isLogging <- asks (optsLogGraph . ctxOpts)
when isLogging do
let pointSet = foldMap toPointSet trees
diagramDoc <- liftIO (runDiagram $ diagramFull pointSet)
cliPutDoc (diagramDoc <> line)
cliPutDoc =<< cliResultDoc status