module Data.Metrics.Counter (
  Counter,
  counter,
  increment,
  increment',
  decrement,
  decrement',
  module Data.Metrics.Types
) where
import Control.Monad.Primitive
import qualified Data.HashMap.Strict as H
import Data.Metrics.Internal
import Data.Metrics.Types
import Data.Primitive.MutVar
newtype Counter m = Counter { fromCounter :: MV m Int }
instance PrimMonad m => Count m (Counter m) where
  count (Counter ref) = readMutVar ref
instance PrimMonad m => Value m (Counter m) Int where
  value (Counter ref) = readMutVar ref
instance PrimMonad m => Set m (Counter m) Int where
  set (Counter ref) x = updateRef ref (const x)
instance PrimMonad m => Clear m (Counter m) where
  clear c = set c 0
counter :: (Functor m, PrimMonad m) => m (Counter m)
counter = fmap Counter $ newMutVar 0
increment :: PrimMonad m => Counter m -> m ()
increment = flip increment' 1
increment' :: PrimMonad m => Counter m -> Int -> m ()
increment' (Counter ref) x = updateRef ref (+ x)
decrement :: PrimMonad m => Counter m -> m ()
decrement = flip decrement' 1
decrement' :: PrimMonad m => Counter m -> Int -> m ()
decrement' (Counter ref) x = updateRef ref (subtract x)