module Ermine.Diagnostic
(
Rendering
, HasRendering(..)
, Diagnostic(Diagnostic)
, AsDiagnostic(..)
, HasDiagnostic(..)
, Err(Err)
, HasErr(..)
, die
) where
import Control.Exception
import Control.Exception.Lens
import Control.Lens
import Data.Monoid
import Data.Set
import Data.Text
import Data.Typeable
import Text.PrettyPrint.ANSI.Leijen
import Text.Read
import Text.Trifecta.Rendering
import Text.Trifecta.Result
data Diagnostic = Diagnostic
{ _diagnosticRendering :: !Rendering
, _diagnosticMessage :: Maybe Doc
, _diagnosticNotes :: [Doc]
, _diagnosticExpected :: Set String
} deriving Typeable
makeClassy ''Diagnostic
die :: HasRendering r => r -> Text -> Diagnostic
die r s = Diagnostic (r^.rendering) (Just (pretty $ unpack s)) [] mempty
class AsDiagnostic t where
_Diagnostic :: Prism' t Diagnostic
instance AsDiagnostic Diagnostic where
_Diagnostic = id
instance AsDiagnostic SomeException where
_Diagnostic = exception
instance Exception Diagnostic
instance Show Diagnostic where
show d = show $ plain $ explain (d^.rendering) (d^.err)
instance HasErr Diagnostic where
err f (Diagnostic r p a x) = f (Err p a x) <&> \(Err q b y) -> Diagnostic r q b y
instance HasRendering Diagnostic where
rendering = diagnosticRendering
instance Read Rendering where
readPrec = pfail