-- | The snowflake type
module Calamity.Types.Snowflake
    ( Snowflake(..)
    , HasID(..)
    , type HasID'
    , HasIDField(..)
    , HasIDFieldCoerce(..)
    , type HasIDFieldCoerce'
    , coerceSnowflake ) where

import           Control.DeepSeq
import           Control.Lens
import           Control.Monad

import           Data.Aeson
import           Data.Data
import           Data.Generics.Product.Fields
import           Data.Hashable
import           Data.Text.Read
import qualified Data.Vector.Generic.Base     as V
import qualified Data.Vector.Generic.Mutable  as MV
import qualified Data.Vector.Unboxed          as U
import           Data.Word

import           GHC.Generics

import           TextShow
import qualified TextShow.Generic as TSG

-- Thanks sbrg
-- https://github.com/saevarb/haskord/blob/d1bb07bcc4f3dbc29f2dfd3351ff9f16fc100c07/haskord-lib/src/Haskord/Types/Common.hs#L78
newtype Snowflake t = Snowflake
  { Snowflake t -> Word64
fromSnowflake :: Word64
  }
  deriving ( (forall x. Snowflake t -> Rep (Snowflake t) x)
-> (forall x. Rep (Snowflake t) x -> Snowflake t)
-> Generic (Snowflake t)
forall x. Rep (Snowflake t) x -> Snowflake t
forall x. Snowflake t -> Rep (Snowflake t) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall k (t :: k) x. Rep (Snowflake t) x -> Snowflake t
forall k (t :: k) x. Snowflake t -> Rep (Snowflake t) x
$cto :: forall k (t :: k) x. Rep (Snowflake t) x -> Snowflake t
$cfrom :: forall k (t :: k) x. Snowflake t -> Rep (Snowflake t) x
Generic, Int -> Snowflake t -> ShowS
[Snowflake t] -> ShowS
Snowflake t -> String
(Int -> Snowflake t -> ShowS)
-> (Snowflake t -> String)
-> ([Snowflake t] -> ShowS)
-> Show (Snowflake t)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (t :: k). Int -> Snowflake t -> ShowS
forall k (t :: k). [Snowflake t] -> ShowS
forall k (t :: k). Snowflake t -> String
showList :: [Snowflake t] -> ShowS
$cshowList :: forall k (t :: k). [Snowflake t] -> ShowS
show :: Snowflake t -> String
$cshow :: forall k (t :: k). Snowflake t -> String
showsPrec :: Int -> Snowflake t -> ShowS
$cshowsPrec :: forall k (t :: k). Int -> Snowflake t -> ShowS
Show, Snowflake t -> Snowflake t -> Bool
(Snowflake t -> Snowflake t -> Bool)
-> (Snowflake t -> Snowflake t -> Bool) -> Eq (Snowflake t)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (t :: k). Snowflake t -> Snowflake t -> Bool
/= :: Snowflake t -> Snowflake t -> Bool
$c/= :: forall k (t :: k). Snowflake t -> Snowflake t -> Bool
== :: Snowflake t -> Snowflake t -> Bool
$c== :: forall k (t :: k). Snowflake t -> Snowflake t -> Bool
Eq, Eq (Snowflake t)
Eq (Snowflake t) =>
(Snowflake t -> Snowflake t -> Ordering)
-> (Snowflake t -> Snowflake t -> Bool)
-> (Snowflake t -> Snowflake t -> Bool)
-> (Snowflake t -> Snowflake t -> Bool)
-> (Snowflake t -> Snowflake t -> Bool)
-> (Snowflake t -> Snowflake t -> Snowflake t)
-> (Snowflake t -> Snowflake t -> Snowflake t)
-> Ord (Snowflake t)
Snowflake t -> Snowflake t -> Bool
Snowflake t -> Snowflake t -> Ordering
Snowflake t -> Snowflake t -> Snowflake t
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
forall k (t :: k). Eq (Snowflake t)
forall k (t :: k). Snowflake t -> Snowflake t -> Bool
forall k (t :: k). Snowflake t -> Snowflake t -> Ordering
forall k (t :: k). Snowflake t -> Snowflake t -> Snowflake t
min :: Snowflake t -> Snowflake t -> Snowflake t
$cmin :: forall k (t :: k). Snowflake t -> Snowflake t -> Snowflake t
max :: Snowflake t -> Snowflake t -> Snowflake t
$cmax :: forall k (t :: k). Snowflake t -> Snowflake t -> Snowflake t
>= :: Snowflake t -> Snowflake t -> Bool
$c>= :: forall k (t :: k). Snowflake t -> Snowflake t -> Bool
> :: Snowflake t -> Snowflake t -> Bool
$c> :: forall k (t :: k). Snowflake t -> Snowflake t -> Bool
<= :: Snowflake t -> Snowflake t -> Bool
$c<= :: forall k (t :: k). Snowflake t -> Snowflake t -> Bool
< :: Snowflake t -> Snowflake t -> Bool
$c< :: forall k (t :: k). Snowflake t -> Snowflake t -> Bool
compare :: Snowflake t -> Snowflake t -> Ordering
$ccompare :: forall k (t :: k). Snowflake t -> Snowflake t -> Ordering
$cp1Ord :: forall k (t :: k). Eq (Snowflake t)
Ord, Typeable (Snowflake t)
DataType
Constr
Typeable (Snowflake t) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Snowflake t -> c (Snowflake t))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Snowflake t))
-> (Snowflake t -> Constr)
-> (Snowflake t -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Snowflake t)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Snowflake t)))
-> ((forall b. Data b => b -> b) -> Snowflake t -> Snowflake t)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Snowflake t -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Snowflake t -> r)
-> (forall u. (forall d. Data d => d -> u) -> Snowflake t -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Snowflake t -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t))
-> Data (Snowflake t)
Snowflake t -> DataType
Snowflake t -> Constr
(forall b. Data b => b -> b) -> Snowflake t -> Snowflake t
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Snowflake t -> c (Snowflake t)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Snowflake t)
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) -> Snowflake t -> u
forall u. (forall d. Data d => d -> u) -> Snowflake t -> [u]
forall k (t :: k).
(Typeable t, Typeable k) =>
Typeable (Snowflake t)
forall k (t :: k).
(Typeable t, Typeable k) =>
Snowflake t -> DataType
forall k (t :: k).
(Typeable t, Typeable k) =>
Snowflake t -> Constr
forall k (t :: k).
(Typeable t, Typeable k) =>
(forall b. Data b => b -> b) -> Snowflake t -> Snowflake t
forall k (t :: k) u.
(Typeable t, Typeable k) =>
Int -> (forall d. Data d => d -> u) -> Snowflake t -> u
forall k (t :: k) u.
(Typeable t, Typeable k) =>
(forall d. Data d => d -> u) -> Snowflake t -> [u]
forall k (t :: k) r r'.
(Typeable t, Typeable k) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
forall k (t :: k) r r'.
(Typeable t, Typeable k) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
forall k (t :: k) (m :: * -> *).
(Typeable t, Typeable k, Monad m) =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
forall k (t :: k) (m :: * -> *).
(Typeable t, Typeable k, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
forall k (t :: k) (c :: * -> *).
(Typeable t, Typeable k) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Snowflake t)
forall k (t :: k) (c :: * -> *).
(Typeable t, Typeable k) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Snowflake t -> c (Snowflake t)
forall k (t :: k) (t :: * -> *) (c :: * -> *).
(Typeable t, Typeable k, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Snowflake t))
forall k (t :: k) (t :: * -> * -> *) (c :: * -> *).
(Typeable t, Typeable k, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Snowflake t))
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Snowflake t)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Snowflake t -> c (Snowflake t)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Snowflake t))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Snowflake t))
$cSnowflake :: Constr
$tSnowflake :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
$cgmapMo :: forall k (t :: k) (m :: * -> *).
(Typeable t, Typeable k, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
gmapMp :: (forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
$cgmapMp :: forall k (t :: k) (m :: * -> *).
(Typeable t, Typeable k, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
gmapM :: (forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
$cgmapM :: forall k (t :: k) (m :: * -> *).
(Typeable t, Typeable k, Monad m) =>
(forall d. Data d => d -> m d) -> Snowflake t -> m (Snowflake t)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Snowflake t -> u
$cgmapQi :: forall k (t :: k) u.
(Typeable t, Typeable k) =>
Int -> (forall d. Data d => d -> u) -> Snowflake t -> u
gmapQ :: (forall d. Data d => d -> u) -> Snowflake t -> [u]
$cgmapQ :: forall k (t :: k) u.
(Typeable t, Typeable k) =>
(forall d. Data d => d -> u) -> Snowflake t -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
$cgmapQr :: forall k (t :: k) r r'.
(Typeable t, Typeable k) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
$cgmapQl :: forall k (t :: k) r r'.
(Typeable t, Typeable k) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Snowflake t -> r
gmapT :: (forall b. Data b => b -> b) -> Snowflake t -> Snowflake t
$cgmapT :: forall k (t :: k).
(Typeable t, Typeable k) =>
(forall b. Data b => b -> b) -> Snowflake t -> Snowflake t
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Snowflake t))
$cdataCast2 :: forall k (t :: k) (t :: * -> * -> *) (c :: * -> *).
(Typeable t, Typeable k, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Snowflake t))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Snowflake t))
$cdataCast1 :: forall k (t :: k) (t :: * -> *) (c :: * -> *).
(Typeable t, Typeable k, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Snowflake t))
dataTypeOf :: Snowflake t -> DataType
$cdataTypeOf :: forall k (t :: k).
(Typeable t, Typeable k) =>
Snowflake t -> DataType
toConstr :: Snowflake t -> Constr
$ctoConstr :: forall k (t :: k).
(Typeable t, Typeable k) =>
Snowflake t -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Snowflake t)
$cgunfold :: forall k (t :: k) (c :: * -> *).
(Typeable t, Typeable k) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Snowflake t)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Snowflake t -> c (Snowflake t)
$cgfoldl :: forall k (t :: k) (c :: * -> *).
(Typeable t, Typeable k) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Snowflake t -> c (Snowflake t)
$cp1Data :: forall k (t :: k).
(Typeable t, Typeable k) =>
Typeable (Snowflake t)
Data )
  deriving ( Int -> Snowflake t -> Builder
Int -> Snowflake t -> Text
Int -> Snowflake t -> Text
[Snowflake t] -> Builder
[Snowflake t] -> Text
[Snowflake t] -> Text
Snowflake t -> Builder
Snowflake t -> Text
Snowflake t -> Text
(Int -> Snowflake t -> Builder)
-> (Snowflake t -> Builder)
-> ([Snowflake t] -> Builder)
-> (Int -> Snowflake t -> Text)
-> (Snowflake t -> Text)
-> ([Snowflake t] -> Text)
-> (Int -> Snowflake t -> Text)
-> (Snowflake t -> Text)
-> ([Snowflake t] -> Text)
-> TextShow (Snowflake t)
forall a.
(Int -> a -> Builder)
-> (a -> Builder)
-> ([a] -> Builder)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> (Int -> a -> Text)
-> (a -> Text)
-> ([a] -> Text)
-> TextShow a
forall k (t :: k). Int -> Snowflake t -> Builder
forall k (t :: k). Int -> Snowflake t -> Text
forall k (t :: k). Int -> Snowflake t -> Text
forall k (t :: k). [Snowflake t] -> Builder
forall k (t :: k). [Snowflake t] -> Text
forall k (t :: k). [Snowflake t] -> Text
forall k (t :: k). Snowflake t -> Builder
forall k (t :: k). Snowflake t -> Text
forall k (t :: k). Snowflake t -> Text
showtlList :: [Snowflake t] -> Text
$cshowtlList :: forall k (t :: k). [Snowflake t] -> Text
showtl :: Snowflake t -> Text
$cshowtl :: forall k (t :: k). Snowflake t -> Text
showtlPrec :: Int -> Snowflake t -> Text
$cshowtlPrec :: forall k (t :: k). Int -> Snowflake t -> Text
showtList :: [Snowflake t] -> Text
$cshowtList :: forall k (t :: k). [Snowflake t] -> Text
showt :: Snowflake t -> Text
$cshowt :: forall k (t :: k). Snowflake t -> Text
showtPrec :: Int -> Snowflake t -> Text
$cshowtPrec :: forall k (t :: k). Int -> Snowflake t -> Text
showbList :: [Snowflake t] -> Builder
$cshowbList :: forall k (t :: k). [Snowflake t] -> Builder
showb :: Snowflake t -> Builder
$cshowb :: forall k (t :: k). Snowflake t -> Builder
showbPrec :: Int -> Snowflake t -> Builder
$cshowbPrec :: forall k (t :: k). Int -> Snowflake t -> Builder
TextShow ) via TSG.FromGeneric (Snowflake t)
  deriving newtype ( Snowflake t -> ()
(Snowflake t -> ()) -> NFData (Snowflake t)
forall a. (a -> ()) -> NFData a
forall k (t :: k). Snowflake t -> ()
rnf :: Snowflake t -> ()
$crnf :: forall k (t :: k). Snowflake t -> ()
NFData, ToJSONKeyFunction [Snowflake t]
ToJSONKeyFunction (Snowflake t)
ToJSONKeyFunction (Snowflake t)
-> ToJSONKeyFunction [Snowflake t] -> ToJSONKey (Snowflake t)
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
forall k (t :: k). ToJSONKeyFunction [Snowflake t]
forall k (t :: k). ToJSONKeyFunction (Snowflake t)
toJSONKeyList :: ToJSONKeyFunction [Snowflake t]
$ctoJSONKeyList :: forall k (t :: k). ToJSONKeyFunction [Snowflake t]
toJSONKey :: ToJSONKeyFunction (Snowflake t)
$ctoJSONKey :: forall k (t :: k). ToJSONKeyFunction (Snowflake t)
ToJSONKey, Int -> Snowflake t -> Int
Snowflake t -> Int
(Int -> Snowflake t -> Int)
-> (Snowflake t -> Int) -> Hashable (Snowflake t)
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
forall k (t :: k). Int -> Snowflake t -> Int
forall k (t :: k). Snowflake t -> Int
hash :: Snowflake t -> Int
$chash :: forall k (t :: k). Snowflake t -> Int
hashWithSalt :: Int -> Snowflake t -> Int
$chashWithSalt :: forall k (t :: k). Int -> Snowflake t -> Int
Hashable )

