module ASCII.TemplateHaskell (

    {- * Characters          -} charExp,     charPat,
    {- * Character lists     -} charListExp, charListPat,
    {- * Character supersets -} isCharExp,   isCharPat,
    {- * String supersets    -} isStringExp, isStringPat

  ) where

import qualified ASCII.Char       as  ASCII
import qualified ASCII.Superset   as  S

import Data.Data                  ( Data )
import Data.Maybe                 ( Maybe (..) )
import Language.Haskell.TH.Syntax ( Q, Exp, Pat, dataToExpQ, dataToPatQ )

exp :: Data a => a -> Q Exp
exp :: a -> Q Exp
exp = (forall b. Data b => b -> Maybe (Q Exp)) -> a -> Q Exp
forall a.
Data a =>
(forall b. Data b => b -> Maybe (Q Exp)) -> a -> Q Exp
dataToExpQ (\b
_ -> Maybe (Q Exp)
forall a. Maybe a
Nothing)

pat :: Data a => a -> Q Pat
pat :: a -> Q Pat
pat = (forall b. Data b => b -> Maybe (Q Pat)) -> a -> Q Pat
forall a.
Data a =>
(forall b. Data b => b -> Maybe (Q Pat)) -> a -> Q Pat
dataToPatQ (\b
_ -> Maybe (Q Pat)
forall a. Maybe a
Nothing)

{- |

>>> $(toCharOrFail 'F' >>= charExp)
CapitalLetterF

>>> $(toCharOrFail '\DEL' >>= charExp)
Delete

-}

charExp :: ASCII.Char -> Q Exp
charExp :: Char -> Q Exp
charExp = Char -> Q Exp
forall a. Data a => a -> Q Exp
exp

{- |

>>> :{
>>> case SmallLetterS of
>>>     $(toCharOrFail 'r' >>= charPat) -> 1
>>>     $(toCharOrFail 's' >>= charPat) -> 2
>>>     _                               -> 3
>>> :}
2

This is the same as:

>>> :{
>>> case SmallLetterS of
>>>     SmallLetterR -> 1
>>>     SmallLetterS -> 2
>>>     _            -> 3
>>> :}
2

-}

charPat :: ASCII.Char -> Q Pat
charPat :: Char -> Q Pat
charPat = Char -> Q Pat
forall a. Data a => a -> Q Pat
pat

{- |

>>> $(charListExp [CapitalLetterH, SmallLetterI])
[CapitalLetterH,SmallLetterI]

-}

charListExp :: [ASCII.Char] -> Q Exp
charListExp :: [Char] -> Q Exp
charListExp = [Char] -> Q Exp
forall a. Data a => a -> Q Exp
exp

{- |

>>> :{
>>> case [CapitalLetterH, SmallLetterI] of
>>>     $(charListPat [CapitalLetterH, SmallLetterA]) -> 1
>>>     $(charListPat [CapitalLetterH, SmallLetterI]) -> 2
>>>     _                                             -> 3
>>> :}
2

-}

charListPat :: [ASCII.Char] -> Q Pat
charListPat :: [Char] -> Q Pat
charListPat = [Char] -> Q Pat
forall a. Data a => a -> Q Pat
pat

{- |

>>> $(isCharExp CapitalLetterA) :: ASCII.Char
CapitalLetterA

>>> $(isCharExp CapitalLetterA) :: Word8
65

>>> $(isCharExp CapitalLetterA) :: ASCII Word8
asciiUnsafe 65

-}

isCharExp :: ASCII.Char -> Q Exp
isCharExp :: Char -> Q Exp
isCharExp Char
x = [| S.fromChar $(charExp x) |]

{- |

>>> :set -XViewPatterns

>>> :{
>>> case (66 :: Word8) of
>>>     $(isCharPat CapitalLetterA) -> 1
>>>     $(isCharPat CapitalLetterB) -> 2
>>>     _                           -> 3
>>> :}
2

-}

isCharPat :: ASCII.Char -> Q Pat
isCharPat :: Char -> Q Pat
isCharPat Char
x = [p| (S.toCharMaybe -> Just $(charPat x)) |]

isStringExp :: [ASCII.Char] -> Q Exp
isStringExp :: [Char] -> Q Exp
isStringExp [Char]
xs = [| S.fromCharList $(charListExp xs) |]

isStringPat :: [ASCII.Char] -> Q Pat
isStringPat :: [Char] -> Q Pat
isStringPat [Char]
xs = [p| (S.toCharListMaybe -> Just $(charListPat xs)) |]