{-# LANGUAGE DeriveDataTypeable, TemplateHaskell, RecordWildCards, TypeFamilies #-}
module Clckwrks.ProfileData.Acid
    ( ProfileDataState(..)
    , initialProfileDataState
    , SetProfileData(..)
    , GetProfileData(..)
    , NewProfileData(..)
    , UpdateProfileData(..)
    , HasRole(..)
    , GetRoles(..)
    , AddRole(..)
    , RemoveRole(..)
    ) where

import Clckwrks.ProfileData.Types  (ProfileData(..), Role(..), defaultProfileDataFor)
import Control.Applicative         ((<$>))
import Control.Monad.Reader        (ask)
import Control.Monad.State         (get, put)
import Data.Acid                   (Update, Query, makeAcidic)
import Data.Data                   (Data, Typeable)
import Data.IxSet                  (IxSet, (@=), empty, getOne, insert, updateIx, toList)
import Data.SafeCopy               (base, deriveSafeCopy)
import qualified Data.Set          as Set
import           Data.Set          (Set)
import Data.Text                   (Text)
import qualified Data.Text         as Text
import Data.UserId                 (UserId(..))

data ProfileDataState = ProfileDataState
    { ProfileDataState -> IxSet ProfileData
profileData :: IxSet ProfileData
    }
    deriving (ProfileDataState -> ProfileDataState -> Bool
(ProfileDataState -> ProfileDataState -> Bool)
-> (ProfileDataState -> ProfileDataState -> Bool)
-> Eq ProfileDataState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ProfileDataState -> ProfileDataState -> Bool
$c/= :: ProfileDataState -> ProfileDataState -> Bool
== :: ProfileDataState -> ProfileDataState -> Bool
$c== :: ProfileDataState -> ProfileDataState -> Bool
Eq, Eq ProfileDataState
Eq ProfileDataState
-> (ProfileDataState -> ProfileDataState -> Ordering)
-> (ProfileDataState -> ProfileDataState -> Bool)
-> (ProfileDataState -> ProfileDataState -> Bool)
-> (ProfileDataState -> ProfileDataState -> Bool)
-> (ProfileDataState -> ProfileDataState -> Bool)
-> (ProfileDataState -> ProfileDataState -> ProfileDataState)
-> (ProfileDataState -> ProfileDataState -> ProfileDataState)
-> Ord ProfileDataState
ProfileDataState -> ProfileDataState -> Bool
ProfileDataState -> ProfileDataState -> Ordering
ProfileDataState -> ProfileDataState -> ProfileDataState
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ProfileDataState -> ProfileDataState -> ProfileDataState
$cmin :: ProfileDataState -> ProfileDataState -> ProfileDataState
max :: ProfileDataState -> ProfileDataState -> ProfileDataState
$cmax :: ProfileDataState -> ProfileDataState -> ProfileDataState
>= :: ProfileDataState -> ProfileDataState -> Bool
$c>= :: ProfileDataState -> ProfileDataState -> Bool
> :: ProfileDataState -> ProfileDataState -> Bool
$c> :: ProfileDataState -> ProfileDataState -> Bool
<= :: ProfileDataState -> ProfileDataState -> Bool
$c<= :: ProfileDataState -> ProfileDataState -> Bool
< :: ProfileDataState -> ProfileDataState -> Bool
$c< :: ProfileDataState -> ProfileDataState -> Bool
compare :: ProfileDataState -> ProfileDataState -> Ordering
$ccompare :: ProfileDataState -> ProfileDataState -> Ordering
$cp1Ord :: Eq ProfileDataState
Ord, ReadPrec [ProfileDataState]
ReadPrec ProfileDataState
Int -> ReadS ProfileDataState
ReadS [ProfileDataState]
(Int -> ReadS ProfileDataState)
-> ReadS [ProfileDataState]
-> ReadPrec ProfileDataState
-> ReadPrec [ProfileDataState]
-> Read ProfileDataState
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ProfileDataState]
$creadListPrec :: ReadPrec [ProfileDataState]
readPrec :: ReadPrec ProfileDataState
$creadPrec :: ReadPrec ProfileDataState
readList :: ReadS [ProfileDataState]
$creadList :: ReadS [ProfileDataState]
readsPrec :: Int -> ReadS ProfileDataState
$creadsPrec :: Int -> ReadS ProfileDataState
Read, Int -> ProfileDataState -> ShowS
[ProfileDataState] -> ShowS
ProfileDataState -> String
(Int -> ProfileDataState -> ShowS)
-> (ProfileDataState -> String)
-> ([ProfileDataState] -> ShowS)
-> Show ProfileDataState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ProfileDataState] -> ShowS
$cshowList :: [ProfileDataState] -> ShowS
show :: ProfileDataState -> String
$cshow :: ProfileDataState -> String
showsPrec :: Int -> ProfileDataState -> ShowS
$cshowsPrec :: Int -> ProfileDataState -> ShowS
Show, Typeable ProfileDataState
DataType
Constr
Typeable ProfileDataState
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ProfileDataState -> c ProfileDataState)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ProfileDataState)
-> (ProfileDataState -> Constr)
-> (ProfileDataState -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c ProfileDataState))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c ProfileDataState))
-> ((forall b. Data b => b -> b)
    -> ProfileDataState -> ProfileDataState)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> ProfileDataState -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ProfileDataState -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> ProfileDataState -> m ProfileDataState)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ProfileDataState -> m ProfileDataState)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> ProfileDataState -> m ProfileDataState)
