{-| Match a specific string in a case-insensitive way

    This only handles ASCII strings

>>> match (asciiCI "abc") "ABC"
["ABC"]
-}
asciiCI :: Text -> Pattern Text
asciiCI before' = Pattern (do
    txt <- get
    let (before, after) = Text.splitAt (Text.length before') txt
    guard (lowerChars before == lowerChars before')
    put after
    return before )
  where
    lowerChars = Text.map lowerChar
    lowerChar c | 'A' <= c && c <= 'Z' = chr (ord c + ord 'a' - ord 'A')
                | otherwise            = c

{-| Match any one of the given characters

>>> match (oneOf "1a") "1"
"1"
>>> match (oneOf "2a") "1"
""
-}
asciiCI :: Text -> Pattern Text
asciiCI before' = Pattern (do
    txt <- get
    let (before, after) = Text.splitAt (Text.length before') txt
    guard (lowerChars before == lowerChars before')
    put after
    return before )
  where
    lowerChars = Text.map lowerChar
    lowerChar c | 'A' <= c && c <= 'Z' = chr (ord c + ord 'a' - ord 'A')
                | otherwise            = c

{-| Match any one of the given characters

>>> match (oneOf "1a") "1"
"1"
>>> match (oneOf "2a") "1"
""
-}
asciiCI before' = Pattern (do
    txt <- get
    let (before, after) = Text.splitAt (Text.length before') txt
    guard (lowerChars before == lowerChars before')
    put after
    return before )
  where
    lowerChars = Text.map lowerChar
    lowerChar c | 'A' <= c && c <= 'Z' = chr (ord c + ord 'a' - ord 'A')
                | otherwise            = c

{-| Match any one of the given characters

>>> match (oneOf "1a") "1"
"1"
>>> match (oneOf "2a") "1"
""
-}