{-# 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
ScienceEmoji -> ScienceEmoji -> Bounded ScienceEmoji
forall a. a -> a -> Bounded a
$cminBound :: ScienceEmoji
minBound :: ScienceEmoji
$cmaxBound :: ScienceEmoji
maxBound :: ScienceEmoji
Bounded, Typeable ScienceEmoji
Typeable ScienceEmoji
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> ScienceEmoji -> c ScienceEmoji)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c ScienceEmoji)
-> (ScienceEmoji -> Constr)
-> (ScienceEmoji -> DataType)
-> (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))
-> ((forall b. Data b => b -> b) -> ScienceEmoji -> ScienceEmoji)
-> (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 u. (forall d. Data d => d -> u) -> ScienceEmoji -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> ScienceEmoji -> u)
-> (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 (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji)
-> Data ScienceEmoji
ScienceEmoji -> Constr
ScienceEmoji -> DataType
(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)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScienceEmoji -> c ScienceEmoji
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> ScienceEmoji -> c ScienceEmoji
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScienceEmoji
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c ScienceEmoji
$ctoConstr :: ScienceEmoji -> Constr
toConstr :: ScienceEmoji -> Constr
$cdataTypeOf :: ScienceEmoji -> DataType
dataTypeOf :: ScienceEmoji -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScienceEmoji)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c ScienceEmoji)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScienceEmoji)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c ScienceEmoji)
$cgmapT :: (forall b. Data b => b -> b) -> ScienceEmoji -> ScienceEmoji
gmapT :: (forall b. Data b => b -> b) -> ScienceEmoji -> ScienceEmoji
$cgmapQl :: 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
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> ScienceEmoji -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> ScienceEmoji -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> ScienceEmoji -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ScienceEmoji -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> ScienceEmoji -> u
$cgmapM :: forall (m :: * -> *).
Monad 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
$cgmapMp :: 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
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> ScienceEmoji -> m ScienceEmoji
Data, Int -> ScienceEmoji
ScienceEmoji -> Int
ScienceEmoji -> [ScienceEmoji]
ScienceEmoji -> ScienceEmoji
ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
(ScienceEmoji -> ScienceEmoji)
-> (ScienceEmoji -> ScienceEmoji)
-> (Int -> ScienceEmoji)
-> (ScienceEmoji -> Int)
-> (ScienceEmoji -> [ScienceEmoji])
-> (ScienceEmoji -> ScienceEmoji -> [ScienceEmoji])
-> (ScienceEmoji -> ScienceEmoji -> [ScienceEmoji])
-> (ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji])
-> Enum 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
$csucc :: ScienceEmoji -> ScienceEmoji
succ :: ScienceEmoji -> ScienceEmoji
$cpred :: ScienceEmoji -> ScienceEmoji
pred :: ScienceEmoji -> ScienceEmoji
$ctoEnum :: Int -> ScienceEmoji
toEnum :: Int -> ScienceEmoji
$cfromEnum :: ScienceEmoji -> Int
fromEnum :: ScienceEmoji -> Int
$cenumFrom :: ScienceEmoji -> [ScienceEmoji]
enumFrom :: ScienceEmoji -> [ScienceEmoji]
$cenumFromThen :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
enumFromThen :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
$cenumFromTo :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
enumFromTo :: ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
$cenumFromThenTo :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
enumFromThenTo :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji -> [ScienceEmoji]
Enum, ScienceEmoji -> ScienceEmoji -> Bool
(ScienceEmoji -> ScienceEmoji -> Bool)
-> (ScienceEmoji -> ScienceEmoji -> Bool) -> Eq ScienceEmoji
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ScienceEmoji -> ScienceEmoji -> Bool
== :: ScienceEmoji -> ScienceEmoji -> Bool
$c/= :: ScienceEmoji -> ScienceEmoji -> Bool
/= :: ScienceEmoji -> ScienceEmoji -> Bool
Eq, (forall x. ScienceEmoji -> Rep ScienceEmoji x)
-> (forall x. Rep ScienceEmoji x -> ScienceEmoji)
-> Generic ScienceEmoji
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
$cfrom :: forall x. ScienceEmoji -> Rep ScienceEmoji x
from :: forall x. ScienceEmoji -> Rep ScienceEmoji x
$cto :: forall x. Rep ScienceEmoji x -> ScienceEmoji
to :: forall x. Rep ScienceEmoji x -> ScienceEmoji
Generic, Eq ScienceEmoji
Eq ScienceEmoji
-> (ScienceEmoji -> ScienceEmoji -> Ordering)
-> (ScienceEmoji -> ScienceEmoji -> Bool)
-> (ScienceEmoji -> ScienceEmoji -> Bool)
-> (ScienceEmoji -> ScienceEmoji -> Bool)
-> (ScienceEmoji -> ScienceEmoji -> Bool)
-> (ScienceEmoji -> ScienceEmoji -> ScienceEmoji)
-> (ScienceEmoji -> ScienceEmoji -> ScienceEmoji)
-> Ord 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
$ccompare :: ScienceEmoji -> ScienceEmoji -> Ordering
compare :: ScienceEmoji -> ScienceEmoji -> Ordering
$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
>= :: ScienceEmoji -> ScienceEmoji -> Bool
$cmax :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
max :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
$cmin :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
min :: ScienceEmoji -> ScienceEmoji -> ScienceEmoji
Ord, ReadPrec [ScienceEmoji]
ReadPrec ScienceEmoji
Int -> ReadS ScienceEmoji
ReadS [ScienceEmoji]
(Int -> ReadS ScienceEmoji)
-> ReadS [ScienceEmoji]
-> ReadPrec ScienceEmoji
-> ReadPrec [ScienceEmoji]
-> Read ScienceEmoji
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ScienceEmoji
readsPrec :: Int -> ReadS ScienceEmoji
$creadList :: ReadS [ScienceEmoji]
readList :: ReadS [ScienceEmoji]
$creadPrec :: ReadPrec ScienceEmoji
readPrec :: ReadPrec ScienceEmoji
$creadListPrec :: ReadPrec [ScienceEmoji]
readListPrec :: ReadPrec [ScienceEmoji]
Read, Int -> ScienceEmoji -> ShowS
[ScienceEmoji] -> ShowS
ScienceEmoji -> [Char]
(Int -> ScienceEmoji -> ShowS)
-> (ScienceEmoji -> [Char])
-> ([ScienceEmoji] -> ShowS)
-> Show ScienceEmoji
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ScienceEmoji -> ShowS
showsPrec :: Int -> ScienceEmoji -> ShowS
$cshow :: ScienceEmoji -> [Char]
show :: ScienceEmoji -> [Char]
$cshowList :: [ScienceEmoji] -> ShowS
showList :: [ScienceEmoji] -> ShowS
Show)

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