packages feed

trifecta 0.23 → 0.24

raw patch · 10 files changed

+264/−110 lines, 10 files

Files

Text/Trifecta/Diagnostic.hs view
@@ -1,17 +1,31 @@ module Text.Trifecta.Diagnostic -  ( Diagnostic(..)+  ( +  -- * Diagnostics+    Diagnostic(..)   , tellDiagnostic-  , MonadDiagnostic(..)-  , DiagnosticLevel(..)+  -- * Rendering   , Renderable(..)   , Source   , rendering   , Caret(..), Careted(..)   , Span(..), Spanned(..)   , Fixit(..), Rendered(..)+  -- * Emitting diagnostics+  , MonadDiagnostic(..)+  , fatal+  , err+  , warn+  , note+  , verbose+  , warnWith+  , noteWith+  , verboseWith+  -- * Diagnostic Levels+  , DiagnosticLevel(..)   ) where  import Text.Trifecta.Diagnostic.Prim import Text.Trifecta.Diagnostic.Class+import Text.Trifecta.Diagnostic.Combinators import Text.Trifecta.Diagnostic.Level import Text.Trifecta.Diagnostic.Rendering
Text/Trifecta/Diagnostic/Class.hs view
@@ -6,28 +6,58 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.State.Lazy as Lazy import Control.Monad.Trans.State.Strict as Strict+import Control.Monad.Trans.RWS.Lazy as Lazy+import Control.Monad.Trans.RWS.Strict as Strict+import Control.Monad.Trans.Writer.Lazy as Lazy+import Control.Monad.Trans.Writer.Strict as Strict+import Control.Monad.Trans.Reader+import Control.Monad.Trans.Identity+import Data.Monoid import Text.Trifecta.Diagnostic.Prim+import Text.Trifecta.Diagnostic.Level+import Text.Trifecta.Diagnostic.Rendering.Prim  class Monad m => MonadDiagnostic e m | m -> e where-  record  :: Diagnostic e -> m ()-  fatal   :: e -> m a -- consuming error-  err     :: e -> m a -- non-consuming error-  warn    :: e -> m ()-  note    :: e -> m ()-  verbose :: Int -> e -> m ()+  fatalWith ::                    [Diagnostic e] -> [Rendering] -> e -> m a  -- consuming error+  errWith   ::                    [Diagnostic e] -> [Rendering] -> e -> m a  -- non-consuming error, handled by <|> +  logWith   :: DiagnosticLevel -> [Diagnostic e] -> [Rendering] -> e -> m () -- log an error and continue  instance MonadDiagnostic e m => MonadDiagnostic e (Lazy.StateT s m) where-  record    = lift . record-  fatal     = lift . fatal-  err       = lift . err-  warn      = lift . warn-  note      = lift . note-  verbose n = lift . verbose n+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)  instance MonadDiagnostic e m => MonadDiagnostic e (Strict.StateT s m) where-  record    = lift . record-  fatal     = lift . fatal-  err       = lift . err-  warn      = lift . warn-  note      = lift . note-  verbose n = lift . verbose n+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)++instance MonadDiagnostic e m => MonadDiagnostic e (ReaderT r m) where+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)++instance (MonadDiagnostic e m, Monoid w) => MonadDiagnostic e (Lazy.WriterT w m) where+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)++instance (MonadDiagnostic e m, Monoid w) => MonadDiagnostic e (Strict.WriterT w m) where+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)++instance (MonadDiagnostic e m, Monoid w) => MonadDiagnostic e (Lazy.RWST r w s m) where+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)++instance (MonadDiagnostic e m, Monoid w) => MonadDiagnostic e (Strict.RWST r w s m) where+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)++instance MonadDiagnostic e m => MonadDiagnostic e (IdentityT m) where+  fatalWith d r e = lift (fatalWith d r e)+  errWith   d r e = lift (errWith d r e)+  logWith l d r e = lift (logWith l d r e)
+ Text/Trifecta/Diagnostic/Combinators.hs view
@@ -0,0 +1,45 @@+module Text.Trifecta.Diagnostic.Combinators +  ( fatal+  , err+  , warn+  , note+  , verbose+  , warnWith+  , noteWith+  , verboseWith+  ) where++import Text.Trifecta.Diagnostic.Class+import Text.Trifecta.Diagnostic.Prim+import Text.Trifecta.Diagnostic.Level+import Text.Trifecta.Diagnostic.Rendering.Prim++fatal :: MonadDiagnostic e m => e -> m a+fatal = fatalWith [] []++err :: MonadDiagnostic e m => e -> m a+err = errWith [] []++warn :: MonadDiagnostic e m => e -> m ()+warn = warnWith [] []++note :: MonadDiagnostic e m => e -> m ()+note = noteWith [] []++verbose :: MonadDiagnostic e m => Int -> e -> m ()+verbose n = verboseWith n [] []++warnWith :: MonadDiagnostic e m => [Diagnostic e] -> [Rendering] -> e -> m ()+warnWith = logWith Warning++noteWith :: MonadDiagnostic e m => [Diagnostic e] -> [Rendering] -> e -> m ()+noteWith = logWith Note++verboseWith :: MonadDiagnostic e m => Int -> [Diagnostic e] -> [Rendering] -> e -> m ()+verboseWith n = logWith (Verbose n)++-- sublimate :: MonadDiagnostic e m => m a -> m a+-- sublimate a = a `catchError` \e -> +--   if fatalErr e then throwError e else do +--     m <- here+--     tell (diagnose m e)
Text/Trifecta/Diagnostic/Err.hs view
@@ -1,12 +1,9 @@ module Text.Trifecta.Diagnostic.Err   ( Err(..)-  , diagnose   , knownErr   , fatalErr   ) where -import Control.Applicative-import Control.Comonad import Data.Semigroup import Data.Monoid import Data.Functor.Plus@@ -14,71 +11,32 @@ import Text.Trifecta.Diagnostic.Level import Text.Trifecta.Diagnostic.Rendering.Prim import Text.PrettyPrint.Free-import System.Console.Terminfo.PrettyPrint --- | unlocated error messages+-- | unlocated error data Err e   = EmptyErr-  | UnexpectedErr String-  | EndOfFileErr-  | FailErr String -  | RichErr (Rendering -> Diagnostic e) -- relocates with us as we try-  | FatalErr (Diagnostic e)--instance Show e => Show (Err e) where-  showsPrec _ EmptyErr = showString "EmptyErr"-  showsPrec d (FailErr s) = showParen (d > 10) $-    showString "FailErr " . showsPrec 11 s-  showsPrec d (UnexpectedErr s) = showParen (d > 10) $-    showString "UnexpectedErr " . showsPrec 11 s-  showsPrec d (FatalErr e) = showParen (d > 10) $ showString "FatalErr " . showsPrec 11 e-  showsPrec _ EndOfFileErr = showString "EndOfFileErr"-  showsPrec d (RichErr _) = showParen (d > 10) $ -    showString "RichErr ..."+  | FailErr String+  | Err     [Rendering] !DiagnosticLevel e [Diagnostic e]+  deriving Show  knownErr :: Err e -> Bool knownErr EmptyErr = False knownErr _ = True  fatalErr :: Err e -> Bool-fatalErr FatalErr{} = True+fatalErr (Err _ Fatal _ _) = True fatalErr _ = False -diagnose :: (t -> Doc e) -> Rendering -> Err t -> Diagnostic (Doc e)-diagnose _ r EmptyErr          = Diagnostic r Error (text "unexpected") []-diagnose _ r (FailErr m)       = Diagnostic r Error (fillSep $ text <$> words m) []-diagnose _ r (UnexpectedErr s) = Diagnostic r Error (fillSep $ fmap text $ "unexpected" : words s) []-diagnose _ r EndOfFileErr      = Diagnostic r Error (text "unexpected EOF") []-diagnose k _ (FatalErr e)      = fmap k e-diagnose k r (RichErr f)       = fmap k (f r)--diagnose0 :: Pretty t => Err t -> Diagnostic (Doc e)-diagnose0 = diagnose pretty emptyRendering--diagnoseTerm0 :: PrettyTerm t => Err t -> Diagnostic TermDoc-diagnoseTerm0 = diagnose prettyTerm emptyRendering--instance Pretty t => Pretty (Err t) where-  pretty = pretty . extract . diagnose0-  prettyList = prettyList . map (extract . diagnose0)--instance PrettyTerm t => PrettyTerm (Err t) where-  prettyTerm = prettyTerm . diagnoseTerm0-  prettyTermList = prettyTermList . map diagnoseTerm0-   instance Functor Err where   fmap _ EmptyErr = EmptyErr   fmap _ (FailErr s) = FailErr s-  fmap _ EndOfFileErr = EndOfFileErr-  fmap f (FatalErr e) = FatalErr (fmap f e)-  fmap _ (UnexpectedErr s) = UnexpectedErr s -  fmap f (RichErr k) = RichErr (fmap f . k)+  fmap f (Err rs l e es) = Err rs l (f e) (fmap (fmap f) es)  instance Alt Err where-  EmptyErr     <!> a            = a-  e@FatalErr{} <!> _            = e-  _            <!> e@FatalErr{} = e-  a            <!> _            = a +  a                   <!> EmptyErr            = a+  _                   <!> a@(Err _ Fatal _ _) = a+  a@(Err _ Fatal _ _) <!> _                   = a+  _                   <!> b                   = b   {-# INLINE (<!>) #-}  instance Plus Err where
Text/Trifecta/Diagnostic/Err/State.hs view
@@ -6,22 +6,23 @@ import Data.Set as Set import Data.Semigroup import Data.Monoid+import Text.PrettyPrint.Free import Text.Trifecta.Diagnostic.Err  data ErrState e = ErrState- { errExpected :: !(Set String)- , errMessage  :: !(Err e)+ { errExpected  :: !(Set String)+ , errMessage   :: !(Err e)  }  instance Functor ErrState where   fmap f (ErrState a b) = ErrState a (fmap f b)  instance Alt ErrState where-  ErrState a b <!> ErrState a' b' = ErrState (a <> a') (b <!> b')+  ErrState a b <!> ErrState a' b' = ErrState (a <> a') (b <> b')   {-# INLINE (<!>) #-}  instance Plus ErrState where-  zero = ErrState mempty zero+  zero = ErrState mempty mempty   instance Semigroup (ErrState e) where   (<>) = (<!>) 
Text/Trifecta/Diagnostic/Level.hs view
@@ -34,7 +34,7 @@  instance PrettyTerm DiagnosticLevel where   prettyTerm (Verbose n) = blue $ text "verbose (" <> int n <> char ')'-  prettyTerm Note        = text "note"+  prettyTerm Note        = black $ text "note"   prettyTerm Warning     = magenta $ text "warning"   prettyTerm Error       = red $ text "error"-  prettyTerm Fatal       = blink $ red $ text "fatal"+  prettyTerm Fatal       = standout $ red $ text "fatal"
Text/Trifecta/Parser/Class.hs view
@@ -18,6 +18,7 @@   , (<?>)   , slicedWith   , sliced+  , rend   ) where  import Control.Applicative@@ -25,12 +26,22 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.State.Lazy as Lazy import Control.Monad.Trans.State.Strict as Strict+import Control.Monad.Trans.Writer.Lazy as Lazy+import Control.Monad.Trans.Writer.Strict as Strict+import Control.Monad.Trans.RWS.Lazy as Lazy+import Control.Monad.Trans.RWS.Strict as Strict+import Control.Monad.Trans.Reader+import Control.Monad.Trans.Identity+import Data.Monoid+-- import Control.Monad.Trans.Maybe.Strict as Strict+-- import Control.Monad.Trans.Either.Strict as Strict import Data.ByteString as Strict import Data.Semigroup import Data.Set as Set import Text.Trifecta.Rope.Delta import Text.Trifecta.Rope.Prim import Text.Trifecta.Parser.It+import Text.Trifecta.Diagnostic.Rendering.Prim  infix 0 <?> @@ -72,6 +83,75 @@   unexpected = lift . unexpected   satisfyAscii = lift . satisfyAscii +instance MonadParser m => MonadParser (ReaderT e m) where+  satisfy = lift . satisfy+  try (ReaderT m) = ReaderT $ try . m+  labels (ReaderT m) ss = ReaderT $ \s -> labels (m s) ss+  line = lift line+  liftIt = lift . liftIt+  mark = lift mark +  release = lift . release+  unexpected = lift . unexpected+  satisfyAscii = lift . satisfyAscii++instance (MonadParser m, Monoid w) => MonadParser (Strict.WriterT w m) where+  satisfy = lift . satisfy+  try (Strict.WriterT m) = Strict.WriterT $ try m+  labels (Strict.WriterT m) ss = Strict.WriterT $ labels m ss+  line = lift line+  liftIt = lift . liftIt+  mark = lift mark +  release = lift . release+  unexpected = lift . unexpected+  satisfyAscii = lift . satisfyAscii++instance (MonadParser m, Monoid w) => MonadParser (Lazy.WriterT w m) where+  satisfy = lift . satisfy+  try (Lazy.WriterT m) = Lazy.WriterT $ try m+  labels (Lazy.WriterT m) ss = Lazy.WriterT $ labels m ss+  line = lift line+  liftIt = lift . liftIt+  mark = lift mark +  release = lift . release+  unexpected = lift . unexpected+  satisfyAscii = lift . satisfyAscii++instance (MonadParser m, Monoid w) => MonadParser (Lazy.RWST r w s m) where+  satisfy = lift . satisfy+  try (Lazy.RWST m) = Lazy.RWST $ \r s -> try (m r s)+  labels (Lazy.RWST m) ss = Lazy.RWST $ \r s -> labels (m r s) ss+  line = lift line+  liftIt = lift . liftIt+  mark = lift mark +  release = lift . release+  unexpected = lift . unexpected+  satisfyAscii = lift . satisfyAscii++instance (MonadParser m, Monoid w) => MonadParser (Strict.RWST r w s m) where+  satisfy = lift . satisfy+  try (Strict.RWST m) = Strict.RWST $ \r s -> try (m r s)+  labels (Strict.RWST m) ss = Strict.RWST $ \r s -> labels (m r s) ss+  line = lift line+  liftIt = lift . liftIt+  mark = lift mark +  release = lift . release+  unexpected = lift . unexpected+  satisfyAscii = lift . satisfyAscii++instance MonadParser m => MonadParser (IdentityT m) where+  satisfy = lift . satisfy+  try (IdentityT m) = IdentityT $ try m+  labels (IdentityT m) = IdentityT . labels m+  line = lift line+  liftIt = lift . liftIt+  mark = lift mark +  release = lift . release+  unexpected = lift . unexpected+  satisfyAscii = lift . satisfyAscii++-- instance (MonadParser m, Monoid w) => MonadParser (MaybeT m) where+-- instance (Error e, MonadParser m, Monoid w) => MonadParser (ErrorT e m) where+ -- useful when we've just recognized something out of band using access to the current line  skipping :: (MonadParser m, HasDelta d) => d -> m d skipping d = do@@ -100,3 +180,5 @@ sliced :: MonadParser m => m a -> m ByteString sliced = slicedWith (\_ bs -> bs)   +rend :: MonadParser m => m Rendering+rend = rendering <$> mark <*> line
Text/Trifecta/Parser/Prim.hs view
@@ -107,14 +107,13 @@   {-# INLINE (>>=) #-}   (>>) = (*>)    {-# INLINE (>>) #-}-  fail = throwError . FailErr+  fail s = Parser $ \ _ ee _ _ -> ee mempty { errMessage = FailErr s }   {-# INLINE fail #-}  instance MonadPlus (Parser e) where   mzero = empty   mplus = (<|>)  - instance MonadWriter (Seq (Diagnostic e)) (Parser e) where   tell w = Parser $ \eo _ _ _ l -> eo () mempty (l <> w)   {-# INLINE tell #-}@@ -133,28 +132,19 @@       mempty   {-# INLINE pass #-} -logging :: DiagnosticLevel -> e -> Parser e ()-logging level e = do-  m <- mark-  l <- line-  tell $ return $ Diagnostic (addCaret m $ rendering m l) level e []- instance MonadDiagnostic e (Parser e) where-  record = tell . return-  fatal e = Parser $ \_ _ _ ce l d bs -> ce mempty { errMessage = FatalErr (Diagnostic (addCaret d $ rendering d bs) Fatal e []) } l d bs-  err e = do-    m <- mark-    throwError $ RichErr $ \r -> Diagnostic (addCaret m r) Error e [] -- showing the actual location-  warn = logging Warning-  note = logging Note-  verbose = logging . Verbose--instance MonadError (Err e) (Parser e) where-  throwError m = Parser $ \_ ee _ _ -> ee mempty { errMessage = m } +  fatalWith ds rs e = Parser $ \_ _ _ ce -> +    ce mempty { errMessage = Err rs Fatal e ds }+  errWith ds rs e = Parser $ \_ ee _ _ -> +    ee mempty { errMessage = Err rs Error e ds }+  logWith v ds rs e = Parser $ \eo _ _ _ l d bs -> +    eo () mempty (l |> Diagnostic (addCaret d $ Prelude.foldr (<>) (rendering d bs) rs) v e ds) d bs+    +instance MonadError (ErrState e) (Parser e) where+  throwError m = Parser $ \_ ee _ _ -> ee m   {-# INLINE throwError #-}   catchError (Parser m) k = Parser $ \ eo ee co ce -> -    m eo (\e -> unparser (k (errMessage e)) (\a e'-> eo a (e <> e')) (\e' -> ee (e <> e')) co ce) -      co ce+    m eo (\e -> unparser (k e) eo ee co ce) co ce   {-# INLINE catchError #-}  instance MonadParser (Parser e) where@@ -162,11 +152,11 @@   try (Parser m) = Parser $ \ eo ee co ce -> m eo ee co $      \e -> if fatalErr (errMessage e) then ce e else ee e   {-# INLINE try #-}-  unexpected s = Parser $ \ _ ee _ _ -> ee mempty { errMessage = UnexpectedErr s } +  unexpected s = Parser $ \ _ ee _ _ -> ee mempty { errMessage = FailErr $ "unexpected " ++ s }    labels (Parser p) msgs = Parser $ \ eo ee -> p-     (\a e -> eo a $ if knownErr (errMessage e) -                     then e { errExpected = errExpected e }+     (\a e -> eo a $ if knownErr (errMessage e)+                     then e { errExpected = msgs `union` errExpected e }                      else e)      (\e -> ee e { errExpected = msgs })   {-# INLINE labels #-}@@ -186,7 +176,7 @@   {-# INLINE line #-}   satisfy f = Parser $ \ _ ee co _ l d bs ->     case UTF8.uncons $ Strict.drop (columnByte d) bs of-      Nothing             -> ee mempty { errMessage = EndOfFileErr } l d bs+      Nothing             -> ee mempty { errMessage = FailErr "unexpected EOF" } l d bs       Just (c, xs)          | not (f c)       -> ee mempty l d bs         | Strict.null xs  -> let ddc = d <> delta c in@@ -201,7 +191,7 @@         | b == Strict.length bs - 1 -> let ddc = d <> delta c in                                         join $ fillIt (co c mempty l ddc bs) (co c mempty l) ddc         | otherwise                 -> co c mempty l (d <> delta c) bs-    else ee mempty { errMessage = EndOfFileErr } l d bs+    else ee mempty { errMessage = FailErr "unexpected EOF" } l d bs   {-# INLINE satisfyAscii #-}  data St e a = JuSt a !(ErrState e) !(ErrLog e) !Delta !ByteString@@ -225,14 +215,16 @@                                    NoSt e l d bs   -> Failure (yl <$> l) $ y e d bs)                                  (go <*> k) ---- explain an error in terms of the expected set, when we are running the step parser for pretty printing why :: Pretty e => (e -> Doc t) -> ErrState e -> Delta -> ByteString -> Diagnostic (Doc t) why pp (ErrState ss m) d bs -  | Set.null ss = diagnose pp (addCaret d $ rendering d bs) m-  | otherwise   = expected <$> diagnose pp (addCaret d $ rendering d bs) m +  | Set.null ss = explicate m +  | otherwise   = expected <$> explicate m   where     expected doc = doc <> text ", expected" <+> fillSep (punctuate (char ',') $ text <$> toList ss)+    r = addCaret d $ rendering d bs+    explicate EmptyErr        = Diagnostic r Error (text "error") []+    explicate (FailErr s)     = Diagnostic r Error (fillSep $ text <$> words s) []+    explicate (Err rs l e es) = Diagnostic (addCaret d $ Prelude.foldr (<>) (rendering d bs) rs) l (pp e) (fmap (fmap pp) es)  parseTest :: Show a => Parser String a -> String -> IO () parseTest p s = case starve $ feed st $ UTF8.fromString s of
Text/Trifecta/Parser/Token/Class.hs view
@@ -17,6 +17,13 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.State.Lazy as Lazy import Control.Monad.Trans.State.Strict as Strict+import Control.Monad.Trans.Writer.Lazy as Lazy+import Control.Monad.Trans.Writer.Strict as Strict+import Control.Monad.Trans.RWS.Lazy as Lazy+import Control.Monad.Trans.RWS.Strict as Strict+import Control.Monad.Trans.Reader+import Control.Monad.Trans.Identity+import Data.Monoid import Text.Trifecta.Parser.Class  class MonadParser m => MonadTokenParser m where@@ -44,6 +51,10 @@   lexeme :: m a -> m a   lexeme p = p <* whiteSpace +instance MonadTokenParser m => MonadTokenParser (ReaderT r m) where+  whiteSpace = lift whiteSpace+  lexeme (ReaderT m) = ReaderT $ lexeme . m+ instance MonadTokenParser m => MonadTokenParser (Lazy.StateT s m) where   whiteSpace = lift whiteSpace   lexeme (Lazy.StateT m) = Lazy.StateT $ lexeme . m@@ -51,3 +62,23 @@ instance MonadTokenParser m => MonadTokenParser (Strict.StateT s m) where   whiteSpace = lift whiteSpace   lexeme (Strict.StateT m) = Strict.StateT $ lexeme . m++instance (MonadTokenParser m, Monoid w) => MonadTokenParser (Lazy.WriterT w m) where+  whiteSpace = lift whiteSpace+  lexeme (Lazy.WriterT m) = Lazy.WriterT $ lexeme m++instance (MonadTokenParser m, Monoid w) => MonadTokenParser (Strict.WriterT w m) where+  whiteSpace = lift whiteSpace+  lexeme (Strict.WriterT m) = Strict.WriterT $ lexeme m++instance (MonadTokenParser m, Monoid w) => MonadTokenParser (Lazy.RWST r w s m) where+  whiteSpace = lift whiteSpace+  lexeme (Lazy.RWST m) = Lazy.RWST $ \r s -> lexeme (m r s)++instance (MonadTokenParser m, Monoid w) => MonadTokenParser (Strict.RWST r w s m) where+  whiteSpace = lift whiteSpace+  lexeme (Strict.RWST m) = Strict.RWST $ \r s -> lexeme (m r s)++instance MonadTokenParser m => MonadTokenParser (IdentityT m) where+  whiteSpace = lift whiteSpace+  lexeme = IdentityT . lexeme . runIdentityT
trifecta.cabal view
@@ -1,6 +1,6 @@ name:          trifecta category:      Text, Parsing, Diagnostics, Pretty Printer, Logging-version:       0.23+version:       0.24 license:       BSD3 cabal-version: >= 1.6 license-file:  LICENSE@@ -38,6 +38,7 @@     Text.Trifecta.Diagnostic     Text.Trifecta.Diagnostic.Prim     Text.Trifecta.Diagnostic.Class+    Text.Trifecta.Diagnostic.Combinators     Text.Trifecta.Diagnostic.Level     Text.Trifecta.Diagnostic.Err     Text.Trifecta.Diagnostic.Err.State