{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- Module      : Data.Char.Emoji.SkinColor
-- Description : A module that defines emoji that display a clock.
-- Maintainer  : hapytexeu+gh@gmail.com
-- Stability   : experimental
-- Portability : POSIX
--
-- For several emoji, one can specify the color of the skin of the person(s)
-- of the emoji. This module defines the skin color modifiers together with
-- its values on the Fitzpatrick scale.
module Data.Char.Emoji.SkinColor
  ( -- * Skin color modifier
    SkinColorModifier (Light, MediumLight, Medium, MediumDark, Dark),
    OptionalSkinColorModifier,
    fromFitzpatrick,
    isSkinColorModifier,

    -- * Create emoji with a 'SkinColorModifier'
    WithSkinColorModifierUnicodeText (withSkinModifier, withOptionalSkinModifier, withoutOptionalSkinModifier),
    withSkinModifier',
    withOptionalSkinModifier',
    withoutOptionalSkinModifier',

    -- * Pattern synonyms for the 'SkinColorModifier' elements
    pattern FitzpatrickI,
    pattern FitzpatrickII,
    pattern FitzpatrickIII,
    pattern FitzpatrickIV,
    pattern FitzpatrickV,
    pattern FitzpatrickVI,
  )
where

import Control.DeepSeq (NFData)
import Data.Char (ord)
import Data.Char.Core (UnicodeCharacter (fromUnicodeChar, fromUnicodeChar', isInCharRange, toUnicodeChar), UnicodeText (fromUnicodeText, isInTextRange, toUnicodeText), generateIsInTextRange', mapFromEnum, mapToEnum, mapToEnumSafe)
import Data.Data (Data)
import Data.Functor.Classes (Eq1 (liftEq))
import Data.Hashable (Hashable)
import Data.Hashable.Lifted (Hashable1)
import Data.Text (Text, snoc, unsnoc)
import GHC.Generics (Generic, Generic1)
import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary), Arbitrary1 (liftArbitrary), arbitrary1, arbitraryBoundedEnum)

_skinColorOffset :: Int
_skinColorOffset :: Int
_skinColorOffset = Int
0x1f3fb

_skinColorLimit :: Int
_skinColorLimit :: Int
_skinColorLimit = Int
0x1f3ff

-- | Check if the given 'Char'acter is a skin color modifier.
isSkinColorModifier ::
  -- | The given 'Char'acter to check.
  Char ->
  -- | 'True' if the given 'Char'acter is a skin color modifier, 'False' otherwise.
  Bool
isSkinColorModifier :: Char -> Bool
isSkinColorModifier Char
c = Int
_skinColorOffset forall a. Ord a => a -> a -> Bool
<= Int
oc Bool -> Bool -> Bool
&& Int
oc forall a. Ord a => a -> a -> Bool
<= Int
_skinColorLimit
  where
    oc :: Int
oc = Char -> Int
ord Char
c

