{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Safe #-}

-- |
-- Module      : Data.Char.Emoji.Science
-- Description : A module to render and parse emoji related to science.
-- Maintainer  : hapytexeu+gh@gmail.com
-- Stability   : experimental
-- Portability : POSIX
--
-- Unicode defines nine Emoji related to science. This module has a data type together with functions
-- to convert this to and from a text fragment.
module Data.Char.Emoji.Science
  ( -- * Defining science emoji.
    ScienceEmoji (Alembic, TestTube, PetriDish, DnaDoubleHelix, Microscope, Telescope, SatelliteAntenna),
  )
where

import Control.DeepSeq (NFData)
import Data.Char (chr, ord)
import Data.Char.Core (UnicodeText (fromUnicodeText, isInTextRange, toUnicodeText))
import Data.Data (Data)
import Data.Hashable (Hashable)
import Data.Text (singleton, unpack)
import GHC.Generics (Generic)
import Test.QuickCheck.Arbitrary (Arbitrary (arbitrary), arbitraryBoundedEnum)

-- | There are nine emoji that depict science.
data ScienceEmoji
  = Alembic -- An /alembic/ is an apparatus for destillation. Normally this is depicted as ⚗️.
  | -- | A /test tube/ is used to conduct chemical experiments. Normally this is depicted as 🧪.
    TestTube
  | -- | A /petri dish/ is used to culture microbes. Normally this is depicted as 🧫.
    PetriDish
  | -- | A double helix of DNA is the genetic blueprint of life. Normally this is depicted as 🧬.
    DnaDoubleHelix
  | -- | A /microscope/ is used to magnify small objects. Normally this is depicted as 🔬.
    Microscope
  | -- | A /telescope/ is used to gaze at stars and planets in the night sky. Normally this is depicted as 🔭.
    Telescope
  | -- | A /dish satellite/ is used to send and receive to or from communication satellites. This is normally depicited as 📡.
    SatelliteAntenna
  deriving (ScienceEmoji
forall a. a -> a -> Bounded a
maxBound :: ScienceEmoji
$cmaxBound :: ScienceEmoji
minBound :: ScienceEmoji
$cminBound :: ScienceEmoji
Bounded, Typeable ScienceEmoji
ScienceEmoji -> DataType
ScienceEmoji -> Constr
(forall b. Data b => b -> b) -> ScienceEmoji -> ScienceEmoji
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) -> ScienceEmoji -> u
forall u. (forall d. Data d => d -> u) -> ScienceEmoji -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScienceEmoji
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScienceEmoji -> c ScienceEmoji
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScienceEmoji)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScienceEmoji)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ScienceEmoji -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ScienceEmoji -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> ScienceEmoji -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ScienceEmoji -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
gmapT :: (forall b. Data b => b -> b) -> ScienceEmoji -> ScienceEmoji
$cgmapT :: (forall b. Data b => b -> b) -> ScienceEmoji -> ScienceEmoji
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScienceEmoji)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScienceEmoji)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScienceEmoji)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScienceEmoji)
dataTypeOf :: ScienceEmoji -> DataType
$cdataTypeOf :: ScienceEmoji -> DataType
toConstr :: ScienceEmoji -> Constr
$ctoConstr :: ScienceEmoji -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScienceEmoji
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScienceEmoji
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScienceEmoji -> c ScienceEmoji
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScienceEmoji -> c ScienceEmoji
Data, Int -> ScienceEmoji
ScienceEmoji -> Int
ScienceEmoji -> [ScienceEmoji]
ScienceEmoji -> ScienceEmoji
ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
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 :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
$cenumFromThenTo :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
enumFromTo :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
$cenumFromTo :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
enumFromThen :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
$cenumFromThen :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
enumFrom :: ScienceEmoji -> [ScienceEmoji]
$cenumFrom :: ScienceEmoji -> [ScienceEmoji]
fromEnum :: ScienceEmoji -> Int
$cfromEnum :: ScienceEmoji -> Int
toEnum :: Int -> ScienceEmoji
$ctoEnum :: Int -> ScienceEmoji
pred :: ScienceEmoji -> ScienceEmoji
$cpred :: ScienceEmoji -> ScienceEmoji
succ :: ScienceEmoji -> ScienceEmoji
$csucc :: ScienceEmoji -> ScienceEmoji
Enum, ScienceEmoji -> ScienceEmoji -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ScienceEmoji -> ScienceEmoji -> Bool
$c/= :: ScienceEmoji -> ScienceEmoji -> Bool
== :: ScienceEmoji -> ScienceEmoji -> Bool
$c== :: ScienceEmoji -> ScienceEmoji -> Bool
Eq, forall x. Rep ScienceEmoji x -> ScienceEmoji
forall x. ScienceEmoji -> Rep ScienceEmoji x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ScienceEmoji x -> ScienceEmoji
$cfrom :: forall x. ScienceEmoji -> Rep ScienceEmoji x
Generic, Eq ScienceEmoji
ScienceEmoji -> ScienceEmoji -> Bool
ScienceEmoji -> ScienceEmoji -> Ordering
ScienceEmoji -> ScienceEmoji -> ScienceEmoji
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 :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
$cmin :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
max :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
$cmax :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
>= :: ScienceEmoji -> ScienceEmoji -> Bool
$c>= :: ScienceEmoji -> ScienceEmoji -> Bool
> :: ScienceEmoji -> ScienceEmoji -> Bool
$c> :: ScienceEmoji -> ScienceEmoji -> Bool
<= :: ScienceEmoji -> ScienceEmoji -> Bool
$c<= :: ScienceEmoji -> ScienceEmoji -> Bool
< :: ScienceEmoji -> ScienceEmoji -> Bool
$c< :: ScienceEmoji -> ScienceEmoji -> Bool
compare :: ScienceEmoji -> ScienceEmoji -> Ordering
$ccompare :: ScienceEmoji -> ScienceEmoji -> Ordering
Ord, ReadPrec [ScienceEmoji]
ReadPrec ScienceEmoji
Int -> ReadS ScienceEmoji
ReadS [ScienceEmoji]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ScienceEmoji]
$creadListPrec :: ReadPrec [ScienceEmoji]
readPrec :: ReadPrec ScienceEmoji
$creadPrec :: ReadPrec ScienceEmoji
readList :: ReadS [ScienceEmoji]
$creadList :: ReadS [ScienceEmoji]
readsPrec :: Int -> ReadS ScienceEmoji
$creadsPrec :: Int -> ReadS ScienceEmoji
Read, Int -> ScienceEmoji -> ShowS
[ScienceEmoji] -> ShowS
ScienceEmoji -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
showList :: [ScienceEmoji] -> ShowS
$cshowList :: [ScienceEmoji] -> ShowS
show :: ScienceEmoji -> [Char]
$cshow :: ScienceEmoji -> [Char]
showsPrec :: Int -> ScienceEmoji -> ShowS
$cshowsPrec :: Int -> ScienceEmoji -> ShowS
Show)

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

