{-# LANGUAGE DeriveDataTypeable #-}

-- | Data structures pertaining to Discord Colors
module Discord.Internal.Types.Color where


import Text.Read (readMaybe)
import Data.Maybe (fromMaybe)
import Data.Char (toLower)
import Data.Aeson
import Data.Data
import Control.Applicative (Alternative((<|>)))
import Data.Bits (Bits((.&.)))


import Discord.Internal.Types.Prelude (InternalDiscordEnum(..))

-- | Color names
-- Color is a bit of a mess on discord embeds.
-- I've here stolen the pallet list from https://gist.github.com/thomasbnt/b6f455e2c7d743b796917fa3c205f812
--
-- All discord embed color stuff is credited to
-- https://github.com/WarwickTabletop/tablebot/pull/34
data DiscordColor
  = DiscordColorRGB Integer Integer Integer
  | DiscordColorDefault
  | DiscordColorAqua
  | DiscordColorDarkAqua
  | DiscordColorGreen
  | DiscordColorDarkGreen
  | DiscordColorBlue
  | DiscordColorDarkBlue
  | DiscordColorPurple
  | DiscordColorDarkPurple
  | DiscordColorLuminousVividPink
  | DiscordColorDarkVividPink
  | DiscordColorGold
  | DiscordColorDarkGold
  | DiscordColorOrange
  | DiscordColorDarkOrange
  | DiscordColorRed
  | DiscordColorDarkRed
  | DiscordColorGray
  | DiscordColorDarkGray
  | DiscordColorDarkerGray
  | DiscordColorLightGray
  | DiscordColorNavy
  | DiscordColorDarkNavy
  | DiscordColorYellow
  | DiscordColorDiscordWhite
  | DiscordColorDiscordBlurple
  | DiscordColorDiscordGrayple
  | DiscordColorDiscordDarkButNotBlack
  | DiscordColorDiscordNotQuiteBlack
  | DiscordColorDiscordGreen
  | DiscordColorDiscordYellow
  | DiscordColorDiscordFuschia
  | DiscordColorDiscordRed
  | DiscordColorDiscordBlack
  deriving (Int -> DiscordColor -> ShowS
[DiscordColor] -> ShowS
DiscordColor -> String
(Int -> DiscordColor -> ShowS)
-> (DiscordColor -> String)
-> ([DiscordColor] -> ShowS)
-> Show DiscordColor
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DiscordColor] -> ShowS
$cshowList :: [DiscordColor] -> ShowS
show :: DiscordColor -> String
$cshow :: DiscordColor -> String
showsPrec :: Int -> DiscordColor -> ShowS
$cshowsPrec :: Int -> DiscordColor -> ShowS
Show, ReadPrec [DiscordColor]
ReadPrec DiscordColor
Int -> ReadS DiscordColor
ReadS [DiscordColor]
(Int -> ReadS DiscordColor)
-> ReadS [DiscordColor]
-> ReadPrec DiscordColor
-> ReadPrec [DiscordColor]
-> Read DiscordColor
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DiscordColor]
$creadListPrec :: ReadPrec [DiscordColor]
readPrec :: ReadPrec DiscordColor
$creadPrec :: ReadPrec DiscordColor
readList :: ReadS [DiscordColor]
$creadList :: ReadS [DiscordColor]
readsPrec :: Int -> ReadS DiscordColor
$creadsPrec :: Int -> ReadS DiscordColor
Read, DiscordColor -> DiscordColor -> Bool
(DiscordColor -> DiscordColor -> Bool)
-> (DiscordColor -> DiscordColor -> Bool) -> Eq DiscordColor
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DiscordColor -> DiscordColor -> Bool
$c/= :: DiscordColor -> DiscordColor -> Bool
== :: DiscordColor -> DiscordColor -> Bool
$c== :: DiscordColor -> DiscordColor -> Bool
Eq, Eq DiscordColor
Eq DiscordColor
-> (DiscordColor -> DiscordColor -> Ordering)
-> (DiscordColor -> DiscordColor -> Bool)
-> (DiscordColor -> DiscordColor -> Bool)
-> (DiscordColor -> DiscordColor -> Bool)
-> (DiscordColor -> DiscordColor -> Bool)
-> (DiscordColor -> DiscordColor -> DiscordColor)
-> (DiscordColor -> DiscordColor -> DiscordColor)
-> Ord DiscordColor
DiscordColor -> DiscordColor -> Bool
DiscordColor -> DiscordColor -> Ordering
DiscordColor -> DiscordColor -> DiscordColor
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 :: DiscordColor -> DiscordColor -> DiscordColor
$cmin :: DiscordColor -> DiscordColor -> DiscordColor
max :: DiscordColor -> DiscordColor -> DiscordColor
$cmax :: DiscordColor -> DiscordColor -> DiscordColor
>= :: DiscordColor -> DiscordColor -> Bool
$c>= :: DiscordColor -> DiscordColor -> Bool
> :: DiscordColor -> DiscordColor -> Bool
$c> :: DiscordColor -> DiscordColor -> Bool
<= :: DiscordColor -> DiscordColor -> Bool
$c<= :: DiscordColor -> DiscordColor -> Bool
< :: DiscordColor -> DiscordColor -> Bool
$c< :: DiscordColor -> DiscordColor -> Bool
compare :: DiscordColor -> DiscordColor -> Ordering
$ccompare :: DiscordColor -> DiscordColor -> Ordering
$cp1Ord :: Eq DiscordColor
Ord, Typeable DiscordColor
DataType
Constr
Typeable DiscordColor
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> DiscordColor -> c DiscordColor)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c DiscordColor)
-> (DiscordColor -> Constr)
-> (DiscordColor -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c DiscordColor))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c DiscordColor))
-> ((forall b. Data b => b -> b) -> DiscordColor -> DiscordColor)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscordColor -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> DiscordColor -> r)
-> (forall u. (forall d. Data d => d -> u) -> DiscordColor -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> DiscordColor -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor)
-> Data DiscordColor
DiscordColor -> DataType
DiscordColor -> Constr
(forall b. Data b => b -> b) -> DiscordColor -> DiscordColor
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DiscordColor -> c DiscordColor
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DiscordColor
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) -> DiscordColor -> u
forall u. (forall d. Data d => d -> u) -> DiscordColor -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DiscordColor -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DiscordColor -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DiscordColor
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DiscordColor -> c DiscordColor
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DiscordColor)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DiscordColor)
$cDiscordColorDiscordBlack :: Constr
$cDiscordColorDiscordRed :: Constr
$cDiscordColorDiscordFuschia :: Constr
$cDiscordColorDiscordYellow :: Constr
$cDiscordColorDiscordGreen :: Constr
$cDiscordColorDiscordNotQuiteBlack :: Constr
$cDiscordColorDiscordDarkButNotBlack :: Constr
$cDiscordColorDiscordGrayple :: Constr
$cDiscordColorDiscordBlurple :: Constr
$cDiscordColorDiscordWhite :: Constr
$cDiscordColorYellow :: Constr
$cDiscordColorDarkNavy :: Constr
$cDiscordColorNavy :: Constr
$cDiscordColorLightGray :: Constr
$cDiscordColorDarkerGray :: Constr
$cDiscordColorDarkGray :: Constr
$cDiscordColorGray :: Constr
$cDiscordColorDarkRed :: Constr
$cDiscordColorRed :: Constr
$cDiscordColorDarkOrange :: Constr
$cDiscordColorOrange :: Constr
$cDiscordColorDarkGold :: Constr
$cDiscordColorGold :: Constr
$cDiscordColorDarkVividPink :: Constr
$cDiscordColorLuminousVividPink :: Constr
$cDiscordColorDarkPurple :: Constr
$cDiscordColorPurple :: Constr
$cDiscordColorDarkBlue :: Constr
$cDiscordColorBlue :: Constr
$cDiscordColorDarkGreen :: Constr
$cDiscordColorGreen :: Constr
$cDiscordColorDarkAqua :: Constr
$cDiscordColorAqua :: Constr
$cDiscordColorDefault :: Constr
$cDiscordColorRGB :: Constr
$tDiscordColor :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
gmapMp :: (forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
gmapM :: (forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> DiscordColor -> m DiscordColor
gmapQi :: Int -> (forall d. Data d => d -> u) -> DiscordColor -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> DiscordColor -> u
gmapQ :: (forall d. Data d => d -> u) -> DiscordColor -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> DiscordColor -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DiscordColor -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> DiscordColor -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DiscordColor -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> DiscordColor -> r
gmapT :: (forall b. Data b => b -> b) -> DiscordColor -> DiscordColor
$cgmapT :: (forall b. Data b => b -> b) -> DiscordColor -> DiscordColor
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DiscordColor)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c DiscordColor)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c DiscordColor)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c DiscordColor)
dataTypeOf :: DiscordColor -> DataType
$cdataTypeOf :: DiscordColor -> DataType
toConstr :: DiscordColor -> Constr
$ctoConstr :: DiscordColor -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DiscordColor
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c DiscordColor
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DiscordColor -> c DiscordColor
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> DiscordColor -> c DiscordColor
$cp1Data :: Typeable DiscordColor
Data)