-- | Some emoji deal with people. One can change the color of the skin with the
-- 'SkinColorModifier'. For the skin color, the <https://en.wikipedia.org/wiki/Fitzpatrick_scale /Fitzpatrick scale/> is used.
-- A numerical classification system for skin types.
data SkinColorModifier
  = -- | An emoji /modifier/ that applies /Fitzpatrick skin type/ one or two to the Emoji.
    Light
  | -- | An emoji /modifier/ that applies /Fitzpatrick skin type/ three to the Emoji.
    MediumLight
  | -- | An emoji /modifier/ that applies /Fitzpatrick skin type/ four to the Emoji.
    Medium
  | -- | An emoji /modifier/ that applies /Fitzpatrick skin type/ five to the Emoji.
    MediumDark
  | -- | An emoji /modifier/ that applies /Fitzpatrick skin type/ six to the Emoji.
    Dark
  deriving (SkinColorModifier
forall a. a -> a -> Bounded a
maxBound :: SkinColorModifier
$cmaxBound :: SkinColorModifier
minBound :: SkinColorModifier
$cminBound :: SkinColorModifier
Bounded, Typeable SkinColorModifier
SkinColorModifier -> DataType
SkinColorModifier -> Constr
(forall b. Data b => b -> b)
-> SkinColorModifier -> SkinColorModifier
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) -> SkinColorModifier -> u
forall u. (forall d. Data d => d -> u) -> SkinColorModifier -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SkinColorModifier -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SkinColorModifier -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SkinColorModifier
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinColorModifier -> c SkinColorModifier
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SkinColorModifier)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SkinColorModifier)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SkinColorModifier -> m SkinColorModifier
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> SkinColorModifier -> u
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> SkinColorModifier -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> SkinColorModifier -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SkinColorModifier -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SkinColorModifier -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SkinColorModifier -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SkinColorModifier -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SkinColorModifier -> r
gmapT :: (forall b. Data b => b -> b)
-> SkinColorModifier -> SkinColorModifier
$cgmapT :: (forall b. Data b => b -> b)
-> SkinColorModifier -> SkinColorModifier
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SkinColorModifier)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SkinColorModifier)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SkinColorModifier)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SkinColorModifier)
dataTypeOf :: SkinColorModifier -> DataType
$cdataTypeOf :: SkinColorModifier -> DataType
toConstr :: SkinColorModifier -> Constr
$ctoConstr :: SkinColorModifier -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SkinColorModifier
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SkinColorModifier
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinColorModifier -> c SkinColorModifier
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinColorModifier -> c SkinColorModifier
Data, Int -> SkinColorModifier
SkinColorModifier -> Int
SkinColorModifier -> [SkinColorModifier]
SkinColorModifier -> SkinColorModifier
SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
SkinColorModifier
-> SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: SkinColorModifier
-> SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
$cenumFromThenTo :: SkinColorModifier
-> SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
enumFromTo :: SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
$cenumFromTo :: SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
enumFromThen :: SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
$cenumFromThen :: SkinColorModifier -> SkinColorModifier -> [SkinColorModifier]
enumFrom :: SkinColorModifier -> [SkinColorModifier]
$cenumFrom :: SkinColorModifier -> [SkinColorModifier]
fromEnum :: SkinColorModifier -> Int
$cfromEnum :: SkinColorModifier -> Int
toEnum :: Int -> SkinColorModifier
$ctoEnum :: Int -> SkinColorModifier
pred :: SkinColorModifier -> SkinColorModifier
$cpred :: SkinColorModifier -> SkinColorModifier
succ :: SkinColorModifier -> SkinColorModifier
$csucc :: SkinColorModifier -> SkinColorModifier
Enum, SkinColorModifier -> SkinColorModifier -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SkinColorModifier -> SkinColorModifier -> Bool
$c/= :: SkinColorModifier -> SkinColorModifier -> Bool
== :: SkinColorModifier -> SkinColorModifier -> Bool
$c== :: SkinColorModifier -> SkinColorModifier -> Bool
Eq, forall x. Rep SkinColorModifier x -> SkinColorModifier
forall x. SkinColorModifier -> Rep SkinColorModifier x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SkinColorModifier x -> SkinColorModifier
$cfrom :: forall x. SkinColorModifier -> Rep SkinColorModifier x
Generic, Eq SkinColorModifier
SkinColorModifier -> SkinColorModifier -> Bool
SkinColorModifier -> SkinColorModifier -> Ordering
SkinColorModifier -> SkinColorModifier -> SkinColorModifier
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 :: SkinColorModifier -> SkinColorModifier -> SkinColorModifier
$cmin :: SkinColorModifier -> SkinColorModifier -> SkinColorModifier
max :: SkinColorModifier -> SkinColorModifier -> SkinColorModifier
$cmax :: SkinColorModifier -> SkinColorModifier -> SkinColorModifier
>= :: SkinColorModifier -> SkinColorModifier -> Bool
$c>= :: SkinColorModifier -> SkinColorModifier -> Bool
> :: SkinColorModifier -> SkinColorModifier -> Bool
$c> :: SkinColorModifier -> SkinColorModifier -> Bool
<= :: SkinColorModifier -> SkinColorModifier -> Bool
$c<= :: SkinColorModifier -> SkinColorModifier -> Bool
< :: SkinColorModifier -> SkinColorModifier -> Bool
$c< :: SkinColorModifier -> SkinColorModifier -> Bool
compare :: SkinColorModifier -> SkinColorModifier -> Ordering
$ccompare :: SkinColorModifier -> SkinColorModifier -> Ordering
Ord, ReadPrec [SkinColorModifier]
ReadPrec SkinColorModifier
Int -> ReadS SkinColorModifier
ReadS [SkinColorModifier]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SkinColorModifier]
$creadListPrec :: ReadPrec [SkinColorModifier]
readPrec :: ReadPrec SkinColorModifier
$creadPrec :: ReadPrec SkinColorModifier
readList :: ReadS [SkinColorModifier]
$creadList :: ReadS [SkinColorModifier]
readsPrec :: Int -> ReadS SkinColorModifier
$creadsPrec :: Int -> ReadS SkinColorModifier
Read, Int -> SkinColorModifier -> ShowS
[SkinColorModifier] -> ShowS
SkinColorModifier -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SkinColorModifier] -> ShowS
$cshowList :: [SkinColorModifier] -> ShowS
show :: SkinColorModifier -> String
$cshow :: SkinColorModifier -> String
showsPrec :: Int -> SkinColorModifier -> ShowS
$cshowsPrec :: Int -> SkinColorModifier -> ShowS
Show)

