calamity 0.1.11.0 → 0.1.11.1
raw patch · 5 files changed
+114/−35 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Calamity.Cache.InMemory: instance GHC.Generics.Generic Calamity.Cache.InMemory.Cache
- Calamity.Cache.InMemory: instance GHC.Show.Show Calamity.Cache.InMemory.Cache
- Calamity.Internal.BoundedStore: BoundedStore :: Deque (Snowflake a) -> HashMap (Snowflake a) a -> Int -> Int -> BoundedStore a
- Calamity.Internal.BoundedStore: [$sel:itemQueue:BoundedStore] :: BoundedStore a -> Deque (Snowflake a)
- Calamity.Internal.BoundedStore: [$sel:items:BoundedStore] :: BoundedStore a -> HashMap (Snowflake a) a
- Calamity.Internal.BoundedStore: [$sel:limit:BoundedStore] :: BoundedStore a -> Int
- Calamity.Internal.BoundedStore: [$sel:size:BoundedStore] :: BoundedStore a -> Int
+ Calamity.Cache.InMemory: instance Calamity.Cache.InMemory.MessageMod Calamity.Cache.InMemory.CacheNoMsg
+ Calamity.Cache.InMemory: instance Calamity.Cache.InMemory.MessageMod Calamity.Cache.InMemory.CacheWithMsg
+ Calamity.Cache.InMemory: instance GHC.Generics.Generic (Calamity.Cache.InMemory.Cache f)
+ Calamity.Cache.InMemory: runCacheInMemory' :: Member (Embed IO) r => Int -> Sem (CacheEff : r) a -> Sem r a
+ Calamity.Cache.InMemory: runCacheInMemoryNoMsg :: Member (Embed IO) r => Sem (CacheEff : r) a -> Sem r a
+ Calamity.Internal.BoundedStore: empty :: Int -> BoundedStore a
- Calamity.Cache.Eff: delDM :: forall r_a9O0m. MemberWithError CacheEff r_a9O0m => Snowflake DMChannel -> Sem r_a9O0m ()
+ Calamity.Cache.Eff: delDM :: forall r_a9O0R. MemberWithError CacheEff r_a9O0R => Snowflake DMChannel -> Sem r_a9O0R ()
- Calamity.Cache.Eff: delGuild :: forall r_a9O0f. MemberWithError CacheEff r_a9O0f => Snowflake Guild -> Sem r_a9O0f ()
+ Calamity.Cache.Eff: delGuild :: forall r_a9O0K. MemberWithError CacheEff r_a9O0K => Snowflake Guild -> Sem r_a9O0K ()
- Calamity.Cache.Eff: delMessage :: forall r_a9O0H. MemberWithError CacheEff r_a9O0H => Snowflake Message -> Sem r_a9O0H ()
+ Calamity.Cache.Eff: delMessage :: forall r_a9O1c. MemberWithError CacheEff r_a9O1c => Snowflake Message -> Sem r_a9O1c ()
- Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9O0A. MemberWithError CacheEff r_a9O0A => Snowflake Guild -> Sem r_a9O0A ()
+ Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9O15. MemberWithError CacheEff r_a9O15 => Snowflake Guild -> Sem r_a9O15 ()
- Calamity.Cache.Eff: delUser :: forall r_a9O0t. MemberWithError CacheEff r_a9O0t => Snowflake User -> Sem r_a9O0t ()
+ Calamity.Cache.Eff: delUser :: forall r_a9O0Y. MemberWithError CacheEff r_a9O0Y => Snowflake User -> Sem r_a9O0Y ()
- Calamity.Cache.Eff: getBotUser :: forall r_a9O07. MemberWithError CacheEff r_a9O07 => Sem r_a9O07 (Maybe User)
+ Calamity.Cache.Eff: getBotUser :: forall r_a9O0C. MemberWithError CacheEff r_a9O0C => Sem r_a9O0C (Maybe User)
- Calamity.Cache.Eff: getDM :: forall r_a9O0j. MemberWithError CacheEff r_a9O0j => Snowflake DMChannel -> Sem r_a9O0j (Maybe DMChannel)
+ Calamity.Cache.Eff: getDM :: forall r_a9O0O. MemberWithError CacheEff r_a9O0O => Snowflake DMChannel -> Sem r_a9O0O (Maybe DMChannel)
- Calamity.Cache.Eff: getDMs :: forall r_a9O0l. MemberWithError CacheEff r_a9O0l => Sem r_a9O0l [DMChannel]
+ Calamity.Cache.Eff: getDMs :: forall r_a9O0Q. MemberWithError CacheEff r_a9O0Q => Sem r_a9O0Q [DMChannel]
- Calamity.Cache.Eff: getGuild :: forall r_a9O0a. MemberWithError CacheEff r_a9O0a => Snowflake Guild -> Sem r_a9O0a (Maybe Guild)
+ Calamity.Cache.Eff: getGuild :: forall r_a9O0F. MemberWithError CacheEff r_a9O0F => Snowflake Guild -> Sem r_a9O0F (Maybe Guild)
- Calamity.Cache.Eff: getGuildChannel :: forall r_a9O0c. MemberWithError CacheEff r_a9O0c => Snowflake GuildChannel -> Sem r_a9O0c (Maybe GuildChannel)
+ Calamity.Cache.Eff: getGuildChannel :: forall r_a9O0H. MemberWithError CacheEff r_a9O0H => Snowflake GuildChannel -> Sem r_a9O0H (Maybe GuildChannel)
- Calamity.Cache.Eff: getGuilds :: forall r_a9O0e. MemberWithError CacheEff r_a9O0e => Sem r_a9O0e [Guild]
+ Calamity.Cache.Eff: getGuilds :: forall r_a9O0J. MemberWithError CacheEff r_a9O0J => Sem r_a9O0J [Guild]
- Calamity.Cache.Eff: getMessage :: forall r_a9O0E. MemberWithError CacheEff r_a9O0E => Snowflake Message -> Sem r_a9O0E (Maybe Message)
+ Calamity.Cache.Eff: getMessage :: forall r_a9O19. MemberWithError CacheEff r_a9O19 => Snowflake Message -> Sem r_a9O19 (Maybe Message)
- Calamity.Cache.Eff: getMessages :: forall r_a9O0G. MemberWithError CacheEff r_a9O0G => Sem r_a9O0G [Message]
+ Calamity.Cache.Eff: getMessages :: forall r_a9O1b. MemberWithError CacheEff r_a9O1b => Sem r_a9O1b [Message]
- Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9O0z. MemberWithError CacheEff r_a9O0z => Sem r_a9O0z [Snowflake Guild]
+ Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9O14. MemberWithError CacheEff r_a9O14 => Sem r_a9O14 [Snowflake Guild]
- Calamity.Cache.Eff: getUser :: forall r_a9O0q. MemberWithError CacheEff r_a9O0q => Snowflake User -> Sem r_a9O0q (Maybe User)
+ Calamity.Cache.Eff: getUser :: forall r_a9O0V. MemberWithError CacheEff r_a9O0V => Snowflake User -> Sem r_a9O0V (Maybe User)
- Calamity.Cache.Eff: getUsers :: forall r_a9O0s. MemberWithError CacheEff r_a9O0s => Sem r_a9O0s [User]
+ Calamity.Cache.Eff: getUsers :: forall r_a9O0X. MemberWithError CacheEff r_a9O0X => Sem r_a9O0X [User]
- Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9O0x. MemberWithError CacheEff r_a9O0x => Snowflake Guild -> Sem r_a9O0x Bool
+ Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9O12. MemberWithError CacheEff r_a9O12 => Snowflake Guild -> Sem r_a9O12 Bool
- Calamity.Cache.Eff: setBotUser :: forall r_a9O05. MemberWithError CacheEff r_a9O05 => User -> Sem r_a9O05 ()
+ Calamity.Cache.Eff: setBotUser :: forall r_a9O0A. MemberWithError CacheEff r_a9O0A => User -> Sem r_a9O0A ()
- Calamity.Cache.Eff: setDM :: forall r_a9O0h. MemberWithError CacheEff r_a9O0h => DMChannel -> Sem r_a9O0h ()
+ Calamity.Cache.Eff: setDM :: forall r_a9O0M. MemberWithError CacheEff r_a9O0M => DMChannel -> Sem r_a9O0M ()
- Calamity.Cache.Eff: setGuild :: forall r_a9O08. MemberWithError CacheEff r_a9O08 => Guild -> Sem r_a9O08 ()
+ Calamity.Cache.Eff: setGuild :: forall r_a9O0D. MemberWithError CacheEff r_a9O0D => Guild -> Sem r_a9O0D ()
- Calamity.Cache.Eff: setMessage :: forall r_a9O0C. MemberWithError CacheEff r_a9O0C => Message -> Sem r_a9O0C ()
+ Calamity.Cache.Eff: setMessage :: forall r_a9O17. MemberWithError CacheEff r_a9O17 => Message -> Sem r_a9O17 ()
- Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9O0v. MemberWithError CacheEff r_a9O0v => Snowflake Guild -> Sem r_a9O0v ()
+ Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9O10. MemberWithError CacheEff r_a9O10 => Snowflake Guild -> Sem r_a9O10 ()
- Calamity.Cache.Eff: setUser :: forall r_a9O0o. MemberWithError CacheEff r_a9O0o => User -> Sem r_a9O0o ()
+ Calamity.Cache.Eff: setUser :: forall r_a9O0T. MemberWithError CacheEff r_a9O0T => User -> Sem r_a9O0T ()
- Calamity.Utils.Permissions: permissionsIn' :: (PermissionsIn' a, BotC r) => a -> Member -> Sem r Permissions
+ Calamity.Utils.Permissions: permissionsIn' :: (PermissionsIn' a, BotC r, HasID User u) => a -> u -> Sem r Permissions
Files
- calamity.cabal +2/−2
- src/Calamity/Cache/InMemory.hs +56/−16
- src/Calamity/Internal/BoundedStore.hs +6/−2
- src/Calamity/Types/Upgradeable.hs +6/−0
- src/Calamity/Utils/Permissions.hs +44/−15
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 67eb6b9ab5e005763f101fcd1bccf75b1e92dbe2f71a376929854d730fb0ee9a+-- hash: 12a035b3d93c607f12c355b451e20803b1c5e62716eddb253a236cf2467effe3 name: calamity-version: 0.1.11.0+version: 0.1.11.1 synopsis: A library for writing discord bots description: Please see the README on GitHub at <https://github.com/nitros12/calamity#readme> category: Network, Web
src/Calamity/Cache/InMemory.hs view
@@ -1,9 +1,11 @@ -- | A 'Cache' handler that operates in memory module Calamity.Cache.InMemory- ( runCacheInMemory ) where+ ( runCacheInMemory+ , runCacheInMemory'+ , runCacheInMemoryNoMsg ) where import Calamity.Cache.Eff-import Calamity.Internal.BoundedStore+import qualified Calamity.Internal.BoundedStore as BS import qualified Calamity.Internal.SnowflakeMap as SM import Calamity.Internal.Utils import Calamity.Types.Model.Channel@@ -14,10 +16,8 @@ import Control.Lens import Control.Monad.State.Strict -import qualified Data.HashMap.Lazy as LH--import Data.Default.Class import Data.Foldable+import qualified Data.HashMap.Lazy as LH import qualified Data.HashSet as LS import Data.IORef @@ -26,30 +26,70 @@ import qualified Polysemy as P import qualified Polysemy.AtomicState as P -data Cache = Cache+data Cache f = Cache { user :: Maybe User , guilds :: SM.SnowflakeMap Guild , dms :: SM.SnowflakeMap DMChannel , guildChannels :: LH.HashMap (Snowflake GuildChannel) Guild , users :: SM.SnowflakeMap User , unavailableGuilds :: LS.HashSet (Snowflake Guild)- , messages :: BoundedStore Message+ , messages :: f (BS.BoundedStore Message) }- deriving ( Generic, Show )+ deriving ( Generic ) -emptyCache :: Cache-emptyCache = Cache Nothing SM.empty SM.empty LH.empty SM.empty LS.empty def+type CacheWithMsg = Cache Identity+type CacheNoMsg = Cache (Const ()) +emptyCache :: CacheWithMsg+emptyCache = Cache Nothing SM.empty SM.empty LH.empty SM.empty LS.empty (Identity $ BS.empty 1000)++emptyCacheNoMsg :: CacheNoMsg+emptyCacheNoMsg = Cache Nothing SM.empty SM.empty LH.empty SM.empty LS.empty (Const ())++emptyCache' :: Int -> CacheWithMsg+emptyCache' msgLimit = Cache Nothing SM.empty SM.empty LH.empty SM.empty LS.empty (Identity $ BS.empty msgLimit)++-- | Run the cache in memory with a default message cache size of 1000 runCacheInMemory :: P.Member (P.Embed IO) r => P.Sem (CacheEff ': r) a -> P.Sem r a runCacheInMemory m = do var <- P.embed $ newIORef emptyCache P.runAtomicStateIORef var $ P.reinterpret runCache' m -runCache' :: P.Member (P.AtomicState Cache) r => CacheEff m a -> P.Sem r a+-- | Run the cache in memory with no messages being cached+runCacheInMemoryNoMsg :: P.Member (P.Embed IO) r => P.Sem (CacheEff ': r) a -> P.Sem r a+runCacheInMemoryNoMsg m = do+ var <- P.embed $ newIORef emptyCacheNoMsg+ P.runAtomicStateIORef var $ P.reinterpret runCache' m++-- | Run the cache in memory with a configurable message cache limit+runCacheInMemory' :: P.Member (P.Embed IO) r => Int -> P.Sem (CacheEff ': r) a -> P.Sem r a+runCacheInMemory' msgLimit m = do+ var <- P.embed $ newIORef (emptyCache' msgLimit)+ P.runAtomicStateIORef var $ P.reinterpret runCache' m++runCache' :: (MessageMod (Cache t), P.Member (P.AtomicState (Cache t)) r) => CacheEff m a -> P.Sem r a runCache' act = P.atomicState' ((swap .) . runState $ runCache act) -runCache :: CacheEff m a -> State Cache a+class MessageMod t where+ setMessage' :: Message -> State t ()+ getMessage' :: Snowflake Message -> State t (Maybe Message)+ getMessages' :: State t [Message]+ delMessage' :: Snowflake Message -> State t () +instance MessageMod CacheWithMsg where+ setMessage' m = #messages . _Wrapped %= BS.addItem m+ getMessage' mid = use (#messages . _Wrapped . at mid)+ getMessages' = toList <$> use (#messages . _Wrapped)+ delMessage' mid = #messages . _Wrapped %= sans mid++instance MessageMod CacheNoMsg where+ setMessage' _ = pure ()+ getMessage' _ = pure Nothing+ getMessages' = pure []+ delMessage' _ = pure ()++runCache :: MessageMod (Cache t) => CacheEff m a -> State (Cache t) a+ runCache (SetBotUser u) = #user ?= u runCache GetBotUser = use #user @@ -79,7 +119,7 @@ runCache GetUnavailableGuilds = LS.toList <$> use #unavailableGuilds runCache (DelUnavailableGuild gid) = #unavailableGuilds %= sans gid -runCache (SetMessage m) = #messages %= addItem m-runCache (GetMessage mid) = use (#messages . at mid)-runCache GetMessages = toList <$> use #messages-runCache (DelMessage mid) = #messages %= sans mid+runCache (SetMessage m) = setMessage' m+runCache (GetMessage mid) = getMessage' mid+runCache GetMessages = getMessages'+runCache (DelMessage mid) = delMessage' mid
src/Calamity/Internal/BoundedStore.hs view
@@ -1,6 +1,7 @@ -- | A thing for storing the last N things with IDs module Calamity.Internal.BoundedStore- ( BoundedStore(..)+ ( BoundedStore+ , empty , addItem , getItem , dropItem ) where@@ -33,7 +34,10 @@ foldr f i = foldr f i . H.elems . items instance Default (BoundedStore a) where- def = BoundedStore mempty H.empty 1000 0+ def = BoundedStore mempty mempty 1000 0++empty :: Int -> BoundedStore a+empty limit = BoundedStore mempty mempty limit 0 type instance (Index (BoundedStore a)) = Snowflake a
src/Calamity/Types/Upgradeable.hs view
@@ -20,7 +20,13 @@ import qualified Polysemy.Fail as P import qualified Polysemy.NonDet as P +-- | A typeclass that represents snowflakes that can be upgraded to their+-- complete data, either through the cache or HTTP. class Upgradeable a ids | a -> ids, ids -> a where+ -- | Upgrade a snowflake to it's complete data.+ --+ -- If it existed in the cache then it is returned from there, otherwise we+ -- fetch from HTTP and update the cache on success. upgrade :: BotC r => ids -> P.Sem r (Maybe a) maybeToAlt :: Alternative f => Maybe a -> f a
src/Calamity/Utils/Permissions.hs view
@@ -1,9 +1,9 @@ -- | Permission utilities module Calamity.Utils.Permissions- ( PermissionsIn(..)- , PermissionsIn'(..)- , basePermissions- , applyOverwrites ) where+ ( basePermissions+ , applyOverwrites+ , PermissionsIn(..)+ , PermissionsIn'(..) ) where import Calamity.Client.Types import Calamity.Types.Model.Channel.Guild@@ -11,6 +11,7 @@ import Calamity.Types.Model.Guild.Member import Calamity.Types.Model.Guild.Overwrite import Calamity.Types.Model.Guild.Permissions+import Calamity.Types.Model.User import Calamity.Types.Snowflake import Calamity.Types.Upgradeable @@ -21,6 +22,7 @@ import qualified Polysemy as P +-- | Calculate a 'Member''s 'Permissions' in a 'Guild' basePermissions :: Guild -> Member -> Permissions basePermissions g m | (g ^. #ownerID == getID m) = allFlags@@ -32,6 +34,7 @@ then allFlags else perms +-- | Apply any 'Overwrite's for a 'GuildChannel' onto some 'Permissions' applyOverwrites :: GuildChannel -> Member -> Permissions -> Permissions applyOverwrites c m p | p .<=. administrator = allFlags@@ -51,38 +54,64 @@ p''' = p'' .-. memberDeny .+. memberAllow in p''' +-- | Things that 'Member's have 'Permissions' in class PermissionsIn a where+ -- | Calculate a 'Member''s 'Permissions' in something permissionsIn :: a -> Member -> Permissions +-- | A 'Member''s 'Permissions' in a channel are their roles and overwrites instance PermissionsIn (Guild, GuildChannel) where permissionsIn (g, c) m = applyOverwrites c m $ basePermissions g m +-- | A 'Member''s 'Permissions' in a guild are just their roles instance PermissionsIn Guild where permissionsIn g m = basePermissions g m +-- | A variant of 'PermissionsIn' that will use the cache/http. class PermissionsIn' a where- permissionsIn' :: BotC r => a -> Member -> P.Sem r Permissions+ -- | Calculate the permissions of something that has a 'User' id+ --+ -- If permissions could not be calculated because something couldn't be found+ -- in the cache, this will return an empty set of permissions. Use+ -- 'permissionsIn' if you want to handle cases where something might not exist+ -- in cache.+ permissionsIn' :: (BotC r, HasID User u) => a -> u -> P.Sem r Permissions +-- | A 'User''s 'Permissions' in a channel are their roles and overwrites+--+-- This will fetch the guild from the cache or http as needed instance PermissionsIn' GuildChannel where- permissionsIn' c m = do+ permissionsIn' c (getID @User -> uid) = do+ m <- upgrade (getID @Guild c, coerceSnowflake @_ @Member uid) g <- upgrade (getID @Guild c)- case g of- Just g' -> pure $ permissionsIn (g', c) m- Nothing -> pure noFlags+ case (m, g) of+ (Just m, Just g') -> pure $ permissionsIn (g', c) m+ _ -> pure noFlags +-- | A 'Member''s 'Permissions' in a guild are just their roles instance PermissionsIn' Guild where- permissionsIn' g m = pure $ permissionsIn g m+ permissionsIn' g (getID @User -> uid) = do+ m <- upgrade (getID @Guild g, coerceSnowflake @_ @Member uid)+ case m of+ Just m' -> pure $ permissionsIn g m'+ Nothing -> pure noFlags +-- | A 'Member''s 'Permissions' in a channel are their roles and overwrites+--+-- This will fetch the guild and channel from the cache or http as needed instance PermissionsIn' (Snowflake GuildChannel) where- permissionsIn' cid m = do+ permissionsIn' cid u = do c <- upgrade cid case c of- Just c' -> permissionsIn' c' m- Nothing -> pure noFlags+ Just c' -> permissionsIn' c' u+ _ -> pure noFlags +-- | A 'Member''s 'Permissions' in a guild are just their roles+--+-- This will fetch the guild from the cache or http as needed instance PermissionsIn' (Snowflake Guild) where- permissionsIn' gid m = do+ permissionsIn' gid u = do g <- upgrade gid case g of- Just g' -> permissionsIn' g' m+ Just g' -> permissionsIn' g' u Nothing -> pure noFlags