-> Data ProfileDataState
ProfileDataState -> DataType
ProfileDataState -> Constr
(forall b. Data b => b -> b)
-> ProfileDataState -> ProfileDataState
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ProfileDataState -> c ProfileDataState
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ProfileDataState
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> ProfileDataState -> u
forall u. (forall d. Data d => d -> u) -> ProfileDataState -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ProfileDataState
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ProfileDataState -> c ProfileDataState
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ProfileDataState)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ProfileDataState)
$cProfileDataState :: Constr
$tProfileDataState :: DataType
gmapMo :: (forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
gmapMp :: (forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
gmapM :: (forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> ProfileDataState -> m ProfileDataState
gmapQi :: Int -> (forall d. Data d => d -> u) -> ProfileDataState -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> ProfileDataState -> u
gmapQ :: (forall d. Data d => d -> u) -> ProfileDataState -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ProfileDataState -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ProfileDataState -> r
gmapT :: (forall b. Data b => b -> b)
-> ProfileDataState -> ProfileDataState
$cgmapT :: (forall b. Data b => b -> b)
-> ProfileDataState -> ProfileDataState
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ProfileDataState)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ProfileDataState)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c ProfileDataState)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ProfileDataState)
dataTypeOf :: ProfileDataState -> DataType
$cdataTypeOf :: ProfileDataState -> DataType
toConstr :: ProfileDataState -> Constr
$ctoConstr :: ProfileDataState -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ProfileDataState
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ProfileDataState
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ProfileDataState -> c ProfileDataState
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ProfileDataState -> c ProfileDataState
$cp1Data :: Typeable ProfileDataState
Data, Typeable)