-- | @hexToRGB@ attempts to convert a potential hex string into its decimal RGB
-- components.
hexToRGB :: String -> Maybe (Integer, Integer, Integer)
hexToRGB :: String -> Maybe (Integer, Integer, Integer)
hexToRGB String
hex = do
  let h :: String
h = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
hex
  Integer
r <- String -> Maybe String
forall a. [a] -> Maybe [a]
take2 String
h Maybe String -> (String -> Maybe Integer) -> Maybe Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe Integer
toDec
  Integer
g <- String -> Maybe String
forall a. [a] -> Maybe [a]
drop2 String
h Maybe String -> (String -> Maybe String) -> Maybe String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe String
forall a. [a] -> Maybe [a]
take2 Maybe String -> (String -> Maybe Integer) -> Maybe Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe Integer
toDec
  Integer
b <- String -> Maybe String
forall a. [a] -> Maybe [a]
drop2 String
h Maybe String -> (String -> Maybe String) -> Maybe String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe String
forall a. [a] -> Maybe [a]
drop2 Maybe String -> (String -> Maybe Integer) -> Maybe Integer
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe Integer
toDec
  (Integer, Integer, Integer) -> Maybe (Integer, Integer, Integer)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer
r, Integer
g, Integer
b)
  where
    take2 :: [a] -> Maybe [a]
