content: 
  module Test.Sandwich.Interpreters.PrettyShow (prettyShow) where
  
  import Control.Monad.Free
  import qualified Data.List as L
  import Test.Sandwich.Types.Spec
  
  
  -- | Pretty show a spec tree
  prettyShow :: Free (SpecCommand context m) r -> String
  prettyShow = prettyShow' 0
  
  prettyShow' :: Int -> Free (SpecCommand context m) r -> String
  prettyShow' indent (Free (Before'' _loc _no l _f subspec next)) = showNode indent l subspec next
  prettyShow' indent (Free (After'' _loc _no l _f subspec next)) = showNode indent l subspec next
  prettyShow' indent (Free (Introduce'' _loc _no l _cl _alloc _cleanup subspec next)) = showNode indent l subspec next
  prettyShow' indent (Free (IntroduceWith'' _loc _no l _cl _action subspec next)) = showNode indent l subspec next
  prettyShow' indent (Free (Around'' _loc _no l _f subspec next)) = showNode indent l subspec next
  prettyShow' indent (Free (Describe'' _loc _no l subspec next)) = showNode indent l subspec next
  prettyShow' indent (Free (Parallel'' _loc _no subspec next)) = showNode indent "parallel" subspec next
  prettyShow' indent (Free (It'' _loc _no l _ex next)) = showNode indent l ((return ()) :: Free (SpecCommand () m) ()) next
  prettyShow' _ (Pure _) = ""
  
  -- * Util
  
  indentSize :: Int
  indentSize = 2
  
  showNode :: Int -> String -> Free (SpecCommand c m) r -> Free (SpecCommand c' m) r' -> String
  showNode indent label subspec next = L.intercalate "\n" $ filter (/= "") [
    (L.replicate indent ' ') <> label
    , prettyShow' (indent + indentSize) subspec
    , prettyShow' indent next
    ]
  