-- |The basic use of this module is to first parse a regular expression string (like @"[mn]{2,5}[eio]+s?"@) into an 'Anagrex' with 'makeAnagrex'.
-- This can then be used to efficiently test candidate strings with 'testAnagrex'.
module Text.Regex.Anagram
  ( Anagrex
  , makeAnagrex
  , makeAnagrexCI
  , testAnagrex
  , testAnagrexCI
  ) where

import qualified Data.CaseInsensitive as CI
import qualified Data.CaseInsensitive.Unsafe as CI

import Text.Regex.Anagram.Parse
import Text.Regex.Anagram.Compile
import Text.Regex.Anagram.Test

-- |Build a case-insensitive version of a pattern.
-- This is more efficient than 'CI.mk' since it avoids the complication of the case-sensitive version as well.
-- Uses 'CI.unsafeMk' so the 'CI.original' version is also case-folded.
makeAnagrexCI :: String -> Either String (CI.CI Anagrex)
makeAnagrexCI :: String -> Either String (CI Anagrex)
makeAnagrexCI = (AnaPattern -> CI Anagrex)
-> Either String AnaPattern -> Either String (CI Anagrex)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Anagrex -> CI Anagrex
forall s. FoldCase s => s -> CI s
CI.unsafeMk (Anagrex -> CI Anagrex)
-> (AnaPattern -> Anagrex) -> AnaPattern -> CI Anagrex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnaPattern -> Anagrex
compileAnagrex (AnaPattern -> Anagrex)
-> (AnaPattern -> AnaPattern) -> AnaPattern -> Anagrex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnaPattern -> AnaPattern
forall s. FoldCase s => s -> s
CI.foldCase) (Either String AnaPattern -> Either String (CI Anagrex))
-> (String -> Either String AnaPattern)
-> String
-> Either String (CI Anagrex)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String AnaPattern
parseAnaPattern

-- |Test a case-insensitive pattern against a case-insensitive string.  You can also directly use 'Data.CaseInsensitive.foldCase' on both the pattern and the string to test.
testAnagrexCI :: CI.CI Anagrex -> CI.CI String -> Bool
testAnagrexCI :: CI Anagrex -> CI String -> Bool
testAnagrexCI CI Anagrex
p = Anagrex -> String -> Bool
testAnagrex (CI Anagrex -> Anagrex
forall s. CI s -> s
CI.foldedCase CI Anagrex
p) (String -> Bool) -> (CI String -> String) -> CI String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CI String -> String
forall s. CI s -> s
CI.foldedCase