    {-|
    Module      :  Text.Regex.TDFA.Text
    Copyright   :  Chris Kuklewicz 2007-2009, shelarcy 2012
    License     :  BSD-style (see the file LICENSE)

    This modules provides 'RegexMaker' and 'RegexLike' instances for using
    'Text' with the TDFA backend ("Text.Regex.TDFA.NewDFA.Engine" and
    "Text.Regex.TDFA.NewDFA.Tester").

    This exports instances of the high level API and the medium level
    API of 'compile','execute', and 'regexec'.

    @since 1.3.1
    -}
    module Text.Regex.TDFA.Text(
      Regex
     ,CompOption
     ,ExecOption
     ,compile
     ,execute
     ,regexec
     ) where

    import Data.Array((!),elems)
    import qualified Data.Text as T(Text,unpack)

    import Text.Regex.Base(RegexLike(..),RegexMaker(..),Extract(..),MatchArray,RegexContext(..))
    import Text.Regex.Base.Impl(polymatch,polymatchM)
    import Text.Regex.TDFA.ReadRegex(parseRegex)
    import Text.Regex.TDFA.String() -- piggyback on RegexMaker for String
    import Text.Regex.TDFA.TDFA(patternToRegex)
    import Text.Regex.TDFA.Common(Regex(..),CompOption,ExecOption(captureGroups),Position)

    import Data.Maybe(listToMaybe)
    import Text.Regex.TDFA.NewDFA.Uncons(Uncons)
    import qualified Text.Regex.TDFA.NewDFA.Engine as Engine(execMatch)
    import qualified Text.Regex.TDFA.NewDFA.Tester as Tester(matchTest)

    -- | @since 1.3.1
    instance RegexContext Regex T.Text T.Text where
      match :: Regex -> Text -> Text
    match = Regex -> Text -> Text
    forall a b. RegexLike a b => a -> b -> b
    polymatch
      matchM :: forall (m :: * -> *). MonadFail m => Regex -> Text -> m Text
    matchM = Regex -> Text -> m Text
    forall a b (m :: * -> *).
    (RegexLike a b, MonadFail m) =>
    a -> b -> m b
    polymatchM

    -- | @since 1.3.1
    instance RegexMaker Regex CompOption ExecOption T.Text where
      makeRegexOptsM :: forall (m :: * -> *).
    MonadFail m =>
    CompOption -> ExecOption -> Text -> m Regex
    makeRegexOptsM CompOption
    c ExecOption
    e Text
    source = CompOption -> ExecOption -> String -> m Regex
    forall regex compOpt execOpt source (m :: * -> *).
    (RegexMaker regex compOpt execOpt source, MonadFail m) =>
    compOpt -> execOpt -> source -> m regex
    forall (m :: * -> *).
    MonadFail m =>
    CompOption -> ExecOption -> String -> m Regex
    makeRegexOptsM CompOption
    c ExecOption
    e (Text -> String
    T.unpack Text
    source)

    -- | @since 1.3.1
    {-# SPECIALIZE execMatch :: Regex -> Position -> Char -> T.Text -> [MatchArray] #-}
    execMatch :: Uncons text => Regex -> Position -> Char -> text -> [MatchArray]
    execMatch :: forall text.
    Uncons text =>
    Regex -> Position -> Char -> text -> [MatchArray]
    execMatch = Regex -> Position -> Char -> text -> [MatchArray]
    forall text.
    Uncons text =>
    Regex -> Position -> Char -> text -> [MatchArray]
    Engine.execMatch

    -- | @since 1.3.1
    {-# SPECIALIZE myMatchTest :: Regex -> T.Text -> Bool #-}
    myMatchTest :: Uncons text => Regex -> text -> Bool
    myMatchTest :: forall text. Uncons text => Regex -> text -> Bool
    myMatchTest = Regex -> text -> Bool
    forall text. Uncons text => Regex -> text -> Bool
    Tester.matchTest

    -- | @since 1.3.1
    instance RegexLike Regex T.Text where
      matchOnce :: Regex -> Text -> Maybe MatchArray
    matchOnce Regex
    r Text
    s = [MatchArray] -> Maybe MatchArray
    forall a. [a] -> Maybe a
    listToMaybe (Regex -> Text -> [MatchArray]
    forall regex source.
    RegexLike regex source =>
    regex -> source -> [MatchArray]
    matchAll Regex
    r Text
    s)
      matchAll :: Regex -> Text -> [MatchArray]
    matchAll Regex
    r Text
    s = Regex -> Position -> Char -> Text -> [MatchArray]
    forall text.
    Uncons text =>
    Regex -> Position -> Char -> text -> [MatchArray]
    execMatch Regex
    r Position
    0 Char
    '\n' Text
    s
      matchCount :: Regex -> Text -> Position
    matchCount Regex
    r Text
    s = [MatchArray] -> Position
    forall a. [a] -> Position
    forall (t :: * -> *) a. Foldable t => t a -> Position
    length (Regex -> Text -> [MatchArray]
    forall regex source.
    RegexLike regex source =>
    regex -> source -> [MatchArray]
    matchAll Regex
    r' Text
    s)
        where r' :: Regex
    r' = Regex
    r { regex_execOptions = (regex_execOptions r) {captureGroups = False} }
      matchTest :: Regex -> Text -> Bool
    matchTest = Regex -> Text -> Bool
    forall text. Uncons text => Regex -> text -> Bool
    myMatchTest
      matchOnceText :: Regex -> Text -> Maybe (Text, MatchText Text, Text)
    matchOnceText Regex
    regex Text
    source =
        (MatchArray -> (Text, MatchText Text, Text))
    -> Maybe MatchArray -> Maybe (Text, MatchText Text, Text)
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\MatchArray
    ma -> let (Position
    o,Position
    l) = MatchArray
    maMatchArray -> Position -> (Position, Position)
    forall i e. Ix i => Array i e -> i -> e
    !Position
    0
                     in (Position -> Text -> Text
    forall source. Extract source => Position -> source -> source
    before Position
    o Text
    source
                        ,((Position, Position) -> (Text, (Position, Position)))
    -> MatchArray -> MatchText Text
    forall a b. (a -> b) -> Array Position a -> Array Position b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(Position, Position)
    ol -> ((Position, Position) -> Text -> Text
    forall source.
    Extract source =>
    (Position, Position) -> source -> source
    extract (Position, Position)
    ol Text
    source,(Position, Position)
    ol)) MatchArray
    ma
                        ,Position -> Text -> Text
    forall source. Extract source => Position -> source -> source
    after (Position
    oPosition -> Position -> Position
    forall a. Num a => a -> a -> a
    +Position
    l) Text
    source))
             (Regex -> Text -> Maybe MatchArray
    forall regex source.
    RegexLike regex source =>
    regex -> source -> Maybe MatchArray
    matchOnce Regex
    regex Text
    source)
      matchAllText :: Regex -> Text -> [MatchText Text]
    matchAllText Regex
    regex Text
    source =
        (MatchArray -> MatchText Text) -> [MatchArray] -> [MatchText Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (((Position, Position) -> (Text, (Position, Position)))
    -> MatchArray -> MatchText Text
    forall a b. (a -> b) -> Array Position a -> Array Position b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(Position, Position)
    ol -> ((Position, Position) -> Text -> Text
    forall source.
    Extract source =>
    (Position, Position) -> source -> source
    extract (Position, Position)
    ol Text
    source,(Position, Position)
    ol)))
            (Regex -> Text -> [MatchArray]
    forall regex source.
    RegexLike regex source =>
    regex -> source -> [MatchArray]
    matchAll Regex
    regex Text
    source)

    -- | @since 1.3.1
    compile :: CompOption -- ^ Flags (summed together)
            -> ExecOption -- ^ Flags (summed together)
            -> T.Text -- ^ The regular expression to compile
            -> Either String Regex -- ^ Returns: the compiled regular expression
    compile :: CompOption -> ExecOption -> Text -> Either String Regex
    compile CompOption
    compOpt ExecOption
    execOpt Text
    txt =
      case String -> Either ParseError (Pattern, (Position, DoPa))
    parseRegex (Text -> String
    T.unpack Text
    txt) of
        Left ParseError
    err -> String -> Either String Regex
    forall a b. a -> Either a b
    Left (String
    "parseRegex for Text.Regex.TDFA.Text failed:"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ParseError -> String
    forall a. Show a => a -> String
    show ParseError
    err)
        Right (Pattern, (Position, DoPa))
    pattern -> Regex -> Either String Regex
    forall a b. b -> Either a b
    Right ((Pattern, (Position, DoPa)) -> CompOption -> ExecOption -> Regex
    patternToRegex (Pattern, (Position, DoPa))
    pattern CompOption
    compOpt ExecOption
    execOpt)

    -- | @since 1.3.1
    execute :: Regex  -- ^ Compiled regular expression
            -> T.Text -- ^ Text to match against
            -> Either String (Maybe MatchArray)
    execute :: Regex -> Text -> Either String (Maybe MatchArray)
    execute Regex
    r Text
    txt = Maybe MatchArray -> Either String (Maybe MatchArray)
    forall a b. b -> Either a b
    Right (Regex -> Text -> Maybe MatchArray
    forall regex source.
    RegexLike regex source =>
    regex -> source -> Maybe MatchArray
    matchOnce Regex
    r Text
    txt)

    -- | @since 1.3.1
    regexec :: Regex  -- ^ Compiled regular expression
            -> T.Text -- ^ Text to match against
            -> Either String (Maybe (T.Text, T.Text, T.Text, [T.Text]))
    regexec :: Regex -> Text -> Either String (Maybe (Text, Text, Text, [Text]))
    regexec Regex
    r Text
    txt = Maybe (Text, Text, Text, [Text])
    -> Either String (Maybe (Text, Text, Text, [Text]))
    forall a b. b -> Either a b
    Right (Maybe (Text, Text, Text, [Text])
     -> Either String (Maybe (Text, Text, Text, [Text])))
    -> Maybe (Text, Text, Text, [Text])
    -> Either String (Maybe (Text, Text, Text, [Text]))
    forall a b. (a -> b) -> a -> b
    $
      case Regex -> Text -> Maybe (Text, MatchText Text, Text)
    forall regex source.
    RegexLike regex source =>
    regex -> source -> Maybe (source, MatchText source, source)
    matchOnceText Regex
    r Text
    txt of
        Just (Text
    pre, MatchText Text
    mt, Text
    post) | Text
    main:[Text]
    rest <- ((Text, (Position, Position)) -> Text)
    -> [(Text, (Position, Position))] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (Text, (Position, Position)) -> Text
    forall a b. (a, b) -> a
    fst (MatchText Text -> [(Text, (Position, Position))]
    forall i e. Array i e -> [e]
    elems MatchText Text
    mt)
          -> (Text, Text, Text, [Text]) -> Maybe (Text, Text, Text, [Text])
    forall a. a -> Maybe a
    Just (Text
    pre, Text
    main, Text
    post, [Text]
    rest)
        Maybe (Text, MatchText Text, Text)
    _ -> Maybe (Text, Text, Text, [Text])
    forall a. Maybe a
    Nothing