take2 (a
a:a
b:[a]
_) = [a] -> Maybe [a]
forall a. a -> Maybe a
Just [a
a, a
b]
    take2 [a]
_ = Maybe [a]
forall a. Maybe a
Nothing
    drop2 :: [a] -> Maybe [a]
drop2 (a
_ : a
_ : [a]
as) = [a] -> Maybe [a]
forall a. a -> Maybe a
Just [a]
as
    drop2 [a]
_ = Maybe [a]
forall a. Maybe a
Nothing
    toDec :: String -> Maybe Integer
    toDec :: String -> Maybe Integer
toDec [Char
s, Char
u] = do
      Integer
a <- Char -> Maybe Integer
charToDec Char
s
      Integer
b <- Char -> Maybe Integer
charToDec Char
u
      Integer -> Maybe Integer
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
16 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b
    toDec String
_ = Maybe Integer
forall a. Maybe a
Nothing
    charToDec :: Char -> Maybe Integer
    charToDec :: Char -> Maybe Integer
charToDec Char
'a' = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
10
    charToDec Char
'b' = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
11
    charToDec Char
'c' = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
12
    charToDec Char
'd' = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
13
    charToDec Char
'e' = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
14
    charToDec Char
'f' = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
15
    charToDec Char
c = String -> Maybe Integer
forall a. Read a => String -> Maybe a
readMaybe [Char
c]