instance Hashable ScienceEmoji

instance NFData ScienceEmoji

instance UnicodeText ScienceEmoji where
  toUnicodeText :: ScienceEmoji -> Text
toUnicodeText ScienceEmoji
Alembic = Text
"\x2697\xfe0f"
  toUnicodeText ScienceEmoji
Microscope = Text
"\x1f52c"
  toUnicodeText ScienceEmoji
Telescope = Text
"\x1f52d"
  toUnicodeText ScienceEmoji
SatelliteAntenna = Text
"\x1f4e1"
  toUnicodeText ScienceEmoji
x = Char -> Text
singleton (Int -> Char
chr (forall a. Enum a => a -> Int
fromEnum ScienceEmoji
x forall a. Num a => a -> a -> a
+ Int
0x1f9e9))
  fromUnicodeText :: Text -> Maybe ScienceEmoji
fromUnicodeText Text
"\x2697\xfe0f" = forall a. a -> Maybe a
Just ScienceEmoji
Alembic
  fromUnicodeText Text
"\x1f52c" = forall a. a -> Maybe a
Just ScienceEmoji
Microscope
  fromUnicodeText Text
"\x1f52d" = forall a. a -> Maybe a
Just ScienceEmoji
Telescope
  fromUnicodeText Text
"\x1f4e1" = forall a. a -> Maybe a
Just ScienceEmoji
SatelliteAntenna
  fromUnicodeText Text
"\x1f9ea" = forall a. a -> Maybe a
Just ScienceEmoji
TestTube
  fromUnicodeText Text
"\x1f9eb" = forall a. a -> Maybe a
Just ScienceEmoji
PetriDish
  fromUnicodeText Text
t
    | [Char
c] <- Text -> [Char]
unpack Text
t, Char
'\x1f9ea' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\x1f9ec' = forall a. a -> Maybe a
Just (forall a. Enum a => Int -> a
toEnum (Char -> Int
ord Char
c forall a. Num a => a -> a -> a
- Int
0x1f9e9))
    | Bool
otherwise = forall a. Maybe a
Nothing
  isInTextRange :: Text -> Bool
isInTextRange Text
"\x2697\xfe0f" = Bool
True
  isInTextRange Text
"\x1f52c" = Bool
True
  isInTextRange Text
"\x1f52d" = Bool
True
  isInTextRange Text
"\x1f4e1" = Bool
True
  isInTextRange Text
"\x1f9ea" = Bool
True
  isInTextRange Text
"\x1f9eb" = Bool
True
  isInTextRange Text
t
    | [Char
c] <- Text -> [Char]
unpack Text
t = Char
'\x1f9ea' forall a. Ord a => a -> a -> Bool
<= Char
c Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\x1f9ec'
    | Bool
otherwise = Bool
False