instance ToJSON (Snowflake t) where
  toJSON :: Snowflake t -> Value
toJSON (Snowflake s :: Word64
s) = Text -> Value
String (Text -> Value) -> (Word64 -> Text) -> Word64 -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Text
forall a. TextShow a => a -> Text
showt (Word64 -> Value) -> Word64 -> Value
forall a b. (a -> b) -> a -> b
$ Word64
s

instance FromJSON (Snowflake t) where
  parseJSON :: Value -> Parser (Snowflake t)
parseJSON = String
-> (Text -> Parser (Snowflake t)) -> Value -> Parser (Snowflake t)
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText "Snowflake" ((Text -> Parser (Snowflake t)) -> Value -> Parser (Snowflake t))
-> (Text -> Parser (Snowflake t)) -> Value -> Parser (Snowflake t)
forall a b. (a -> b) -> a -> b
$ \t :: Text
t -> do
    Word64
n <- case Reader Word64
forall a. Integral a => Reader a
decimal Text
t of
      Right (n :: Word64
n, _) -> Word64 -> Parser Word64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word64
n
      Left e :: String
e       -> String -> Parser Word64
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
e
    Snowflake t -> Parser (Snowflake t)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Snowflake t -> Parser (Snowflake t))
-> Snowflake t -> Parser (Snowflake t)
forall a b. (a -> b) -> a -> b
$ Word64 -> Snowflake t
forall k (t :: k). Word64 -> Snowflake t
Snowflake Word64
n

