module Hpack.Haskell (
  isModule
, isModuleNameComponent
, isQualifiedIdentifier
, isIdentifier
) where

import           Data.Char

isModule :: [String] -> Bool
isModule :: [String] -> Bool
isModule [String]
name = (Bool -> Bool
not (Bool -> Bool) -> ([String] -> Bool) -> [String] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) [String]
name Bool -> Bool -> Bool
&& (String -> Bool) -> [String] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all String -> Bool
isModuleNameComponent [String]
name

isModuleNameComponent :: String -> Bool
isModuleNameComponent :: String -> Bool
isModuleNameComponent String
name = case String
name of
  Char
x : String
xs -> Char -> Bool
isUpper Char
x Bool -> Bool -> Bool
&& (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isIdChar String
xs
  String
_ -> Bool
False

isQualifiedIdentifier :: [String] -> Bool
isQualifiedIdentifier :: [String] -> Bool
isQualifiedIdentifier [String]
name = case [String] -> [String]
forall a. [a] -> [a]
reverse [String]
name of
  String
x : [String]
xs  -> String -> Bool
isIdentifier String
x Bool -> Bool -> Bool
&& [String] -> Bool
isModule [String]
xs
  [String]
_ -> Bool
False

isIdentifier :: String -> Bool
isIdentifier :: String -> Bool
isIdentifier String
name = case String
name of
  Char
x : String
xs -> Char -> Bool
isLower Char
x Bool -> Bool -> Bool
&& (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isIdChar String
xs Bool -> Bool -> Bool
&& String
name String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [String]
reserved
  String
_ -> Bool
False

reserved :: [String]
reserved :: [String]
reserved = [
    String
"case"
  , String
"class"
  , String
"data"
  , String
"default"
  , String
"deriving"
  , String
"do"
  , String
"else"
  , String
"foreign"
  , String
"if"
  , String
"import"
  , String
"in"
  , String
"infix"
  , String
"infixl"
  , String
"infixr"
  , String
"instance"
  , String
"let"
  , String
"module"
  , String
"newtype"
  , String
"of"
  , String
"then"
  , String
"type"
  , String
"where"
  , String
"_"
  ]

isIdChar :: Char -> Bool
isIdChar :: Char -> Bool
isIdChar Char
c = Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\''