    {-# 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 { Char7 -> Word8
    toByte :: Word8 }
        deriving (Int -> Char7 -> ShowS
    [Char7] -> ShowS
    Char7 -> String
    (Int -> Char7 -> ShowS)
    -> (Char7 -> String) -> ([Char7] -> ShowS) -> Show Char7
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Char7 -> ShowS
    showsPrec :: Int -> Char7 -> ShowS
    $cshow :: Char7 -> String
    show :: Char7 -> String
    $cshowList :: [Char7] -> ShowS
    showList :: [Char7] -> ShowS
    Show,Char7 -> Char7 -> Bool
    (Char7 -> Char7 -> Bool) -> (Char7 -> Char7 -> Bool) -> Eq Char7
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Char7 -> Char7 -> Bool
    == :: Char7 -> Char7 -> Bool
    $c/= :: Char7 -> Char7 -> Bool
    /= :: Char7 -> Char7 -> Bool
    Eq,Eq Char7
    Eq Char7 =>
    (Char7 -> Char7 -> Ordering)
    -> (Char7 -> Char7 -> Bool)
    -> (Char7 -> Char7 -> Bool)
    -> (Char7 -> Char7 -> Bool)
    -> (Char7 -> Char7 -> Bool)
    -> (Char7 -> Char7 -> Char7)
    -> (Char7 -> Char7 -> Char7)
    -> Ord Char7
    Char7 -> Char7 -> Bool
    Char7 -> Char7 -> Ordering
    Char7 -> Char7 -> Char7
    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 :: Char7 -> Char7 -> Ordering
    compare :: Char7 -> Char7 -> Ordering
    $c< :: Char7 -> Char7 -> Bool
    < :: Char7 -> Char7 -> Bool
    $c<= :: Char7 -> Char7 -> Bool
    <= :: Char7 -> Char7 -> Bool
    $c> :: Char7 -> Char7 -> Bool
    > :: Char7 -> Char7 -> Bool
    $c>= :: Char7 -> Char7 -> Bool
    >= :: Char7 -> Char7 -> Bool
    $cmax :: Char7 -> Char7 -> Char7
    max :: Char7 -> Char7 -> Char7
    $cmin :: Char7 -> Char7 -> Char7
    min :: Char7 -> Char7 -> Char7
    Ord,Typeable)

    -- | Convert a 'Char7' to a unicode code point 'Char'
    toChar :: Char7 -> Char
    toChar :: Char7 -> Char
    toChar !(Char7 (W8# Word8#
    w)) = Char# -> Char
    C# (Int# -> Char#
    chr# (Word# -> Int#
    word2Int# (Word8# -> Word#
    word8ToWord# Word8#
    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 :: Char -> Maybe Char7
    fromChar !(C# Char#
    c#)
        | Int# -> Bool
    bool# (Char# -> Char# -> Int#
    ltChar# Char#
    c# (Int# -> Char#
    chr# Int#
    0x80#)) = Char7 -> Maybe Char7
    forall a. a -> Maybe a
    Just (Char7 -> Maybe Char7) -> Char7 -> Maybe Char7
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Char7
    Char7 (Word8 -> Char7) -> Word8 -> Char7
    forall a b. (a -> b) -> a -> b
    $ Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# (Int# -> Word#
    int2Word# (Char# -> Int#
    ord# Char#
    c#)))
        | Bool
    otherwise                       = Maybe Char7
    forall a. Maybe a
    Nothing

    -- | Try to convert 'Word8' to a 'Char7'
    --
    -- If the byte got higher bit set, then Nothing is returned.
    fromByte :: Word8 -> Maybe Char7
    fromByte :: Word8 -> Maybe Char7
    fromByte !Word8
    w
        | (Word8
    w Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0x80) Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0 = Char7 -> Maybe Char7
    forall a. a -> Maybe a
    Just (Char7 -> Maybe Char7) -> Char7 -> Maybe Char7
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Char7
    Char7 Word8
    w
        | Bool
    otherwise         = Maybe Char7
    forall a. Maybe a
    Nothing

    -- | Convert a 'Char' to a 'Char7' ignoring all higher bits
    fromCharMask :: Char -> Char7
    fromCharMask :: Char -> Char7
    fromCharMask !(C# Char#
    c#) = Word8 -> Char7
    Char7 (Word8 -> Char7) -> Word8 -> Char7
    forall a b. (a -> b) -> a -> b
    $ Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# (Word# -> Word# -> Word#
    and# (Int# -> Word#
    int2Word# (Char# -> Int#
    ord# Char#
    c#)) Word#
    0x7f##))

    -- | Convert a 'Byte' to a 'Char7' ignoring the higher bit
    fromByteMask :: Word8 -> Char7
    fromByteMask :: Word8 -> Char7
    fromByteMask !Word8
    w = Word8 -> Char7
    Char7 (Word8
    w Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0x7f)

    c7_LF :: Char7
    c7_LF :: Char7
    c7_LF = Word8 -> Char7
    Char7 Word8
    0xa

    c7_CR :: Char7
    c7_CR :: Char7
    c7_CR = Word8 -> Char7
    Char7 Word8
    0xd

    c7_minus :: Char7
    c7_minus :: Char7
    c7_minus = Word8 -> Char7
    Char7 Word8
    0x2d

    c7_a :: Char7
    c7_a :: Char7
    c7_a = Word8 -> Char7
    Char7 Word8
    0x61

    c7_A :: Char7
    c7_A :: Char7
    c7_A = Word8 -> Char7
    Char7 Word8
    0x41

    c7_z :: Char7
    c7_z :: Char7
    c7_z = Word8 -> Char7
    Char7 Word8
    0x7a

    c7_Z :: Char7
    c7_Z :: Char7
    c7_Z = Word8 -> Char7
    Char7 Word8
    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
    c7_0 = Word8 -> Char7
    Char7 Word8
    0x30
    c7_1 :: Char7
    c7_1 = Word8 -> Char7
    Char7 Word8
    0x31
    c7_2 :: Char7
    c7_2 = Word8 -> Char7
    Char7 Word8
    0x32
    c7_3 :: Char7
    c7_3 = Word8 -> Char7
    Char7 Word8
    0x33
    c7_4 :: Char7
    c7_4 = Word8 -> Char7
    Char7 Word8
    0x34
    c7_5 :: Char7
    c7_5 = Word8 -> Char7
    Char7 Word8
    0x35
    c7_6 :: Char7
    c7_6 = Word8 -> Char7
    Char7 Word8
    0x36
    c7_7 :: Char7
    c7_7 = Word8 -> Char7
    Char7 Word8
    0x37
    c7_8 :: Char7
    c7_8 = Word8 -> Char7
    Char7 Word8
    0x38
    c7_9 :: Char7
    c7_9 = Word8 -> Char7
    Char7 Word8
    0x39

    c7Lower :: Char7 -> Char7
    c7Lower :: Char7 -> Char7
    c7Lower c :: Char7
    c@(Char7 Word8
    w)
        | Char7
    c Char7 -> Char7 -> Bool
    forall a. Ord a => a -> a -> Bool
    <  Char7
    c7_A = Char7
    c
        | Char7
    c Char7 -> Char7 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char7
    c7_Z = Word8 -> Char7
    Char7 (Word8
    w Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. Word8
    0x20)
        | Bool
    otherwise = Char7
    c

    c7Upper :: Char7 -> Char7
    c7Upper :: Char7 -> Char7
    c7Upper c :: Char7
    c@(Char7 Word8
    w)
        | Char7
    c Char7 -> Char7 -> Bool
    forall a. Ord a => a -> a -> Bool
    <  Char7
    c7_a = Char7
    c
        | Char7
    c Char7 -> Char7 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char7
    c7_z = Word8 -> Char7
    Char7 (Word8
    w Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0xdf)
        | Bool
    otherwise = Char7
    c