| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 
 | {-# LANGUAGE MagicHash                  #-}
{-# LANGUAGE BangPatterns               #-}
module Basement.Types.Char7
    ( Char7(..)
    , toChar
    , fromCharMask
    , fromChar
    , fromByteMask
    , fromByte
    -- * individual ASCII Characters
    , c7_LF
    , c7_CR
    , c7_minus
    , c7_a
    , c7_A
    , c7_z
    , c7_Z
    , c7_0
    , c7_1
    , c7_2
    , c7_3
    , c7_4
    , c7_5
    , c7_6
    , c7_7
    , c7_8
    , c7_9
    -- * Upper / Lower With ASCII
    , c7Upper
    , c7Lower
    ) where
import GHC.Prim
import GHC.Word
import GHC.Types
import Data.Bits
import Data.Maybe
import Basement.Compat.Base
import Basement.Compat.Primitive
-- | ASCII value between 0x0 and 0x7f
newtype Char7 = Char7 { toByte :: Word8 }
    deriving (Show,Eq,Ord,Typeable)
-- | Convert a 'Char7' to a unicode code point 'Char'
toChar :: Char7 -> Char
toChar !(Char7 (W8# w)) = C# (chr# (word2Int# (word8ToWord# w)))
-- | Try to convert a 'Char' to a 'Char7'
-- 
-- If the code point is non ascii, then Nothing is returned.
fromChar :: Char -> Maybe Char7
fromChar !(C# c#)
    | bool# (ltChar# c# (chr# 0x80#)) = Just $ Char7 $ W8# (wordToWord8# (int2Word# (ord# c#)))
    | otherwise                       = Nothing
-- | Try to convert 'Word8' to a 'Char7'
--
-- If the byte got higher bit set, then Nothing is returned.
fromByte :: Word8 -> Maybe Char7
fromByte !w
    | (w .&. 0x80) == 0 = Just $ Char7 w
    | otherwise         = Nothing
-- | Convert a 'Char' to a 'Char7' ignoring all higher bits
fromCharMask :: Char -> Char7
fromCharMask !(C# c#) = Char7 $ W8# (wordToWord8# (and# (int2Word# (ord# c#)) 0x7f##))
-- | Convert a 'Byte' to a 'Char7' ignoring the higher bit
fromByteMask :: Word8 -> Char7
fromByteMask !w = Char7 (w .&. 0x7f)
c7_LF :: Char7
c7_LF = Char7 0xa
c7_CR :: Char7
c7_CR = Char7 0xd
c7_minus :: Char7
c7_minus = Char7 0x2d
c7_a :: Char7
c7_a = Char7 0x61
c7_A :: Char7
c7_A = Char7 0x41
c7_z :: Char7
c7_z = Char7 0x7a
c7_Z :: Char7
c7_Z = Char7 0x5a
c7_0, c7_1, c7_2, c7_3, c7_4, c7_5, c7_6, c7_7, c7_8, c7_9 :: Char7
c7_0 = Char7 0x30
c7_1 = Char7 0x31
c7_2 = Char7 0x32
c7_3 = Char7 0x33
c7_4 = Char7 0x34
c7_5 = Char7 0x35
c7_6 = Char7 0x36
c7_7 = Char7 0x37
c7_8 = Char7 0x38
c7_9 = Char7 0x39
c7Lower :: Char7 -> Char7
c7Lower c@(Char7 w)
    | c <  c7_A = c
    | c <= c7_Z = Char7 (w .|. 0x20)
    | otherwise = c
c7Upper :: Char7 -> Char7
c7Upper c@(Char7 w)
    | c <  c7_a = c
    | c <= c7_z = Char7 (w .&. 0xdf)
    | otherwise = c
 |