-- | @hexToDiscordColor@ converts a potential hex string into a DiscordColor,
-- evaluating to Default if it fails.
hexToDiscordColor :: String -> DiscordColor
hexToDiscordColor :: String -> DiscordColor
hexToDiscordColor String
hex =
  let (Integer
r, Integer
g, Integer
b) = (Integer, Integer, Integer)
-> Maybe (Integer, Integer, Integer) -> (Integer, Integer, Integer)
forall a. a -> Maybe a -> a
fromMaybe (Integer
0, Integer
0, Integer
0) (Maybe (Integer, Integer, Integer) -> (Integer, Integer, Integer))
-> Maybe (Integer, Integer, Integer) -> (Integer, Integer, Integer)
forall a b. (a -> b) -> a -> b
$ String -> Maybe (Integer, Integer, Integer)
hexToRGB String
hex
   in Integer -> Integer -> Integer -> DiscordColor
DiscordColorRGB Integer
r Integer
g Integer
b

colorToInternal :: DiscordColor -> Integer
-- colorToInternal (DiscordColor i) = i
colorToInternal :: DiscordColor -> Integer
colorToInternal (DiscordColorRGB Integer
r Integer
g Integer
b) = (Integer
r Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
g) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b
colorToInternal DiscordColor
DiscordColorDefault = Integer
0
colorToInternal DiscordColor
DiscordColorAqua = Integer
1752220
colorToInternal DiscordColor
DiscordColorDarkAqua = Integer
1146986
colorToInternal DiscordColor
DiscordColorGreen = Integer
3066993
colorToInternal DiscordColor
DiscordColorDarkGreen = Integer
2067276
colorToInternal DiscordColor
DiscordColorBlue = Integer
3447003
colorToInternal DiscordColor
DiscordColorDarkBlue = Integer
2123412
colorToInternal DiscordColor
DiscordColorPurple = Integer
10181046
colorToInternal DiscordColor
DiscordColorDarkPurple = Integer
7419530
colorToInternal DiscordColor
DiscordColorLuminousVividPink = Integer
15277667
colorToInternal DiscordColor
DiscordColorDarkVividPink = Integer
11342935
colorToInternal DiscordColor
DiscordColorGold = Integer
15844367
colorToInternal DiscordColor
DiscordColorDarkGold = Integer
12745742
colorToInternal DiscordColor
DiscordColorOrange = Integer
15105570
colorToInternal DiscordColor
DiscordColorDarkOrange = Integer
11027200
colorToInternal DiscordColor
DiscordColorRed = Integer
15158332
colorToInternal DiscordColor
DiscordColorDarkRed = Integer
10038562
colorToInternal DiscordColor
DiscordColorGray = Integer
9807270
colorToInternal DiscordColor
DiscordColorDarkGray = Integer
9936031
colorToInternal DiscordColor
DiscordColorDarkerGray = Integer
8359053
colorToInternal DiscordColor
DiscordColorLightGray = Integer
12370112
colorToInternal DiscordColor
DiscordColorNavy = Integer
3426654
colorToInternal DiscordColor
DiscordColorDarkNavy = Integer
2899536
colorToInternal DiscordColor
DiscordColorYellow = Integer
16776960
colorToInternal DiscordColor
DiscordColorDiscordWhite = Integer
16777215
colorToInternal DiscordColor
DiscordColorDiscordBlurple = Integer
5793266
colorToInternal DiscordColor
DiscordColorDiscordGrayple = Integer
10070709
colorToInternal DiscordColor
DiscordColorDiscordDarkButNotBlack = Integer
2895667
colorToInternal DiscordColor
DiscordColorDiscordNotQuiteBlack = Integer
2303786
colorToInternal DiscordColor
DiscordColorDiscordGreen = Integer
5763719
colorToInternal DiscordColor
DiscordColorDiscordYellow = Integer
16705372
colorToInternal DiscordColor
DiscordColorDiscordFuschia = Integer
15418782
colorToInternal DiscordColor
DiscordColorDiscordRed = Integer
15548997
colorToInternal DiscordColor
DiscordColorDiscordBlack = Integer
16777215