coerceSnowflake :: Snowflake a -> Snowflake b
coerceSnowflake :: Snowflake a -> Snowflake b
coerceSnowflake (Snowflake t :: Word64
t) = Word64 -> Snowflake b
forall k (t :: k). Word64 -> Snowflake t
Snowflake Word64
t

-- | A typeclass for types that contain snowflakes of type `b`
class HasID b a where

  -- | Retrieve the ID from the type
  getID :: a -> Snowflake b

type HasID' a = HasID a a

-- | A newtype wrapper for deriving HasID generically
newtype HasIDField field a = HasIDField a

instance (HasID b c, HasField' field a c) => HasID b (HasIDField field a) where
  getID :: HasIDField field a -> Snowflake b
getID (HasIDField a :: a
a) = c -> Snowflake b
forall k (b :: k) a. HasID b a => a -> Snowflake b
getID (c -> Snowflake b) -> c -> Snowflake b
forall a b. (a -> b) -> a -> b
$ a
a a -> Getting c a c -> c
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' field s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @field

-- | A data `a` which contains an ID of type `Snowflake c`
--   which should be swapped with `Snowflake b` upon fetching
newtype HasIDFieldCoerce field a c = HasIDFieldCoerce a

type HasIDFieldCoerce' field a = HasIDFieldCoerce field a a

instance (HasID c d, HasField' field a d) => HasID b (HasIDFieldCoerce field a c) where
  getID :: HasIDFieldCoerce field a c -> Snowflake b
getID (HasIDFieldCoerce a :: a
a) = Snowflake c -> Snowflake b
forall k k (a :: k) (b :: k). Snowflake a -> Snowflake b
coerceSnowflake (Snowflake c -> Snowflake b)
-> (d -> Snowflake c) -> d -> Snowflake b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. HasID c a => a -> Snowflake c
forall k (b :: k) a. HasID b a => a -> Snowflake b
getID @c (d -> Snowflake b) -> d -> Snowflake b
forall a b. (a -> b) -> a -> b
$ a
a a -> Getting d a d -> d
forall s a. s -> Getting a s a -> a
^. forall s a. HasField' field s a => Lens s s a a
forall (field :: Symbol) s a. HasField' field s a => Lens s s a a
field' @field

instance HasID a (Snowflake a) where
  getID :: Snowflake a -> Snowflake a
getID = Snowflake a -> Snowflake a
forall a. a -> a
id

newtype instance U.MVector s (Snowflake t) = MV_Snowflake (U.MVector s Word64)

newtype instance U.Vector (Snowflake t) = V_Snowflake (U.Vector Word64)

instance MV.MVector U.MVector (Snowflake t) where
  {-# INLINE basicLength #-}
  {-# INLINE basicUnsafeSlice #-}
  {-# INLINE basicOverlaps #-}
  {-# INLINE basicUnsafeNew #-}
  {-# INLINE basicInitialize #-}
  {-# INLINE basicUnsafeReplicate #-}
  {-# INLINE basicUnsafeRead #-}
  {-# INLINE basicUnsafeWrite #-}
  {-# INLINE basicClear #-}
  {-# INLINE basicSet #-}
  {-# INLINE basicUnsafeCopy #-}
  {-# INLINE basicUnsafeGrow #-}
  basicLength :: MVector s (Snowflake t) -> Int
basicLength (MV_Snowflake v) = MVector s Word64 -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
MV.basicLength MVector s Word64
v

  basicUnsafeSlice :: Int -> Int -> MVector s (Snowflake t) -> MVector s (Snowflake t)
basicUnsafeSlice i :: Int
i n :: Int
n (MV_Snowflake v) = MVector s Word64 -> MVector s (Snowflake t)
forall k s (t :: k). MVector s Word64 -> MVector s (Snowflake t)
MV_Snowflake (MVector s Word64 -> MVector s (Snowflake t))
-> MVector s Word64 -> MVector s (Snowflake t)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> MVector s Word64 -> MVector s Word64
forall (v :: * -> * -> *) a s.
MVector v a =>
Int -> Int -> v s a -> v s a
MV.basicUnsafeSlice Int
i Int
n MVector s Word64
v

  basicOverlaps :: MVector s (Snowflake t) -> MVector s (Snowflake t) -> Bool
basicOverlaps (MV_Snowflake v1) (MV_Snowflake v2) = MVector s Word64 -> MVector s Word64 -> Bool
forall (v :: * -> * -> *) a s.
MVector v a =>
v s a -> v s a -> Bool
MV.basicOverlaps MVector s Word64
v1 MVector s Word64
v2

  basicUnsafeNew :: Int -> m (MVector (PrimState m) (Snowflake t))
basicUnsafeNew n :: Int
n = MVector (PrimState m) Word64 -> MVector (PrimState m) (Snowflake t)
forall k s (t :: k). MVector s Word64 -> MVector s (Snowflake t)
MV_Snowflake (MVector (PrimState m) Word64
 -> MVector (PrimState m) (Snowflake t))
-> m (MVector (PrimState m) Word64)
-> m (MVector (PrimState m) (Snowflake t))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Int -> m (MVector (PrimState m) Word64)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
Int -> m (v (PrimState m) a)
MV.basicUnsafeNew Int
n

  basicInitialize :: MVector (PrimState m) (Snowflake t) -> m ()
basicInitialize (MV_Snowflake v) = MVector (PrimState m) Word64 -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
MV.basicInitialize MVector (PrimState m) Word64
v

  basicUnsafeReplicate :: Int -> Snowflake t -> m (MVector (PrimState m) (Snowflake t))
basicUnsafeReplicate n :: Int
n x :: Snowflake t
x = MVector (PrimState m) Word64 -> MVector (PrimState m) (Snowflake t)
forall k s (t :: k). MVector s Word64 -> MVector s (Snowflake t)
MV_Snowflake (MVector (PrimState m) Word64
 -> MVector (PrimState m) (Snowflake t))
-> m (MVector (PrimState m) Word64)
-> m (MVector (PrimState m) (Snowflake t))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Int -> Word64 -> m (MVector (PrimState m) Word64)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
Int -> a -> m (v (PrimState m) a)
MV.basicUnsafeReplicate Int
n (Snowflake t -> Word64
forall k (t :: k). Snowflake t -> Word64
fromSnowflake Snowflake t
x)

  basicUnsafeRead :: MVector (PrimState m) (Snowflake t) -> Int -> m (Snowflake t)
basicUnsafeRead (MV_Snowflake v) i :: Int
i = Word64 -> Snowflake t
forall k (t :: k). Word64 -> Snowflake t
Snowflake (Word64 -> Snowflake t) -> m Word64 -> m (Snowflake t)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` MVector (PrimState m) Word64 -> Int -> m Word64
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> m a
MV.basicUnsafeRead MVector (PrimState m) Word64
v Int
i

  basicUnsafeWrite :: MVector (PrimState m) (Snowflake t) -> Int -> Snowflake t -> m ()
basicUnsafeWrite (MV_Snowflake v) i :: Int
i x :: Snowflake t
x = MVector (PrimState m) Word64 -> Int -> Word64 -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> a -> m ()
MV.basicUnsafeWrite MVector (PrimState m) Word64
v Int
i (Snowflake t -> Word64
forall k (t :: k). Snowflake t -> Word64
fromSnowflake Snowflake t
x)

  basicClear :: MVector (PrimState m) (Snowflake t) -> m ()
basicClear (MV_Snowflake v) = MVector (PrimState m) Word64 -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> m ()
MV.basicClear MVector (PrimState m) Word64
v

  basicSet :: MVector (PrimState m) (Snowflake t) -> Snowflake t -> m ()
basicSet (MV_Snowflake v) x :: Snowflake t
x = MVector (PrimState m) Word64 -> Word64 -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> a -> m ()
MV.basicSet MVector (PrimState m) Word64
v (Snowflake t -> Word64
forall k (t :: k). Snowflake t -> Word64
fromSnowflake Snowflake t
x)

  basicUnsafeCopy :: MVector (PrimState m) (Snowflake t)
-> MVector (PrimState m) (Snowflake t) -> m ()
basicUnsafeCopy (MV_Snowflake v1) (MV_Snowflake v2) = MVector (PrimState m) Word64
-> MVector (PrimState m) Word64 -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
MV.basicUnsafeCopy MVector (PrimState m) Word64
v1 MVector (PrimState m) Word64
v2

  basicUnsafeMove :: MVector (PrimState m) (Snowflake t)
-> MVector (PrimState m) (Snowflake t) -> m ()
basicUnsafeMove (MV_Snowflake v1) (MV_Snowflake v2) = MVector (PrimState m) Word64
-> MVector (PrimState m) Word64 -> m ()
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> v (PrimState m) a -> m ()
MV.basicUnsafeMove MVector (PrimState m) Word64
v1 MVector (PrimState m) Word64
v2

  basicUnsafeGrow :: MVector (PrimState m) (Snowflake t)
-> Int -> m (MVector (PrimState m) (Snowflake t))
basicUnsafeGrow (MV_Snowflake v) n :: Int
n = MVector (PrimState m) Word64 -> MVector (PrimState m) (Snowflake t)
forall k s (t :: k). MVector s Word64 -> MVector s (Snowflake t)
MV_Snowflake (MVector (PrimState m) Word64
 -> MVector (PrimState m) (Snowflake t))
-> m (MVector (PrimState m) Word64)
-> m (MVector (PrimState m) (Snowflake t))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` MVector (PrimState m) Word64
-> Int -> m (MVector (PrimState m) Word64)
forall (v :: * -> * -> *) a (m :: * -> *).
(MVector v a, PrimMonad m) =>
v (PrimState m) a -> Int -> m (v (PrimState m) a)
MV.basicUnsafeGrow MVector (PrimState m) Word64
v Int
n

instance V.Vector U.Vector (Snowflake t) where
  {-# INLINE basicUnsafeFreeze #-}
  {-# INLINE basicUnsafeThaw #-}
  {-# INLINE basicLength #-}
  {-# INLINE basicUnsafeSlice #-}
  {-# INLINE basicUnsafeIndexM #-}
  {-# INLINE elemseq #-}
  basicUnsafeFreeze :: Mutable Vector (PrimState m) (Snowflake t)
-> m (Vector (Snowflake t))
basicUnsafeFreeze (MV_Snowflake v) = Vector Word64 -> Vector (Snowflake t)
forall k (t :: k). Vector Word64 -> Vector (Snowflake t)
V_Snowflake (Vector Word64 -> Vector (Snowflake t))
-> m (Vector Word64) -> m (Vector (Snowflake t))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Mutable Vector (PrimState m) Word64 -> m (Vector Word64)
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
Mutable v (PrimState m) a -> m (v a)
V.basicUnsafeFreeze MVector (PrimState m) Word64
Mutable Vector (PrimState m) Word64
v

  basicUnsafeThaw :: Vector (Snowflake t)
-> m (Mutable Vector (PrimState m) (Snowflake t))
basicUnsafeThaw (V_Snowflake v) = MVector (PrimState m) Word64 -> MVector (PrimState m) (Snowflake t)
forall k s (t :: k). MVector s Word64 -> MVector s (Snowflake t)
MV_Snowflake (MVector (PrimState m) Word64
 -> MVector (PrimState m) (Snowflake t))
-> m (MVector (PrimState m) Word64)
-> m (MVector (PrimState m) (Snowflake t))
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Vector Word64 -> m (Mutable Vector (PrimState m) Word64)
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
v a -> m (Mutable v (PrimState m) a)
V.basicUnsafeThaw Vector Word64
v

  basicLength :: Vector (Snowflake t) -> Int
basicLength (V_Snowflake v) = Vector Word64 -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
V.basicLength Vector Word64
v

  basicUnsafeSlice :: Int -> Int -> Vector (Snowflake t) -> Vector (Snowflake t)
basicUnsafeSlice i :: Int
i n :: Int
n (V_Snowflake v) = Vector Word64 -> Vector (Snowflake t)
forall k (t :: k). Vector Word64 -> Vector (Snowflake t)
V_Snowflake (Vector Word64 -> Vector (Snowflake t))
-> Vector Word64 -> Vector (Snowflake t)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Vector Word64 -> Vector Word64
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
V.basicUnsafeSlice Int
i Int
n Vector Word64
v

  basicUnsafeIndexM :: Vector (Snowflake t) -> Int -> m (Snowflake t)
basicUnsafeIndexM (V_Snowflake v) i :: Int
i = Word64 -> Snowflake t
forall k (t :: k). Word64 -> Snowflake t
Snowflake (Word64 -> Snowflake t) -> m Word64 -> m (Snowflake t)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Vector Word64 -> Int -> m Word64
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
V.basicUnsafeIndexM Vector Word64
v Int
i

  basicUnsafeCopy :: Mutable Vector (PrimState m) (Snowflake t)
-> Vector (Snowflake t) -> m ()
basicUnsafeCopy (MV_Snowflake mv) (V_Snowflake v) = Mutable Vector (PrimState m) Word64 -> Vector Word64 -> m ()
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, PrimMonad m) =>
Mutable v (PrimState m) a -> v a -> m ()
V.basicUnsafeCopy MVector (PrimState m) Word64
Mutable Vector (PrimState m) Word64
mv Vector Word64
v

  elemseq :: Vector (Snowflake t) -> Snowflake t -> b -> b
elemseq _ = Snowflake t -> b -> b
forall a b. a -> b -> b
seq

instance U.Unbox (Snowflake t)