{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NoImplicitPrelude #-} -- Integer-based identifier. module Omni.Id ( Id (..), mk, untag, ) where import Alpha import Data.Aeson (FromJSON (..), ToJSON (..)) import Data.Binary (Binary) import Data.Data (Data) import Servant (FromHttpApiData (..), ToHttpApiData (..)) newtype Id entity = Id Int deriving (Eq, Ord, Show, Generic, Typeable, Data) mk :: proxy entity -> Int -> Id entity mk _ = Id untag :: Id entity -> Int untag (Id i) = i instance Hashable (Id entity) instance Binary (Id entity) instance Enum (Id entity) where toEnum = mk (Proxy :: Proxy entity) fromEnum = untag instance NFData (Id entity) where rnf (Id s) = rnf s instance FromJSON (Id entity) where parseJSON = fmap Id <. parseJSON instance ToJSON (Id entity) where toJSON = toJSON <. untag -- this is just provided to satisfy Monoid, no reason to actually use it instance Semigroup (Id entity) where a <> b = mk (Proxy :: Proxy entity) <| untag a + untag b instance Monoid (Id entity) where mempty = mk (Proxy :: Proxy entity) 0 instance FromHttpApiData (Id entity) where parseUrlPiece p = mk (Proxy :: Proxy entity) tshow