{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}

-- |
-- Module      :  ELynx.Data.Alphabet.Character
-- Description :  Alphabet characters
-- Copyright   :  (c) Dominik Schrempf 2021
-- License     :  GPL-3.0-or-later
--
-- Maintainer  :  dominik.schrempf@gmail.com
-- Stability   :  unstable
-- Portability :  portable
--
-- Creation date: Sun May 19 21:06:38 2019.
module ELynx.Data.Alphabet.Character
  ( Character,
    toWord,
    fromWord,
    toChar,
    fromChar,
    toString,
    fromString,
    toCVec,
    fromCVec,
  )
where

import Data.ByteString.Internal (c2w, w2c)
import qualified Data.Vector.Unboxed as V
import Data.Vector.Unboxed.Deriving
import Data.Word8
import qualified ELynx.Data.Character.Character as C

-- | Alphabet characters; abstracted so that representation can be changed at
-- some point.
newtype Character = Character Word8
  deriving (ReadPrec [Character]
ReadPrec Character
Int -> ReadS Character
ReadS [Character]
(Int -> ReadS Character)
-> ReadS [Character]
-> ReadPrec Character
-> ReadPrec [Character]
-> Read Character
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Character]
$creadListPrec :: ReadPrec [Character]
readPrec :: ReadPrec Character
$creadPrec :: ReadPrec Character
readList :: ReadS [Character]
$creadList :: ReadS [Character]
readsPrec :: Int -> ReadS Character
$creadsPrec :: Int -> ReadS Character
Read, Int -> Character -> ShowS
[Character] -> ShowS
Character -> String
(Int -> Character -> ShowS)
-> (Character -> String)
-> ([Character] -> ShowS)
-> Show Character
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Character] -> ShowS
$cshowList :: [Character] -> ShowS
show :: Character -> String
$cshow :: Character -> String
showsPrec :: Int -> Character -> ShowS
$cshowsPrec :: Int -> Character -> ShowS
Show, Character -> Character -> Bool
(Character -> Character -> Bool)
-> (Character -> Character -> Bool) -> Eq Character
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Character -> Character -> Bool
$c/= :: Character -> Character -> Bool
== :: Character -> Character -> Bool
$c== :: Character -> Character -> Bool
Eq, Eq Character
Eq Character
-> (Character -> Character -> Ordering)
-> (Character -> Character -> Bool)
-> (Character -> Character -> Bool)
-> (Character -> Character -> Bool)
-> (Character -> Character -> Bool)
-> (Character -> Character -> Character)
-> (Character -> Character -> Character)
-> Ord Character
Character -> Character -> Bool
Character -> Character -> Ordering
Character -> Character -> Character
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 :: Character -> Character -> Character
$cmin :: Character -> Character -> Character
max :: Character -> Character -> Character
$cmax :: Character -> Character -> Character
>= :: Character -> Character -> Bool
$c>= :: Character -> Character -> Bool
> :: Character -> Character -> Bool
$c> :: Character -> Character -> Bool
<= :: Character -> Character -> Bool
$c<= :: Character -> Character -> Bool
< :: Character -> Character -> Bool
$c< :: Character -> Character -> Bool
compare :: Character -> Character -> Ordering
$ccompare :: Character -> Character -> Ordering
$cp1Ord :: Eq Character
Ord, Character
Character -> Character -> Bounded Character
forall a. a -> a -> Bounded a
maxBound :: Character
$cmaxBound :: Character
minBound :: Character
$cminBound :: Character
Bounded)

derivingUnbox
  "Character"
  [t|Character -> Word8|]
  [|\(Character w) -> w|]
  [|Character|]

-- | Conversion of 'Character's.
toWord :: Character -> Word8
toWord :: Character -> Word8
toWord (Character Word8
w) = Word8
w

-- | Conversion of 'Character's.
fromWord :: Word8 -> Character
fromWord :: Word8 -> Character
fromWord = Word8 -> Character
Character

-- | Conversion of 'Character's.
toChar :: Character -> Char
toChar :: Character -> Char
toChar (Character Word8
w) = Word8 -> Char
w2c Word8
w

-- | Conversion of 'Character's.
fromChar :: Char -> Character
fromChar :: Char -> Character
fromChar = Word8 -> Character
Character (Word8 -> Character) -> (Char -> Word8) -> Char -> Character
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Word8
c2w

-- | Conversion of 'Character's.
toString :: [Character] -> String
toString :: [Character] -> String
toString = (Character -> Char) -> [Character] -> String
forall a b. (a -> b) -> [a] -> [b]
map Character -> Char
toChar

-- | Conversion of 'Character's.
fromString :: String -> [Character]
fromString :: String -> [Character]
fromString = (Char -> Character) -> String -> [Character]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Character
fromChar

-- | Conversion of 'Character's.
toCVec :: C.Character a => V.Vector Character -> V.Vector a
toCVec :: Vector Character -> Vector a
toCVec = (Character -> a) -> Vector Character -> Vector a
forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
V.map (Word8 -> a
forall a. Character a => Word8 -> a
C.fromWord (Word8 -> a) -> (Character -> Word8) -> Character -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Character -> Word8
toWord)

-- | Conversion of 'Character's.
fromCVec :: C.Character a => V.Vector a -> V.Vector Character
fromCVec :: Vector a -> Vector Character
fromCVec = (a -> Character) -> Vector a -> Vector Character
forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
V.map (Word8 -> Character
fromWord (Word8 -> Character) -> (a -> Word8) -> a -> Character
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Word8
forall a. Character a => a -> Word8
C.toWord)