convertToRGB :: Integer -> DiscordColor
convertToRGB :: Integer -> DiscordColor
convertToRGB Integer
i = Integer -> Integer -> Integer -> DiscordColor
DiscordColorRGB (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div Integer
i (Integer
256 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
256) Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
255) (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div Integer
i Integer
256 Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
255) (Integer
i Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
255)

instance InternalDiscordEnum DiscordColor where
  discordTypeStartValue :: DiscordColor
discordTypeStartValue = DiscordColor
DiscordColorDefault
  fromDiscordType :: DiscordColor -> Int
fromDiscordType = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int)
-> (DiscordColor -> Integer) -> DiscordColor -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiscordColor -> Integer
colorToInternal
  discordTypeTable :: [(Int, DiscordColor)]
discordTypeTable = (DiscordColor -> (Int, DiscordColor))
-> [DiscordColor] -> [(Int, DiscordColor)]
forall a b. (a -> b) -> [a] -> [b]
map (\DiscordColor
d -> (DiscordColor -> Int
forall a. InternalDiscordEnum a => a -> Int
fromDiscordType DiscordColor
d, DiscordColor
d)) (DiscordColor -> [DiscordColor]
forall b. Data b => b -> [b]
makeTable DiscordColor
forall a. InternalDiscordEnum a => a
discordTypeStartValue)
    where
      makeTable :: Data b => b -> [b]
      makeTable :: b -> [b]
makeTable b
t = (Constr -> b) -> [Constr] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map ((forall d. Data d => d) -> Constr -> b
forall a. Data a => (forall d. Data d => d) -> Constr -> a
fromConstrB (Constr -> d
forall a. Data a => Constr -> a
fromConstr (Int -> Constr
forall a. Data a => a -> Constr
toConstr (Int
0 :: Int)))) (DataType -> [Constr]
dataTypeConstrs (DataType -> [Constr]) -> DataType -> [Constr]
forall a b. (a -> b) -> a -> b
$ b -> DataType
forall a. Data a => a -> DataType
dataTypeOf b
t)

instance ToJSON DiscordColor where
  toJSON :: DiscordColor -> Value
toJSON = Int -> Value
forall a. ToJSON a => a -> Value
toJSON (Int -> Value) -> (DiscordColor -> Int) -> DiscordColor -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiscordColor -> Int
forall a. InternalDiscordEnum a => a -> Int
fromDiscordType

instance FromJSON DiscordColor where
  parseJSON :: Value -> Parser DiscordColor
parseJSON =
    String
-> (Scientific -> Parser DiscordColor)
-> Value
-> Parser DiscordColor
forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific
      String
"DiscordColor"
      ( \Scientific
v ->
          String -> Value -> Parser DiscordColor
forall a. InternalDiscordEnum a => String -> Value -> Parser a
discordTypeParseJSON String
"DiscordColor" (Scientific -> Value
Number Scientific
v)
            Parser DiscordColor -> Parser DiscordColor -> Parser DiscordColor
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ( case Scientific -> Maybe Integer
forall a a. (RealFrac a, Integral a) => a -> Maybe a
maybeInt Scientific
v Maybe Integer
-> (Integer -> Maybe DiscordColor) -> Maybe DiscordColor
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DiscordColor -> Maybe DiscordColor
forall a. a -> Maybe a
Just (DiscordColor -> Maybe DiscordColor)
-> (Integer -> DiscordColor) -> Integer -> Maybe DiscordColor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> DiscordColor
convertToRGB of
                    Maybe DiscordColor
Nothing -> String -> Parser DiscordColor
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser DiscordColor) -> String -> Parser DiscordColor
forall a b. (a -> b) -> a -> b
$ String
"could not parse discord color: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Scientific -> String
forall a. Show a => a -> String
show Scientific
v
                    Just DiscordColor
d -> DiscordColor -> Parser DiscordColor
forall (m :: * -> *) a. Monad m => a -> m a
return DiscordColor
d
                )
      )
    where
      maybeInt :: a -> Maybe a
maybeInt a
i
        | Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round a
i) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
i = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a b. (RealFrac a, Integral b) => a -> b
round a
i
        | Bool
otherwise = Maybe a
forall a. Maybe a
Nothing