module Data.CaseInsensitive.Eq
( CaseInsensitiveEq(..)
, (^==)
, (^/=)
)
where
import Data.Char
import Data.Word
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
class CaseInsensitiveEq a where
caseInsensitiveEq :: a -> a -> Bool
caseInsensitiveMatch :: [a] -> [a] -> Bool
caseInsensitiveMatch = list_eq
(^==) :: (CaseInsensitiveEq a) => a -> a -> Bool
(^==) = caseInsensitiveEq
(^/=) :: (CaseInsensitiveEq a) => a -> a -> Bool
(^/=) a = not . (^==) a
instance CaseInsensitiveEq Char where
caseInsensitiveEq = char_eq
instance (CaseInsensitiveEq a) => CaseInsensitiveEq [a] where
caseInsensitiveEq = caseInsensitiveMatch
instance CaseInsensitiveEq Word8 where
caseInsensitiveEq = char8_eq
instance CaseInsensitiveEq BS.ByteString where
caseInsensitiveEq = bs_strict_eq
instance CaseInsensitiveEq BSL.ByteString where
caseInsensitiveEq = bs_lazy_eq
instance CaseInsensitiveEq T.Text where
caseInsensitiveEq = t_strict_eq
instance CaseInsensitiveEq TL.Text where
caseInsensitiveEq = t_lazy_eq
instance (CaseInsensitiveEq a, CaseInsensitiveEq b) => CaseInsensitiveEq (a,b) where
caseInsensitiveEq (a,b) (a',b')
| caseInsensitiveEq a a' = True
| otherwise = caseInsensitiveEq b b'
instance (CaseInsensitiveEq a, CaseInsensitiveEq b, CaseInsensitiveEq c) => CaseInsensitiveEq (a,b,c) where
caseInsensitiveEq (a,b,c) (a',b',c')
| caseInsensitiveEq a a' = True
| otherwise = caseInsensitiveEq (b,c) (b',c')
instance (CaseInsensitiveEq a, CaseInsensitiveEq b, CaseInsensitiveEq c, CaseInsensitiveEq d) => CaseInsensitiveEq (a,b,c,d) where
caseInsensitiveEq (a,b,c,d) (a',b',c',d')
| caseInsensitiveEq a a' = True
| otherwise = caseInsensitiveEq (b,c,d) (b',c',d')
char_eq :: Char -> Char -> Bool
char_eq a b
| a == b = True
| a == toLower b = True
| b == toLower a = True
| a == toUpper b = True
| b == toUpper a = True
| otherwise = False
char8_eq :: Word8 -> Word8 -> Bool
char8_eq a b
| a == b = True
| a < 65 || b < 65 = False
| a < 91 && b < 123 = a == b 32
| b < 91 && a < 123 = b == a 32
| a < 192 || b < 192 = False
| a == 215 || b == 215 = False
| a < 223 = a == b 32
| b < 223 = a 32 == b
| otherwise = False
bs_strict_eq :: BS.ByteString -> BS.ByteString -> Bool
bs_strict_eq a b
| BS.length a /= BS.length b = False
| otherwise = continue_bs_strict_eq a b
continue_bs_strict_eq a b
| BS.null a = True
| char8_eq (BS.head a) (BS.head b) = continue_bs_strict_eq (BS.tail a) (BS.tail b)
| otherwise = False
list_eq :: (CaseInsensitiveEq a) => [a] -> [a] -> Bool
list_eq a b
| null a || null b = null a && null b
| caseInsensitiveEq (head a) (head b) = list_eq (tail a) (tail b)
| otherwise = False
bs_lazy_eq :: BSL.ByteString -> BSL.ByteString -> Bool
bs_lazy_eq a b
| BSL.null a || BSL.null b = BSL.null a && BSL.null b
| char8_eq (BSL.head a) (BSL.head b) = bs_lazy_eq (BSL.tail a) (BSL.tail b)
| otherwise = False
t_strict_eq :: T.Text -> T.Text -> Bool
t_strict_eq a b
| T.null a || T.null b = T.null a && T.null b
| char_eq (T.head a) (T.head b) = t_strict_eq (T.tail a) (T.tail b)
| otherwise = False
t_lazy_eq :: TL.Text -> TL.Text -> Bool
t_lazy_eq a b
| TL.null a || TL.null b = TL.null a && TL.null b
| char_eq (TL.head a) (TL.head b) = t_lazy_eq (TL.tail a) (TL.tail b)
| otherwise = False