instance Arbitrary SkinColorModifier where
  arbitrary :: Gen SkinColorModifier
arbitrary = forall a. (Bounded a, Enum a) => Gen a
arbitraryBoundedEnum

instance Hashable SkinColorModifier

instance NFData SkinColorModifier

instance UnicodeCharacter SkinColorModifier where
  toUnicodeChar :: SkinColorModifier -> Char
toUnicodeChar = forall a. Enum a => Int -> a -> Char
mapFromEnum Int
_skinColorOffset
  fromUnicodeChar :: Char -> Maybe SkinColorModifier
fromUnicodeChar = forall a. (Bounded a, Enum a) => Int -> Char -> Maybe a
mapToEnumSafe Int
_skinColorOffset
  fromUnicodeChar' :: Char -> SkinColorModifier
fromUnicodeChar' = forall a. Enum a => Int -> Char -> a
mapToEnum Int
_skinColorOffset
  isInCharRange :: Char -> Bool
isInCharRange Char
c = Char
'\x1f3fb' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\x1f3ff'

instance UnicodeText SkinColorModifier where
  isInTextRange :: Text -> Bool
isInTextRange = forall a. UnicodeCharacter a => Text -> Bool
generateIsInTextRange' @SkinColorModifier

-- | Append the given 'Text' object with the Unicode character to modify its skin color.
withSkinModifier' ::
  -- | The given 'Text' object where we want to specify the skin color.
  Text ->
  -- | The given'SkinColorModifier' to apply.
  SkinColorModifier ->
  -- | The given 'Text' object combined with the given 'SkinColorModifier'.
  Text
withSkinModifier' :: Text -> SkinColorModifier -> Text
withSkinModifier' Text
t
  | Just (Text
t', Char
'\xfe0f') <- Text -> Maybe (Text, Char)
unsnoc Text
t = Text -> Char -> Text
snoc Text
t' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. UnicodeCharacter a => a -> Char
toUnicodeChar
  | Bool
otherwise = Text -> Char -> Text
snoc Text
t forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. UnicodeCharacter a => a -> Char
toUnicodeChar

