{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
{-|
Module      : Htcc.CRules.Char
Description : Characters rules of C language
Copyright   : (c) roki, 2019
License     : MIT
Maintainer  : falgon53@yahoo.co.jp
Stability   : experimental
Portability : POSIX

Characters rules of C language
-}
module Htcc.CRules.Char (
    -- * The definition of characters rules
    isValidChar,
    -- * The helper class for some string types
    GenericStr (..)
) where

import           Data.Char  (isAlpha, isDigit)
import qualified Data.Text  as T

import           Htcc.Utils (lor, sop, sopText)

-- | Return `True` if it is a valid character.
isValidChar :: Char -> Bool
isValidChar :: Char -> Bool
isValidChar = [Char -> Bool] -> Char -> Bool
forall a. [a -> Bool] -> a -> Bool
lor [Char -> Bool
isAlpha, (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='_'), Char -> Bool
isDigit]

-- | Class of type that can be treated as a set of characters.
class GenericStr a where
    -- | Returns `True` if the set of characters is
    -- a valid C language characters.
    isValid :: a -> Bool

instance GenericStr String where
    isValid :: String -> Bool
isValid [] = Bool
False
    isValid (x :: Char
x:xs :: String
xs) = [Char -> Bool
isAlpha, (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='_')] [Char -> Bool] -> Char -> Bool
forall a. [a -> Bool] -> a -> Bool
`lor` Char
x Bool -> Bool -> Bool
&& [Char -> Bool
isAlpha, (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='_'), Char -> Bool
isDigit] [Char -> Bool] -> String -> Bool
forall a. [a -> Bool] -> [a] -> Bool
`sop` String
xs

instance GenericStr T.Text where
    isValid :: Text -> Bool
isValid xs :: Text
xs
        | Text -> Bool
T.null Text
xs = Bool
False
        | Bool
otherwise = [Char -> Bool
isAlpha, (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='_')] [Char -> Bool] -> Char -> Bool
forall a. [a -> Bool] -> a -> Bool
`lor` Text -> Char
T.head Text
xs Bool -> Bool -> Bool
&& [Char -> Bool
isAlpha, (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='_'), Char -> Bool
isDigit] [Char -> Bool] -> Text -> Bool
`sopText` Text -> Text
T.tail Text
xs