$(deriveSafeCopy 1 'base ''ProfileDataState)

initialProfileDataState :: ProfileDataState
initialProfileDataState :: ProfileDataState
initialProfileDataState = ProfileDataState :: IxSet ProfileData -> ProfileDataState
ProfileDataState { profileData :: IxSet ProfileData
profileData = IxSet ProfileData
forall a. Indexable a => IxSet a
empty }

setProfileData :: ProfileData
               -> Update ProfileDataState ()
setProfileData :: ProfileData -> Update ProfileDataState ()
setProfileData ProfileData
pd =
    do pds :: ProfileDataState
pds@(ProfileDataState{IxSet ProfileData
profileData :: IxSet ProfileData
profileData :: ProfileDataState -> IxSet ProfileData
..}) <- Update ProfileDataState ProfileDataState
forall s (m :: * -> *). MonadState s m => m s
get
       ProfileDataState -> Update ProfileDataState ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (ProfileDataState -> Update ProfileDataState ())
-> ProfileDataState -> Update ProfileDataState ()
forall a b. (a -> b) -> a -> b
$ ProfileDataState
pds { profileData :: IxSet ProfileData
profileData = UserId -> ProfileData -> IxSet ProfileData -> IxSet ProfileData
forall a k.
(Indexable a, Ord a, Typeable a, Typeable k) =>
k -> a -> IxSet a -> IxSet a
updateIx (ProfileData -> UserId
dataFor ProfileData
pd) ProfileData
pd IxSet ProfileData
profileData }


getProfileData :: UserId
               -> Query ProfileDataState ProfileData
getProfileData :: UserId -> Query ProfileDataState ProfileData
getProfileData UserId
uid =
    do ProfileDataState{IxSet ProfileData
profileData :: IxSet ProfileData
profileData :: ProfileDataState -> IxSet ProfileData
..} <- Query ProfileDataState ProfileDataState
forall r (m :: * -> *). MonadReader r m => m r
ask
       case IxSet ProfileData -> Maybe ProfileData
forall a. Ord a => IxSet a -> Maybe a
getOne (IxSet ProfileData -> Maybe ProfileData)
-> IxSet ProfileData -> Maybe ProfileData
forall a b. (a -> b) -> a -> b
$ IxSet ProfileData
profileData IxSet ProfileData -> UserId -> IxSet ProfileData
forall a k.
(Indexable a, Typeable a, Ord a, Typeable k) =>
IxSet a -> k -> IxSet a
@= UserId
uid of
         (Just ProfileData
pd) -> ProfileData -> Query ProfileDataState ProfileData
forall (m :: * -> *) a. Monad m => a -> m a
return ProfileData
pd
         Maybe ProfileData
Nothing -> ProfileData -> Query ProfileDataState ProfileData
forall (m :: * -> *) a. Monad m => a -> m a
return (UserId -> ProfileData
defaultProfileDataFor UserId
uid)

updateProfileData :: ProfileData
                  -> Update ProfileDataState ()
updateProfileData :: ProfileData -> Update ProfileDataState ()
updateProfileData ProfileData
pd =
    do ProfileDataState
ps <- Update ProfileDataState ProfileDataState
forall s (m :: * -> *). MonadState s m => m s
get
       ProfileDataState -> Update ProfileDataState ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (ProfileDataState -> Update ProfileDataState ())
-> ProfileDataState -> Update ProfileDataState ()
forall a b. (a -> b) -> a -> b
$ ProfileDataState
ps { profileData :: IxSet ProfileData
profileData = UserId -> ProfileData -> IxSet ProfileData -> IxSet ProfileData
forall a k.
(Indexable a, Ord a, Typeable a, Typeable k) =>
k -> a -> IxSet a -> IxSet a
updateIx (ProfileData -> UserId
dataFor ProfileData
pd) ProfileData
pd (ProfileDataState -> IxSet ProfileData
profileData ProfileDataState
ps) }

modifyProfileData :: (ProfileData -> ProfileData)
                  -> UserId
                  -> Update ProfileDataState ()
modifyProfileData :: (ProfileData -> ProfileData)
-> UserId -> Update ProfileDataState ()
modifyProfileData ProfileData -> ProfileData
fn UserId
uid =
    do ps :: ProfileDataState
ps@(ProfileDataState {IxSet ProfileData
profileData :: IxSet ProfileData
profileData :: ProfileDataState -> IxSet ProfileData
..}) <- Update ProfileDataState ProfileDataState
forall s (m :: * -> *). MonadState s m => m s
get
       case IxSet ProfileData -> Maybe ProfileData
forall a. Ord a => IxSet a -> Maybe a
getOne (IxSet ProfileData -> Maybe ProfileData)
-> IxSet ProfileData -> Maybe ProfileData
forall a b. (a -> b) -> a -> b
$ IxSet ProfileData
profileData IxSet ProfileData -> UserId -> IxSet ProfileData
forall a k.
(Indexable a, Typeable a, Ord a, Typeable k) =>
IxSet a -> k -> IxSet a
@= UserId
uid of
         Maybe ProfileData
Nothing   ->
           do let pd' :: ProfileData
pd' = ProfileData -> ProfileData
fn (UserId -> ProfileData
defaultProfileDataFor UserId
uid)
              ProfileDataState -> Update ProfileDataState ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put ProfileDataState
ps { profileData :: IxSet ProfileData
profileData = ProfileData -> IxSet ProfileData -> IxSet ProfileData
forall a.
(Typeable a, Ord a, Indexable a) =>
a -> IxSet a -> IxSet a
insert ProfileData
pd' IxSet ProfileData
profileData }
         (Just ProfileData
pd) ->
           do let pd' :: ProfileData
pd' = ProfileData -> ProfileData
fn ProfileData
pd
              ProfileDataState -> Update ProfileDataState ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put ProfileDataState
ps { profileData :: IxSet ProfileData
profileData = UserId -> ProfileData -> IxSet ProfileData -> IxSet ProfileData
forall a k.
(Indexable a, Ord a, Typeable a, Typeable k) =>
k -> a -> IxSet a -> IxSet a
updateIx (ProfileData -> UserId
dataFor ProfileData
pd') ProfileData
pd' IxSet ProfileData
profileData }



-- | create the profile data, but only if it is missing
newProfileData :: ProfileData
               -> Update ProfileDataState (ProfileData, Bool)
newProfileData :: ProfileData -> Update ProfileDataState (ProfileData, Bool)
newProfileData ProfileData
pd =
    do pds :: ProfileDataState
pds@(ProfileDataState {IxSet ProfileData
profileData :: IxSet ProfileData
profileData :: ProfileDataState -> IxSet ProfileData
..}) <- Update ProfileDataState ProfileDataState
forall s (m :: * -> *). MonadState s m => m s
get
       case IxSet ProfileData -> Maybe ProfileData
forall a. Ord a => IxSet a -> Maybe a
getOne (IxSet ProfileData
profileData IxSet ProfileData -> UserId -> IxSet ProfileData
forall a k.
(Indexable a, Typeable a, Ord a, Typeable k) =>
IxSet a -> k -> IxSet a
@= (ProfileData -> UserId
dataFor ProfileData
pd)) of
         Maybe ProfileData
Nothing -> do ProfileDataState -> Update ProfileDataState ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (ProfileDataState -> Update ProfileDataState ())
-> ProfileDataState -> Update ProfileDataState ()
forall a b. (a -> b) -> a -> b
$ ProfileDataState
pds { profileData :: IxSet ProfileData
profileData = UserId -> ProfileData -> IxSet ProfileData -> IxSet ProfileData
forall a k.
(Indexable a, Ord a, Typeable a, Typeable k) =>
k -> a -> IxSet a -> IxSet a
updateIx (ProfileData -> UserId
dataFor ProfileData
pd) ProfileData
pd IxSet ProfileData
profileData }
                       (ProfileData, Bool) -> Update ProfileDataState (ProfileData, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (ProfileData
pd, Bool
True)
         (Just ProfileData
pd') -> (ProfileData, Bool) -> Update ProfileDataState (ProfileData, Bool)
forall (m :: * -> *) a. Monad m => a -> m a
return (ProfileData
pd', Bool
False)

getRoles :: UserId
         -> Query ProfileDataState (Set Role)
getRoles :: UserId -> Query ProfileDataState (Set Role)
getRoles UserId
uid =
    do ProfileData
profile <- UserId -> Query ProfileDataState ProfileData
getProfileData UserId
uid
       Set Role -> Query ProfileDataState (Set Role)
forall (m :: * -> *) a. Monad m => a -> m a
return (ProfileData -> Set Role
roles ProfileData
profile)

hasRole :: UserId
        -> Set Role
        -> Query ProfileDataState Bool
hasRole :: UserId -> Set Role -> Query ProfileDataState Bool
hasRole UserId
uid Set Role
role =
    do ProfileData
profile <- UserId -> Query ProfileDataState ProfileData
getProfileData UserId
uid
       Bool -> Query ProfileDataState Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set Role -> Bool
forall a. Set a -> Bool
Set.null (Set Role -> Bool) -> Set Role -> Bool
forall a b. (a -> b) -> a -> b
$ Set Role
role Set Role -> Set Role -> Set Role
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` ProfileData -> Set Role
roles ProfileData
profile)

addRole :: UserId
        -> Role
        -> Update ProfileDataState ()
addRole :: UserId -> Role -> Update ProfileDataState ()
addRole UserId
uid Role
role =
    (ProfileData -> ProfileData)
-> UserId -> Update ProfileDataState ()
modifyProfileData ProfileData -> ProfileData
fn UserId
uid
    where
      fn :: ProfileData -> ProfileData
fn ProfileData
profileData = ProfileData
profileData { roles :: Set Role
roles = Role -> Set Role -> Set Role
forall a. Ord a => a -> Set a -> Set a
Set.insert Role
role (ProfileData -> Set Role
roles ProfileData
profileData) }

removeRole :: UserId
           -> Role
           -> Update ProfileDataState ()
removeRole :: UserId -> Role -> Update ProfileDataState ()
removeRole UserId
uid Role
role =
    (ProfileData -> ProfileData)
-> UserId -> Update ProfileDataState ()
modifyProfileData ProfileData -> ProfileData
fn UserId
uid
    where
      fn :: ProfileData -> ProfileData
fn ProfileData
profileData = ProfileData
profileData { roles :: Set Role
roles = Role -> Set Role -> Set Role
forall a. Ord a => a -> Set a -> Set a
Set.delete Role
role (ProfileData -> Set Role
roles ProfileData
profileData) }

$(makeAcidic ''ProfileDataState
  [ 'setProfileData
  , 'getProfileData
  , 'newProfileData
  , 'updateProfileData
  , 'getRoles
  , 'hasRole
  , 'addRole
  , 'removeRole
  ])