module Text.Regex.TDFA.Pipes
( Regex
, CompOption
, ExecOption
, compile
, execute
, regexec
, ProjectChar(..)
) where
import Prelude
( Monad(..)
, Functor(..)
, String
, Either(..)
, (.)
, (++)
, Maybe(..)
, show
, Char
, fst
, tail
, map
, id
, either
)
import Text.Regex.TDFA.NewDFA.Uncons
( Uncons(..)
)
import Text.Regex.TDFA.NewDFA.Engine
( execMatch
)
import Text.Regex.Base.Impl
( polymatch
, polymatchM
)
import Text.Regex.TDFA.Common
( CompOption
, ExecOption
)
import Text.Regex.TDFA.TDFA
( patternToRegex
)
import Text.Regex.Base
( RegexLike(..)
, RegexOptions
, Extract(..)
, RegexContext(..)
, MatchArray
, matchOnce
)
import Text.Regex.TDFA
( Regex
)
import Text.Regex.TDFA.ReadRegex
( parseRegex
)
import Pipes
( (<-<)
)
import Pipes as Pipe
( next
)
import qualified Pipes.Prelude as Pipe
( take
, drop
, toListM
)
import Pipes.Core
( Producer
)
import Control.Lens
( (^?)
, over
, _Just
, _1
, _Right
, each
, firstOf
)
import Data.Foldable
( Foldable
, asum
)
import Data.Array.IArray
( (!)
, elems
, amap
)
import Control.Monad.Identity
( Identity(..)
)
class ProjectChar a where
projectChar :: a -> Char
instance ProjectChar Char where
projectChar = id
instance (ProjectChar a, ProjectChar b) =>
ProjectChar (Either a b)
where
projectChar = either projectChar projectChar
instance (ProjectChar a) => ProjectChar (Identity a) where
projectChar = projectChar . runIdentity
instance (ProjectChar a, Monad m, Foldable m, Functor m) =>
Uncons (Producer a m r)
where
uncons = over (_Just . _1) projectChar
. asum
. fmap (^? _Right)
. Pipe.next
instance (Monad m) => Extract (Producer a m ()) where
before = (<-<) . Pipe.take
after = (<-<) . Pipe.drop
empty = return ()
extract (off, len) = before len . after off
instance (ProjectChar a, Monad m, Foldable m, Functor m) =>
RegexLike Regex (Producer a m ())
where
matchOnce r p = firstOf each (matchAll r p)
matchAll r p = execMatch r 0 '\n' p
instance (ProjectChar a, Monad m, Foldable m, Functor m) =>
RegexContext Regex (Producer a m ()) (Producer a m ())
where
match = polymatch
matchM = polymatchM
compile :: (ProjectChar a, Monad m, Foldable m, Functor m) =>
CompOption
-> ExecOption
-> Producer a m ()
-> Either String Regex
compile compOpt execOpt regexp =
case parseRegex (map projectChar (asum (Pipe.toListM regexp))) of
Left err -> Left ( "parseRegex for Text.Regex.TDFA.Pipes failed: "
++ show err
)
Right pat -> Right (patternToRegex pat compOpt execOpt)
execute :: (ProjectChar a, Monad m, Foldable m, Functor m) =>
Regex -> Producer a m () -> Either a (Maybe MatchArray)
execute r p = Right (matchOnce r p)
regexec :: (ProjectChar a, Monad m, Foldable m, Functor m) =>
Regex
-> Producer a m ()
-> Either String ( Maybe ( Producer a m ()
, Producer a m ()
, Producer a m ()
, [Producer a m ()]
)
)
regexec r bs =
case matchOnceText r bs of
Nothing -> Right Nothing
Just (pre,mt,post) ->
let main = fst (mt!0)
rest = map fst (tail (elems mt))
in Right (Just (pre,main,post,rest))