calamity 0.1.28.3 → 0.1.28.4
raw patch · 7 files changed
+103/−58 lines, 7 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Calamity.HTTP.Internal.Route: instance Calamity.HTTP.Internal.Route.RouteFragmentable Calamity.HTTP.Internal.Route.S ids
- Calamity.HTTP.Internal.Route: instance Data.Hashable.Class.Hashable Calamity.HTTP.Internal.Route.Route
- Calamity.HTTP.Internal.Route: instance Data.Typeable.Internal.Typeable a => Calamity.HTTP.Internal.Route.RouteFragmentable (Calamity.HTTP.Internal.Route.ID a) ids
- Calamity.HTTP.Internal.Route: instance GHC.Classes.Eq Calamity.HTTP.Internal.Route.Route
- Calamity.HTTP.Internal.Types: [$sel:lock:Bucket] :: Bucket -> Lock
- Calamity.HTTP.Internal.Types: data Bucket
+ Calamity.HTTP.Internal.Route: PS :: PS (s :: Symbol)
+ Calamity.HTTP.Internal.Route: data PS (s :: Symbol)
+ Calamity.HTTP.Internal.Route: giveParam :: forall (s :: Symbol) reqs. KnownSymbol s => Text -> RouteBuilder reqs -> RouteBuilder ('( 'PSRequirement s, 'Satisfied) : reqs)
+ Calamity.HTTP.Internal.Route: instance Calamity.HTTP.Internal.Route.RouteFragmentable Calamity.HTTP.Internal.Route.S reqs
+ Calamity.HTTP.Internal.Route: instance Data.Typeable.Internal.Typeable a => Calamity.HTTP.Internal.Route.RouteFragmentable (Calamity.HTTP.Internal.Route.ID a) reqs
+ Calamity.HTTP.Internal.Route: instance GHC.TypeLits.KnownSymbol s => Calamity.HTTP.Internal.Route.RouteFragmentable (Calamity.HTTP.Internal.Route.PS s) reqs
+ Calamity.HTTP.Internal.Route: routeKey :: Route -> RouteKey
+ Calamity.HTTP.Internal.Route: type RouteKey = (Text, Maybe (Snowflake Channel), Maybe (Snowflake Guild))
+ Calamity.HTTP.Internal.Types: newtype Bucket
- Calamity.Cache.Eff: delDM :: forall r_a9tNC. MemberWithError CacheEff r_a9tNC => Snowflake DMChannel -> Sem r_a9tNC ()
+ Calamity.Cache.Eff: delDM :: forall r_a9tTw. MemberWithError CacheEff r_a9tTw => Snowflake DMChannel -> Sem r_a9tTw ()
- Calamity.Cache.Eff: delGuild :: forall r_a9tNv. MemberWithError CacheEff r_a9tNv => Snowflake Guild -> Sem r_a9tNv ()
+ Calamity.Cache.Eff: delGuild :: forall r_a9tTp. MemberWithError CacheEff r_a9tTp => Snowflake Guild -> Sem r_a9tTp ()
- Calamity.Cache.Eff: delMessage :: forall r_a9tNX. MemberWithError CacheEff r_a9tNX => Snowflake Message -> Sem r_a9tNX ()
+ Calamity.Cache.Eff: delMessage :: forall r_a9tTR. MemberWithError CacheEff r_a9tTR => Snowflake Message -> Sem r_a9tTR ()
- Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9tNQ. MemberWithError CacheEff r_a9tNQ => Snowflake Guild -> Sem r_a9tNQ ()
+ Calamity.Cache.Eff: delUnavailableGuild :: forall r_a9tTK. MemberWithError CacheEff r_a9tTK => Snowflake Guild -> Sem r_a9tTK ()
- Calamity.Cache.Eff: delUser :: forall r_a9tNJ. MemberWithError CacheEff r_a9tNJ => Snowflake User -> Sem r_a9tNJ ()
+ Calamity.Cache.Eff: delUser :: forall r_a9tTD. MemberWithError CacheEff r_a9tTD => Snowflake User -> Sem r_a9tTD ()
- Calamity.Cache.Eff: getBotUser :: forall r_a9tNn. MemberWithError CacheEff r_a9tNn => Sem r_a9tNn (Maybe User)
+ Calamity.Cache.Eff: getBotUser :: forall r_a9tTh. MemberWithError CacheEff r_a9tTh => Sem r_a9tTh (Maybe User)
- Calamity.Cache.Eff: getDM :: forall r_a9tNz. MemberWithError CacheEff r_a9tNz => Snowflake DMChannel -> Sem r_a9tNz (Maybe DMChannel)
+ Calamity.Cache.Eff: getDM :: forall r_a9tTt. MemberWithError CacheEff r_a9tTt => Snowflake DMChannel -> Sem r_a9tTt (Maybe DMChannel)
- Calamity.Cache.Eff: getDMs :: forall r_a9tNB. MemberWithError CacheEff r_a9tNB => Sem r_a9tNB [DMChannel]
+ Calamity.Cache.Eff: getDMs :: forall r_a9tTv. MemberWithError CacheEff r_a9tTv => Sem r_a9tTv [DMChannel]
- Calamity.Cache.Eff: getGuild :: forall r_a9tNq. MemberWithError CacheEff r_a9tNq => Snowflake Guild -> Sem r_a9tNq (Maybe Guild)
+ Calamity.Cache.Eff: getGuild :: forall r_a9tTk. MemberWithError CacheEff r_a9tTk => Snowflake Guild -> Sem r_a9tTk (Maybe Guild)
- Calamity.Cache.Eff: getGuildChannel :: forall r_a9tNs. MemberWithError CacheEff r_a9tNs => Snowflake GuildChannel -> Sem r_a9tNs (Maybe GuildChannel)
+ Calamity.Cache.Eff: getGuildChannel :: forall r_a9tTm. MemberWithError CacheEff r_a9tTm => Snowflake GuildChannel -> Sem r_a9tTm (Maybe GuildChannel)
- Calamity.Cache.Eff: getGuilds :: forall r_a9tNu. MemberWithError CacheEff r_a9tNu => Sem r_a9tNu [Guild]
+ Calamity.Cache.Eff: getGuilds :: forall r_a9tTo. MemberWithError CacheEff r_a9tTo => Sem r_a9tTo [Guild]
- Calamity.Cache.Eff: getMessage :: forall r_a9tNU. MemberWithError CacheEff r_a9tNU => Snowflake Message -> Sem r_a9tNU (Maybe Message)
+ Calamity.Cache.Eff: getMessage :: forall r_a9tTO. MemberWithError CacheEff r_a9tTO => Snowflake Message -> Sem r_a9tTO (Maybe Message)
- Calamity.Cache.Eff: getMessages :: forall r_a9tNW. MemberWithError CacheEff r_a9tNW => Sem r_a9tNW [Message]
+ Calamity.Cache.Eff: getMessages :: forall r_a9tTQ. MemberWithError CacheEff r_a9tTQ => Sem r_a9tTQ [Message]
- Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9tNP. MemberWithError CacheEff r_a9tNP => Sem r_a9tNP [Snowflake Guild]
+ Calamity.Cache.Eff: getUnavailableGuilds :: forall r_a9tTJ. MemberWithError CacheEff r_a9tTJ => Sem r_a9tTJ [Snowflake Guild]
- Calamity.Cache.Eff: getUser :: forall r_a9tNG. MemberWithError CacheEff r_a9tNG => Snowflake User -> Sem r_a9tNG (Maybe User)
+ Calamity.Cache.Eff: getUser :: forall r_a9tTA. MemberWithError CacheEff r_a9tTA => Snowflake User -> Sem r_a9tTA (Maybe User)
- Calamity.Cache.Eff: getUsers :: forall r_a9tNI. MemberWithError CacheEff r_a9tNI => Sem r_a9tNI [User]
+ Calamity.Cache.Eff: getUsers :: forall r_a9tTC. MemberWithError CacheEff r_a9tTC => Sem r_a9tTC [User]
- Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9tNN. MemberWithError CacheEff r_a9tNN => Snowflake Guild -> Sem r_a9tNN Bool
+ Calamity.Cache.Eff: isUnavailableGuild :: forall r_a9tTH. MemberWithError CacheEff r_a9tTH => Snowflake Guild -> Sem r_a9tTH Bool
- Calamity.Cache.Eff: setBotUser :: forall r_a9tNl. MemberWithError CacheEff r_a9tNl => User -> Sem r_a9tNl ()
+ Calamity.Cache.Eff: setBotUser :: forall r_a9tTf. MemberWithError CacheEff r_a9tTf => User -> Sem r_a9tTf ()
- Calamity.Cache.Eff: setDM :: forall r_a9tNx. MemberWithError CacheEff r_a9tNx => DMChannel -> Sem r_a9tNx ()
+ Calamity.Cache.Eff: setDM :: forall r_a9tTr. MemberWithError CacheEff r_a9tTr => DMChannel -> Sem r_a9tTr ()
- Calamity.Cache.Eff: setGuild :: forall r_a9tNo. MemberWithError CacheEff r_a9tNo => Guild -> Sem r_a9tNo ()
+ Calamity.Cache.Eff: setGuild :: forall r_a9tTi. MemberWithError CacheEff r_a9tTi => Guild -> Sem r_a9tTi ()
- Calamity.Cache.Eff: setMessage :: forall r_a9tNS. MemberWithError CacheEff r_a9tNS => Message -> Sem r_a9tNS ()
+ Calamity.Cache.Eff: setMessage :: forall r_a9tTM. MemberWithError CacheEff r_a9tTM => Message -> Sem r_a9tTM ()
- Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9tNL. MemberWithError CacheEff r_a9tNL => Snowflake Guild -> Sem r_a9tNL ()
+ Calamity.Cache.Eff: setUnavailableGuild :: forall r_a9tTF. MemberWithError CacheEff r_a9tTF => Snowflake Guild -> Sem r_a9tTF ()
- Calamity.Cache.Eff: setUser :: forall r_a9tNE. MemberWithError CacheEff r_a9tNE => User -> Sem r_a9tNE ()
+ Calamity.Cache.Eff: setUser :: forall r_a9tTy. MemberWithError CacheEff r_a9tTy => User -> Sem r_a9tTy ()
- Calamity.HTTP.Internal.Route: (//) :: RouteFragmentable a ids => RouteBuilder ids -> a -> ConsRes a ids
+ Calamity.HTTP.Internal.Route: (//) :: RouteFragmentable a reqs => RouteBuilder reqs -> a -> ConsRes a reqs
- Calamity.HTTP.Internal.Route: buildRoute :: forall (ids :: [(Type, RouteRequirement)]). EnsureFulfilled ids => RouteBuilder ids -> Route
+ Calamity.HTTP.Internal.Route: buildRoute :: forall (reqs :: [(RequirementType, RouteRequirement)]). EnsureFulfilled reqs => RouteBuilder reqs -> Route
- Calamity.HTTP.Internal.Route: class Typeable a => RouteFragmentable a ids where {
+ Calamity.HTTP.Internal.Route: class Typeable a => RouteFragmentable a reqs where {
- Calamity.HTTP.Internal.Route: data RouteBuilder (idState :: [(Type, RouteRequirement)])
+ Calamity.HTTP.Internal.Route: data RouteBuilder (reqstate :: [(RequirementType, RouteRequirement)])
- Calamity.HTTP.Internal.Route: giveID :: forall k ids. Typeable k => Snowflake k -> RouteBuilder ids -> RouteBuilder ('(k, 'Satisfied) : ids)
+ Calamity.HTTP.Internal.Route: giveID :: forall t reqs. Typeable t => Snowflake t -> RouteBuilder reqs -> RouteBuilder ('( 'IDRequirement t, 'Satisfied) : reqs)
- Calamity.HTTP.Internal.Route: type family ConsRes a ids;
+ Calamity.HTTP.Internal.Route: type family ConsRes a reqs;
- Calamity.HTTP.Internal.Types: Bucket :: Lock -> TVar BucketState -> Bucket
+ Calamity.HTTP.Internal.Types: Bucket :: TVar BucketState -> Bucket
- Calamity.HTTP.Internal.Types: RateLimitState :: Map Route ByteString -> Map ByteString Bucket -> Event -> RateLimitState
+ Calamity.HTTP.Internal.Types: RateLimitState :: Map RouteKey ByteString -> Map ByteString Bucket -> Event -> RateLimitState
- Calamity.HTTP.Internal.Types: [$sel:bucketKeys:RateLimitState] :: RateLimitState -> Map Route ByteString
+ Calamity.HTTP.Internal.Types: [$sel:bucketKeys:RateLimitState] :: RateLimitState -> Map RouteKey ByteString
Files
- Calamity/HTTP/Channel.hs +8/−4
- Calamity/HTTP/Internal/Ratelimit.hs +10/−13
- Calamity/HTTP/Internal/Route.hs +71/−32
- Calamity/HTTP/Internal/Types.hs +3/−5
- Calamity/HTTP/Invite.hs +4/−2
- ChangeLog.md +5/−0
- calamity.cabal +2/−2
Calamity/HTTP/Channel.hs view
@@ -235,21 +235,25 @@ & giveID mid & buildRoute route (CreateReaction (getID -> cid) (getID @Message -> mid) emoji) =- baseRoute cid // S "messages" // ID @Message // S "reactions" // S (renderEmoji emoji) // S "@me"+ baseRoute cid // S "messages" // ID @Message // S "reactions" // PS @"emoji" // S "@me" & giveID mid+ & giveParam @"emoji" (renderEmoji emoji) & buildRoute route (DeleteOwnReaction (getID -> cid) (getID @Message -> mid) emoji) =- baseRoute cid // S "messages" // ID @Message // S "reactions" // S (renderEmoji emoji) // S "@me"+ baseRoute cid // S "messages" // ID @Message // S "reactions" // PS @"emoji" // S "@me" & giveID mid+ & giveParam @"emoji" (renderEmoji emoji) & buildRoute route (DeleteUserReaction (getID -> cid) (getID @Message -> mid) emoji (getID @User -> uid)) =- baseRoute cid // S "messages" // ID @Message // S "reactions" // S (renderEmoji emoji) // ID @User+ baseRoute cid // S "messages" // ID @Message // S "reactions" // PS @"emoji" // ID @User & giveID mid & giveID uid+ & giveParam @"emoji" (renderEmoji emoji) & buildRoute route (GetReactions (getID -> cid) (getID @Message -> mid) emoji _) =- baseRoute cid // S "messages" // ID @Message // S "reactions" // S (renderEmoji emoji)+ baseRoute cid // S "messages" // ID @Message // S "reactions" // PS @"emoji" & giveID mid+ & giveParam @"emoji" (renderEmoji emoji) & buildRoute route (DeleteAllReactions (getID -> cid) (getID @Message -> mid)) = baseRoute cid // S "messages" // ID @Message // S "reactions"
Calamity/HTTP/Internal/Ratelimit.hs view
@@ -14,7 +14,6 @@ import Control.Concurrent.Event (Event) import qualified Control.Concurrent.Event as E import Control.Concurrent.STM-import qualified Control.Concurrent.STM.Lock as L import Control.Lens import Control.Monad @@ -47,9 +46,9 @@ data Ratelimit = KnownRatelimit Bucket- | UnknownRatelimit Route+ | UnknownRatelimit RouteKey -getRateLimit :: RateLimitState -> Route -> STM Ratelimit+getRateLimit :: RateLimitState -> RouteKey -> STM Ratelimit getRateLimit s h = do bucketKey <- SC.lookup h $ bucketKeys s bucket <- join <$> sequenceA (flip SC.lookup (buckets s) <$> bucketKey)@@ -62,7 +61,7 @@ {- | Knowing the bucket for a route, and the ratelimit info, map the route to the bucket key and retrieve the bucket -}-updateBucket :: RateLimitState -> Route -> B.ByteString -> BucketState -> STM Bucket+updateBucket :: RateLimitState -> RouteKey -> B.ByteString -> BucketState -> STM Bucket updateBucket s h b bucketState = do bucketKey <- SC.lookup h $ bucketKeys s case bucketKey of@@ -77,12 +76,10 @@ Nothing -> Prelude.error "Not possible" Nothing -> do -- the bucket key wasn't known, make a new bucket and insert it- lock <- L.new- bs <- newTVar bucketState- let bucket = Bucket lock bs- SC.insert bucket b $ buckets s+ bs <- Bucket <$> newTVar bucketState+ SC.insert bs b $ buckets s SC.insert b h $ bucketKeys s- pure bucket+ pure bs where mergeStates :: BucketState -> BucketState -> BucketState mergeStates old new =@@ -321,7 +318,7 @@ doSingleRequest rlstate route gl r = do P.embed $ E.wait (globalLock rlstate) - rl <- P.embed . atomically $ getRateLimit rlstate route+ rl <- P.embed . atomically $ getRateLimit rlstate (routeKey route) case rl of KnownRatelimit bucket ->@@ -339,7 +336,7 @@ _ -> pure () case rlHeaders of Just (bs, bk) ->- void $ updateBucket rlstate route bk bs+ void $ updateBucket rlstate (routeKey route) bk bs Nothing -> pure () pure $ RGood v Ratelimited unlockWhen False (Just (bs, bk)) -> do@@ -350,7 +347,7 @@ KnownRatelimit bucket -> modifyTVar' (bucket ^. #state) (#ongoing -~ 1) _ -> pure ()- void $ updateBucket rlstate route bk bs+ void $ updateBucket rlstate (routeKey route) bk bs P.embed $ do threadDelayUntil unlockWhen@@ -376,7 +373,7 @@ _ -> pure () case bs of Just (bs', bk) ->- void $ updateBucket rlstate route bk bs'+ void $ updateBucket rlstate (routeKey route) bk bs' Nothing -> pure ()
Calamity/HTTP/Internal/Route.hs view
@@ -5,11 +5,15 @@ module Calamity.HTTP.Internal.Route ( mkRouteBuilder , giveID+ , giveParam , buildRoute+ , routeKey+ , RouteKey , RouteBuilder , RouteRequirement , Route(path) , S(..)+ , PS(..) , ID(..) , RouteFragmentable(..) ) where @@ -31,14 +35,24 @@ import GHC.Generics hiding ( S ) import TextShow+import GHC.TypeLits (Symbol, KnownSymbol, symbolVal) data RouteFragment = S' Text+ -- ^ Static string fragment+ | PS' String+ -- ^ Parameterised string fragment | ID' TypeRep+ -- ^ ID fragment deriving ( Generic, Show, Eq ) +-- | A static string fragment of a route newtype S = S Text +-- | A parameterised string fragment of a route+data PS (s :: Symbol) = PS++-- | An id fragment of a route data ID a = ID instance Hashable RouteFragment@@ -49,23 +63,37 @@ | Satisfied deriving ( Generic, Show, Eq ) -data RouteBuilder (idState :: [(Type, RouteRequirement)]) = UnsafeMkRouteBuilder+data RequirementType+ = IDRequirement Type+ | PSRequirement Symbol++data RouteBuilder (reqstate :: [(RequirementType, RouteRequirement)]) = UnsafeMkRouteBuilder { route :: [RouteFragment] , ids :: [(TypeRep, Word64)]+ , params :: [(String, Text)] } mkRouteBuilder :: RouteBuilder '[]-mkRouteBuilder = UnsafeMkRouteBuilder [] []+mkRouteBuilder = UnsafeMkRouteBuilder [] [] [] giveID- :: forall k ids- . Typeable k- => Snowflake k- -> RouteBuilder ids- -> RouteBuilder ('(k, 'Satisfied) ': ids)-giveID (Snowflake id) (UnsafeMkRouteBuilder route ids) =- UnsafeMkRouteBuilder route ((typeRep (Proxy @k), id) : ids)+ :: forall t reqs+ . Typeable t+ => Snowflake t+ -> RouteBuilder reqs+ -> RouteBuilder ('( 'IDRequirement t, 'Satisfied) ': reqs)+giveID (Snowflake id) (UnsafeMkRouteBuilder route ids params) =+ UnsafeMkRouteBuilder route ((typeRep $ Proxy @t, id) : ids) params +giveParam+ :: forall (s :: Symbol) reqs+ . KnownSymbol s+ => Text+ -> RouteBuilder reqs+ -> RouteBuilder ('( 'PSRequirement s, 'Satisfied) ': reqs)+giveParam value (UnsafeMkRouteBuilder route ids params) =+ UnsafeMkRouteBuilder route ids ((symbolVal $ Proxy @s, value) : params)+ type family (&&) (a :: Bool) (b :: Bool) :: Bool where 'True && 'True = 'True _ && _ = 'False@@ -80,17 +108,17 @@ IsElem k (k : _) = 'True IsElem k (_ : xs) = IsElem k xs -type family EnsureFulfilled (ids :: [(k, RouteRequirement)]) :: Constraint where- EnsureFulfilled ids = EnsureFulfilledInner ids '[] 'True+type family EnsureFulfilled (reqs :: [(RequirementType, RouteRequirement)]) :: Constraint where+ EnsureFulfilled reqs = EnsureFulfilledInner reqs '[] 'True -type family EnsureFulfilledInner (ids :: [(k, RouteRequirement)]) (seen :: [k]) (ok :: Bool) :: Constraint where+type family EnsureFulfilledInner (reqs :: [(RequirementType, RouteRequirement)]) (seen :: [RequirementType]) (ok :: Bool) :: Constraint where EnsureFulfilledInner '[] _ 'True = () EnsureFulfilledInner ('(k, 'NotNeeded) ': xs) seen ok = EnsureFulfilledInner xs (k ': seen) ok EnsureFulfilledInner ('(k, 'Satisfied) ': xs) seen ok = EnsureFulfilledInner xs (k ': seen) ok EnsureFulfilledInner ('(k, 'Required) ': xs) seen ok = EnsureFulfilledInner xs (k ': seen) (IsElem k seen && ok) -type family AddRequired k (ids :: [(Type, RouteRequirement)]) :: [(Type, RouteRequirement)] where- AddRequired k ids = '(k, AddRequiredInner (Lookup k ids)) ': ids+type family AddRequired k (reqs :: [(RequirementType, RouteRequirement)]) :: [(RequirementType, RouteRequirement)] where+ AddRequired k reqs = '(k, AddRequiredInner (Lookup k reqs)) ': reqs type family AddRequiredInner (k :: Maybe RouteRequirement) :: RouteRequirement where AddRequiredInner ('Just 'Required) = 'Required@@ -98,23 +126,30 @@ AddRequiredInner ('Just 'NotNeeded) = 'Required AddRequiredInner 'Nothing = 'Required -class Typeable a => RouteFragmentable a ids where- type ConsRes a ids+class Typeable a => RouteFragmentable a reqs where+ type ConsRes a reqs - (//) :: RouteBuilder ids -> a -> ConsRes a ids+ (//) :: RouteBuilder reqs -> a -> ConsRes a reqs -instance RouteFragmentable S ids where- type ConsRes S ids = RouteBuilder ids+instance RouteFragmentable S reqs where+ type ConsRes S reqs = RouteBuilder reqs - (UnsafeMkRouteBuilder r ids) // (S t) =- UnsafeMkRouteBuilder (r <> [S' t]) ids+ (UnsafeMkRouteBuilder r ids params) // (S t) =+ UnsafeMkRouteBuilder (r <> [S' t]) ids params -instance Typeable a => RouteFragmentable (ID (a :: Type)) (ids :: [(Type, RouteRequirement)]) where- type ConsRes (ID a) ids = RouteBuilder (AddRequired a ids)+instance Typeable a => RouteFragmentable (ID (a :: Type)) (reqs :: [(RequirementType, RouteRequirement)]) where+ type ConsRes (ID a) reqs = RouteBuilder (AddRequired ('IDRequirement a) reqs) - (UnsafeMkRouteBuilder r ids) // ID =- UnsafeMkRouteBuilder (r <> [ID' (typeRep (Proxy @a))]) ids+ (UnsafeMkRouteBuilder r ids params) // ID =+ UnsafeMkRouteBuilder (r <> [ID' $ typeRep $ Proxy @a]) ids params +instance KnownSymbol s => RouteFragmentable (PS s) (reqs :: [(RequirementType, RouteRequirement)]) where+ type ConsRes (PS s) reqs = RouteBuilder (AddRequired ('PSRequirement s) reqs)++ (UnsafeMkRouteBuilder r ids params) // PS =+ UnsafeMkRouteBuilder (r <> [PS' $ symbolVal $ Proxy @s]) ids params++ infixl 5 // data Route = Route@@ -122,27 +157,31 @@ , key :: Text , channelID :: Maybe (Snowflake Channel) , guildID :: Maybe (Snowflake Guild)- } deriving (Generic, Show, Eq)+ } deriving (Generic, Show) -instance Hashable Route where- hashWithSalt s (Route _ ident c g) = hashWithSalt s (ident, c, g)+type RouteKey = (Text, Maybe (Snowflake Channel), Maybe (Snowflake Guild)) +routeKey :: Route -> RouteKey+routeKey Route {key, channelID, guildID} = (key, channelID, guildID)+ baseURL :: Url 'Https baseURL = https "discord.com" /: "api" /: "v8" buildRoute- :: forall (ids :: [(Type, RouteRequirement)])- . EnsureFulfilled ids- => RouteBuilder ids+ :: forall (reqs :: [(RequirementType, RouteRequirement)])+ . EnsureFulfilled reqs+ => RouteBuilder reqs -> Route-buildRoute (UnsafeMkRouteBuilder route ids) = Route+buildRoute (UnsafeMkRouteBuilder route ids params) = Route (foldl' (/:) baseURL $ map goR route) (T.concat (map goIdent route)) (Snowflake <$> lookup (typeRep (Proxy @Channel)) ids) (Snowflake <$> lookup (typeRep (Proxy @Guild)) ids) where goR (S' t) = t+ goR (PS' t) = fromJust $ lookup t params goR (ID' t) = showt . fromJust $ lookup t ids goIdent (S' t) = t+ goIdent (PS' s) = T.pack s goIdent (ID' t) = showt t
Calamity/HTTP/Internal/Types.hs view
@@ -12,7 +12,6 @@ import Calamity.Internal.AesonThings import Control.Concurrent.Event ( Event )-import Control.Concurrent.STM.Lock ( Lock ) import Control.Concurrent.STM.TVar ( TVar ) import Data.Time@@ -49,14 +48,13 @@ } deriving ( Generic, Show ) -data Bucket = Bucket- { lock :: Lock- , state :: TVar BucketState+newtype Bucket = Bucket+ { state :: TVar BucketState } deriving ( Generic ) data RateLimitState = RateLimitState- { bucketKeys :: SC.Map Route B.ByteString+ { bucketKeys :: SC.Map RouteKey B.ByteString , buckets :: SC.Map B.ByteString Bucket , globalLock :: Event }
Calamity/HTTP/Invite.hs view
@@ -22,10 +22,12 @@ type Result (InviteRequest a) = a route (GetInvite c) =- baseRoute // S c+ baseRoute // PS @"invite"+ & giveParam @"invite" c & buildRoute route (DeleteInvite c) =- baseRoute // S c+ baseRoute // PS @"invite"+ & giveParam @"invite" c & buildRoute action (GetInvite _) = getWithP ("with_counts" =: True)
ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for Calamity +## 0.1.28.4+++ Rework the route handling so that the bucket keys for emoji routes work+ properly+ ## 0.1.28.3 + Fix HTTP responses from discord that don't have ratelimit info being treated
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 3ef864682cfb94fce9b938cf2c9b2cf32ac1170e904fb5fd492abf28259a6c81+-- hash: ab4efef98213c2235c6f8062573bbfac890f01cc09133f83530d5e4388dbcccd name: calamity-version: 0.1.28.3+version: 0.1.28.4 synopsis: A library for writing discord bots in haskell description: Please see the README on GitHub at <https://github.com/simmsb/calamity#readme> category: Network, Web