module HIndent.Types
(Printer(..)
,PrintState(..)
,Extender(..)
,Style(..)
,Config(..)
,Pretty(..))
where
import Control.Monad.State (MonadState(..),State)
import Data.Default
import Data.Int (Int64)
import Data.Maybe (listToMaybe,mapMaybe)
import Data.Text (Text)
import Data.Text.Lazy.Builder (Builder)
import Data.Typeable (Typeable,cast)
class (Typeable a) => Pretty a where
pretty :: a -> Printer ()
pretty a =
do st <- get
case st of
PrintState{psExtenders = es,psUserState = s} ->
case listToMaybe (mapMaybe (makePrinter s) es) of
Just m -> m
Nothing -> prettyInternal a
where makePrinter s (Extender f) =
case cast a of
Just v -> Just (f s v)
Nothing -> Nothing
prettyInternal :: a -> Printer ()
newtype Printer a = Printer { runPrinter :: State PrintState a }
deriving (Monad,Functor,MonadState PrintState)
data PrintState = forall s. PrintState
{ psIndentLevel :: !Int64
, psOutput :: !Builder
, psNewline :: !Bool
, psColumn :: !Int64
, psLine :: !Int64
, psUserState :: !s
, psExtenders :: ![Extender s]
, psConfig :: !Config
}
instance Eq PrintState where
PrintState ilevel out newline col line _ _ _ == PrintState ilevel' out' newline' col' line' _ _ _ =
(ilevel,out,newline,col,line) == (ilevel',out',newline',col',line')
data Extender s =
forall a. (Typeable a) => Extender (s -> a -> Printer ())
data Style =
forall s. Style {styleName :: !Text
,styleAuthor :: !Text
,styleDescription :: !Text
,styleInitialState :: !s
,styleExtenders :: ![Extender s]
,styleDefConfig :: !Config}
data Config =
Config {configMaxColumns :: !Int64
,configIndentSpaces :: !Int64}
instance Default Config where
def =
Config {configMaxColumns = 80
,configIndentSpaces = 2}