-- | Append the given 'Text' object with the Unicode character to modify its skin color. If 'Nothing', then no modification is applied.
withOptionalSkinModifier' ::
  -- | The given 'Text' object where we want to specify the skin color.
  Text ->
  -- | The given'OptionalSkinColorModifier' to apply.
  OptionalSkinColorModifier ->
  -- | The given 'Text' object combined with the given 'SkinColorModifier'.
  Text
withOptionalSkinModifier' :: Text -> Maybe SkinColorModifier -> Text
withOptionalSkinModifier' Text
t = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
t (Text -> SkinColorModifier -> Text
withSkinModifier' Text
t)

-- | Convert the given 'Text' object to a wrapped 'Text' object with an 'OptionalSkinColorModifier'.
withoutOptionalSkinModifier' ::
  -- | The given 'Text' to decompose.
  Text ->
  -- | A 2-tuple where the first item is the remaining 'Text' and where the second item is an optioanl 'SkinColorModifier'.
  (Text, OptionalSkinColorModifier)
withoutOptionalSkinModifier' :: Text -> (Text, Maybe SkinColorModifier)
withoutOptionalSkinModifier' Text
t
  | Just (Text
t', Char
s) <- Text -> Maybe (Text, Char)
unsnoc Text
t, Char -> Bool
isSkinColorModifier Char
s = (Text
t', forall a. a -> Maybe a
Just (forall a. UnicodeCharacter a => Char -> a
fromUnicodeChar' Char
s))
  | Bool
otherwise = (Text
t, forall a. Maybe a
Nothing)

-- | A typeclass where one can specify that the object can be rendered with a given /skin color modifier/.
class UnicodeText a => WithSkinColorModifierUnicodeText a where
  -- | Apply the given 'SkinColorModifier' to the item and obtain a 'Text' object where the item
  -- has been modified with the 'SkinColorModifier'.
  withSkinModifier ::
    -- | The given item to render to a unicode 'Text' object.
    a ->
    -- | The given skin color modifier to apply.
    SkinColorModifier ->
    -- | The corresponding 'Text' where we applied the given 'SkinColorModifier'.
    Text
  withSkinModifier = Text -> SkinColorModifier -> Text
withSkinModifier' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. UnicodeText a => a -> Text
toUnicodeText

  -- | Apply the given 'SkinColorModifier' to the item given it is not 'Nothing' such that
  -- the object is rendered with the given /skin color modifier/.
  withOptionalSkinModifier ::
    -- | The given item to render to a unicode 'Text' object.
    a ->
    -- | The given optional skin color modifier.
    OptionalSkinColorModifier ->
    -- | The corresponding 'Text' where we applied the given 'SkinColorModifier'.
    Text
  withOptionalSkinModifier = Text -> Maybe SkinColorModifier -> Text
withOptionalSkinModifier' forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. UnicodeText a => a -> Text
toUnicodeText

  -- | Convert the given Text to an item with an 'OptionalSkinColorModifier' that might
  -- have been applied.
  withoutOptionalSkinModifier ::
    -- | The given 'Text' object that should be decoded.
    Text ->
    -- | An optional 2-tuple with the item that has been read, and an optional 'SkinColorModifier'.
    Maybe (a, OptionalSkinColorModifier)
  withoutOptionalSkinModifier Text
