packages feed

descript-lang-0.2.0.0: src/Descript/Build/Cache/PhaseCache.hs

{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}

module Descript.Build.Cache.PhaseCache
  ( PhaseCache (..)
  , newPhaseCache
  , datePhaseCache
  , updatePhaseCache
  , forceGetPhaseCache
  ) where

-- | A cached AST or text for a single phase.
data PhaseCache a
  = PhaseCache
  { phaseCacheUpdated :: Bool -- ^ Whether 'phaseCached' is updated.
  , phaseCached :: Maybe a -- ^ The last-updated version.
  } deriving (Eq, Ord, Read, Show, Functor, Foldable, Traversable)

-- | Creates a cache with no data, which needs to be updated.
newPhaseCache :: PhaseCache a
newPhaseCache = PhaseCache False Nothing

-- | Notifies that the cache needs to be updated.
datePhaseCache :: PhaseCache a -> PhaseCache a
datePhaseCache (PhaseCache _ x) = PhaseCache False x

-- | Creates an updated cache for the given (updated) phase.
updatePhaseCache :: a -> PhaseCache a
updatePhaseCache x = PhaseCache True $ Just x

-- | Asserts the cache is updated, and gets its phase.
forceGetPhaseCache :: PhaseCache a -> a
forceGetPhaseCache (PhaseCache updated cached)
  | not updated = error "forceGetPhaseCache: cache not updated"
  | otherwise
  = case cached of
         Nothing -> error "forceGetPhaseCache: bad state - updated but no phase"
         Just x -> x