t = (,Maybe SkinColorModifier
m) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. UnicodeText a => Text -> Maybe a
fromUnicodeText Text
t'
    where
      ~(Text
t', Maybe SkinColorModifier
m) = Text -> (Text, Maybe SkinColorModifier)
withoutOptionalSkinModifier' Text
t

  {-# MINIMAL #-}

data SkinModified a = SkinModified a SkinColorModifier
  deriving (SkinModified a -> DataType
SkinModified a -> Constr
forall {a}. Data a => Typeable (SkinModified a)
forall a. Data a => SkinModified a -> DataType
forall a. Data a => SkinModified a -> Constr
forall a.
Data a =>
(forall b. Data b => b -> b) -> SkinModified a -> SkinModified a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> SkinModified a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> SkinModified a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SkinModified a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SkinModified a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SkinModified a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinModified a -> c (SkinModified a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (SkinModified a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SkinModified a))
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 (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SkinModified a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinModified a -> c (SkinModified a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (SkinModified a))
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d)
-> SkinModified a -> m (SkinModified a)
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> SkinModified a -> u
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> SkinModified a -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> SkinModified a -> [u]
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> SkinModified a -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SkinModified a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SkinModified a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SkinModified a -> r
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SkinModified a -> r
gmapT :: (forall b. Data b => b -> b) -> SkinModified a -> SkinModified a
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> SkinModified a -> SkinModified a
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SkinModified a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (SkinModified a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (SkinModified a))
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (SkinModified a))
dataTypeOf :: SkinModified a -> DataType
$cdataTypeOf :: forall a. Data a => SkinModified a -> DataType
toConstr :: SkinModified a -> Constr
$ctoConstr :: forall a. Data a => SkinModified a -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SkinModified a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (SkinModified a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinModified a -> c (SkinModified a)
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SkinModified a -> c (SkinModified a)
Data, SkinModified a -> SkinModified a -> Bool
forall a. Eq a => SkinModified a -> SkinModified a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SkinModified a -> SkinModified a -> Bool
$c/= :: forall a. Eq a => SkinModified a -> SkinModified a -> Bool
== :: SkinModified a -> SkinModified a -> Bool
$c== :: forall a. Eq a => SkinModified a -> SkinModified a -> Bool
Eq, forall a. Eq a => a -> SkinModified a -> Bool
forall a. Num a => SkinModified a -> a
forall a. Ord a => SkinModified a -> a
forall m. Monoid m => SkinModified m -> m
forall a. SkinModified a -> Bool
forall a. SkinModified a -> Int
forall a. SkinModified a -> [a]
forall a. (a -> a -> a) -> SkinModified a -> a
forall m a. Monoid m => (a -> m) -> SkinModified a -> m
forall b a. (b -> a -> b) -> b -> SkinModified a -> b
forall a b. (a -> b -> b) -> b -> SkinModified a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => SkinModified a -> a
$cproduct :: forall a. Num a => SkinModified a -> a
sum :: forall a. Num a => SkinModified a -> a
$csum :: forall a. Num a => SkinModified a -> a
minimum :: forall a. Ord a => SkinModified a -> a
$cminimum :: forall a. Ord a => SkinModified a -> a
maximum :: forall a. Ord a => SkinModified a -> a
$cmaximum :: forall a. Ord a => SkinModified a -> a
elem :: forall a. Eq a => a -> SkinModified a -> Bool
$celem :: forall a. Eq a => a -> SkinModified a -> Bool
length :: forall a. SkinModified a -> Int
$clength :: forall a. SkinModified a -> Int
null :: forall a. SkinModified a -> Bool
$cnull :: forall a. SkinModified a -> Bool
toList :: forall a. SkinModified a -> [a]
$ctoList :: forall a. SkinModified a -> [a]
foldl1 :: forall a. (a -> a -> a) -> SkinModified a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> SkinModified a -> a
foldr1 :: forall a. (a -> a -> a) -> SkinModified a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> SkinModified a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> SkinModified a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> SkinModified a -> b
foldl :: forall b a. (b -> a -> b) -> b -> SkinModified a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> SkinModified a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> SkinModified a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> SkinModified a -> b
foldr :: forall a b. (a -> b -> b) -> b -> SkinModified a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> SkinModified a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> SkinModified a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> SkinModified a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> SkinModified a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> SkinModified a -> m
fold :: forall m. Monoid m => SkinModified m -> m
$cfold :: forall m. Monoid m => SkinModified m -> m
Foldable, forall a b. a -> SkinModified b -> SkinModified a
forall a b. (a -> b) -> SkinModified a -> SkinModified b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> SkinModified b -> SkinModified a
$c<$ :: forall a b. a -> SkinModified b -> SkinModified a
fmap :: forall a b. (a -> b) -> SkinModified a -> SkinModified b
$cfmap :: forall a b. (a -> b) -> SkinModified a -> SkinModified b
Functor, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (SkinModified a) x -> SkinModified a
forall a x. SkinModified a -> Rep (SkinModified a) x
$cto :: forall a x. Rep (SkinModified a) x -> SkinModified a
$cfrom :: forall a x. SkinModified a -> Rep (SkinModified a) x
Generic, forall a. Rep1 SkinModified a -> SkinModified a
forall a. SkinModified a -> Rep1 SkinModified a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cto1 :: forall a. Rep1 SkinModified a -> SkinModified a
$cfrom1 :: forall a. SkinModified a -> Rep1 SkinModified a
Generic1, SkinModified a -> SkinModified a -> Bool
SkinModified a -> SkinModified a -> Ordering
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 {a}. Ord a => Eq (SkinModified a)
forall a. Ord a => SkinModified a -> SkinModified a -> Bool
forall a. Ord a => SkinModified a -> SkinModified a -> Ordering
forall a.
Ord a =>
SkinModified a -> SkinModified a -> SkinModified a
min :: SkinModified a -> SkinModified a -> SkinModified a
$cmin :: forall a.
Ord a =>
SkinModified a -> SkinModified a -> SkinModified a
max :: SkinModified a -> SkinModified a -> SkinModified a
$cmax :: forall a.
Ord a =>
SkinModified a -> SkinModified a -> SkinModified a
>= :: SkinModified a -> SkinModified a -> Bool
$c>= :: forall a. Ord a => SkinModified a -> SkinModified a -> Bool
> :: SkinModified a -> SkinModified a -> Bool
$c> :: forall a. Ord a => SkinModified a -> SkinModified a -> Bool
<= :: SkinModified a -> SkinModified a -> Bool
$c<= :: forall a. Ord a => SkinModified a -> SkinModified a -> Bool
< :: SkinModified a -> SkinModified a -> Bool
$c< :: forall a. Ord a => SkinModified a -> SkinModified a -> Bool
compare :: SkinModified a -> SkinModified a -> Ordering
$ccompare :: forall a. Ord a => SkinModified a -> SkinModified a -> Ordering
Ord, ReadPrec [SkinModified a]
ReadPrec (SkinModified a)
ReadS [SkinModified a]
forall a. Read a => ReadPrec [SkinModified a]
forall a. Read a => ReadPrec (SkinModified a)
forall a. Read a => Int -> ReadS (SkinModified a)
forall a. Read a => ReadS [SkinModified a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SkinModified a]
$creadListPrec :: forall a. Read a => ReadPrec [SkinModified a]
readPrec :: ReadPrec (SkinModified a)
$creadPrec :: forall a. Read a => ReadPrec (SkinModified a)
readList :: ReadS [SkinModified a]
$creadList :: forall a. Read a => ReadS [SkinModified a]
readsPrec :: Int -> ReadS (SkinModified a)
$creadsPrec :: forall a. Read a => Int -> ReadS (SkinModified a)
Read, Int -> SkinModified a -> ShowS
forall a. Show a => Int -> SkinModified a -> ShowS
forall a. Show a => [SkinModified a] -> ShowS
forall a. Show a => SkinModified a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SkinModified a] -> ShowS
$cshowList :: forall a. Show a => [SkinModified a] -> ShowS
show :: SkinModified a -> String
$cshow :: forall a. Show a => SkinModified a -> String
showsPrec :: Int -> SkinModified a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> SkinModified a -> ShowS
Show, Functor SkinModified
Foldable SkinModified
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
SkinModified (m a) -> m (SkinModified a)
forall (f :: * -> *) a.
Applicative f =>
SkinModified (f a) -> f (SkinModified a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SkinModified a -> m (SkinModified b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SkinModified a -> f (SkinModified b)
sequence :: forall (m :: * -> *) a.
Monad m =>
SkinModified (m a) -> m (SkinModified a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
SkinModified (m a) -> m (SkinModified a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SkinModified a -> m (SkinModified b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> SkinModified a -> m (SkinModified b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
SkinModified (f a) -> f (SkinModified a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
SkinModified (f a) -> f (SkinModified a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SkinModified a -> f (SkinModified b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SkinModified a -> f (SkinModified b)
Traversable)

instance Arbitrary1 SkinModified where
  liftArbitrary :: forall a. Gen a -> Gen (SkinModified a)
liftArbitrary Gen a
arb = forall a. a -> SkinColorModifier -> SkinModified a
SkinModified forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
arb forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Arbitrary a => Gen a
arbitrary

instance Arbitrary a => Arbitrary (SkinModified a) where
  arbitrary :: Gen (SkinModified a)
arbitrary = forall (f :: * -> *) a. (Arbitrary1 f, Arbitrary a) => Gen (f a)
arbitrary1

instance Bounded a => Bounded (SkinModified a) where
  minBound :: SkinModified a
minBound = forall a. a -> SkinColorModifier -> SkinModified a
SkinModified forall a. Bounded a => a
minBound forall a. Bounded a => a
minBound
  maxBound :: SkinModified a
maxBound = forall a. a -> SkinColorModifier -> SkinModified a
SkinModified forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound

instance Enum a => Enum (SkinModified a) where
  fromEnum :: SkinModified a -> Int
fromEnum (SkinModified a
a SkinColorModifier
m) = Int
5 forall a. Num a => a -> a -> a
* forall a. Enum a => a -> Int
fromEnum a
a forall a. Num a => a -> a -> a
+ forall a. Enum a => a -> Int
fromEnum SkinColorModifier
m
  toEnum :: Int -> SkinModified a
toEnum Int
n = forall a. a -> SkinColorModifier -> SkinModified a
SkinModified (forall a. Enum a => Int -> a
toEnum Int
q) (forall a. Enum a => Int -> a
toEnum Int
r)
    where
      ~(Int
q, Int
r) = forall a. Integral a => a -> a -> (a, a)
quotRem Int
n Int
5

instance Hashable a => Hashable (SkinModified a)

instance Eq1 SkinModified where
  liftEq :: forall a b.
(a -> b -> Bool) -> SkinModified a -> SkinModified b -> Bool
liftEq a -> b -> Bool
eq = SkinModified a -> SkinModified b -> Bool
go
    where
      go :: SkinModified a -> SkinModified b -> Bool
go (SkinModified a
xa SkinColorModifier
sa) (SkinModified b
xb SkinColorModifier
sb) = a -> b -> Bool
eq a
xa b
xb Bool -> Bool -> Bool
&& SkinColorModifier
sa forall a. Eq a => a -> a -> Bool
== SkinColorModifier
sb

instance Hashable1 SkinModified

instance WithSkinColorModifierUnicodeText a => UnicodeText (SkinModified a) where
  toUnicodeText :: SkinModified a -> Text
toUnicodeText (SkinModified a
x SkinColorModifier
m) = forall a.
WithSkinColorModifierUnicodeText a =>
a -> SkinColorModifier -> Text
withSkinModifier a
x SkinColorModifier
m
  fromUnicodeText :: Text -> Maybe (SkinModified a)
fromUnicodeText Text
t
    | Just (a
x, Just SkinColorModifier
m) <- forall a.
WithSkinColorModifierUnicodeText a =>
Text -> Maybe (a, Maybe SkinColorModifier)
withoutOptionalSkinModifier Text
t = forall a. a -> Maybe a
Just (forall a. a -> SkinColorModifier -> SkinModified a
SkinModified a
x SkinColorModifier
m)
    | Bool
otherwise = forall a. Maybe a
Nothing
  isInTextRange :: Text -> Bool
isInTextRange Text
t
    | Just (a
_, Just SkinColorModifier
_) <- forall a.
WithSkinColorModifierUnicodeText a =>
Text -> Maybe (a, Maybe SkinColorModifier)
withoutOptionalSkinModifier @a Text
t = Bool
True
    | Bool
otherwise = Bool
False

-- | The 'SkinColorModifier' that corresponds to type one of the /Fitzpatrick
-- scale/.
pattern FitzpatrickI :: SkinColorModifier
pattern $bFitzpatrickI :: SkinColorModifier
$mFitzpatrickI :: forall {r}. SkinColorModifier -> ((# #) -> r) -> ((# #) -> r) -> r
FitzpatrickI = Light

-- | The 'SkinColorModifier' that corresponds to type two of the /Fitzpatrick
-- scale/.
pattern FitzpatrickII :: SkinColorModifier
pattern $bFitzpatrickII :: SkinColorModifier
$mFitzpatrickII :: forall {r}. SkinColorModifier -> ((# #) -> r) -> ((# #) -> r) -> r
FitzpatrickII = Light

-- | The 'SkinColorModifier' that corresponds to type three of the /Fitzpatrick
-- scale/.
pattern FitzpatrickIII :: SkinColorModifier
pattern $bFitzpatrickIII :: SkinColorModifier
$mFitzpatrickIII :: forall {r}. SkinColorModifier -> ((# #) -> r) -> ((# #) -> r) -> r
FitzpatrickIII = MediumLight

-- | The 'SkinColorModifier' that corresponds to type four of the /Fitzpatrick
-- scale/.
pattern FitzpatrickIV :: SkinColorModifier
pattern $bFitzpatrickIV :: SkinColorModifier
$mFitzpatrickIV :: forall {r}. SkinColorModifier -> ((# #) -> r) -> ((# #) -> r) -> r
FitzpatrickIV = Medium

-- | The 'SkinColorModifier' that corresponds to type five of the /Fitzpatrick
-- scale/.
pattern FitzpatrickV :: SkinColorModifier
pattern $bFitzpatrickV :: SkinColorModifier
$mFitzpatrickV :: forall {r}. SkinColorModifier -> ((# #) -> r) -> ((# #) -> r) -> r
FitzpatrickV = MediumDark

-- | The 'SkinColorModifier' that corresponds to type six of the /Fitzpatrick
-- scale/.
pattern FitzpatrickVI :: SkinColorModifier
pattern $bFitzpatrickVI :: SkinColorModifier
$mFitzpatrickVI :: forall {r}. SkinColorModifier -> ((# #) -> r) -> ((# #) -> r) -> r
FitzpatrickVI = Dark

-- | Convert the given /Fitzpatrick skin type/ to the corresponding
-- 'SkinColorModifier' wrapped in a 'Just', if no such 'SkinColorModifier'
-- exists, 'Nothing' is returned.
fromFitzpatrick ::
  Integral i =>
  -- | The given /Fitzpatrick skin type/.
  i ->
  -- | The corresponding 'SkinColorModifier' wrapped in a 'Just'; 'Nothing' if no such modifier exists.
  Maybe SkinColorModifier
fromFitzpatrick :: forall i. Integral i => i -> Maybe SkinColorModifier
fromFitzpatrick i
1 = forall a. a -> Maybe a
Just SkinColorModifier
Light
fromFitzpatrick i
2 = forall a. a -> Maybe a
Just SkinColorModifier
Light
fromFitzpatrick i
3 = forall a. a -> Maybe a
Just SkinColorModifier
MediumLight
fromFitzpatrick i
4 = forall a. a -> Maybe a
Just SkinColorModifier
Medium
fromFitzpatrick i
5 = forall a. a -> Maybe a
Just SkinColorModifier
MediumDark
fromFitzpatrick i
6 = forall a. a -> Maybe a
Just SkinColorModifier
Dark
fromFitzpatrick i
_ = forall a. Maybe a
Nothing

-- | For emoji often the skin color is optional: in case there is no skin color specified, the emoji have often a /yellow/ skin color.
type OptionalSkinColorModifier = Maybe SkinColorModifier