{- | see "Text.Regex.Base.RegexLike" 

    see "Text.Regex.Do.Match.Latin" for API changes

    __'toByteString'__ converts String to utf8 'ByteString'     -}
module Text.Regex.Do.Match.Utf8
    (MatchOnce(..),
    MatchAll(..),
    R.extract   -- | 'extract' is reexport from "Text.Regex.Base.RegexLike"
    ) where

import Data.Tagged
import Data.ByteString
import qualified Text.Regex.Base.RegexLike as R hiding (makeRegex)
import Text.Regex.Do.Type.Do
import Text.Regex.Do.Match.Matchf as F
import Text.Regex.PCRE.Wrap()
import Text.Regex.Do.Match.Regex as T
import Text.Regex.Do.Match.Option
import Text.Regex.Do.Type.Reexport as Re
import Text.Regex.Do.Type.Convert
import Text.Regex.Do.Type.Internal


{- | * pattern:  'String', 'ByteString', 'Regex'      compile 'Re.Regex' with 'Utf8' opt

        String | ByteString pattern may contains regex
    
    * body:  'String', 'ByteString'
    * out: out | E out

        * 'Bool'  :  test if regex matches
        * ['String'] 
        * ['ByteString']
        * ['PosLen']    -}
class MatchOnce pattern body out where
    (~?)::pattern -> body -> out


{- | * pattern:  'String', 'ByteString', 'Re.Regex'      compile 'Re.Regex' with 'Utf8' opt
    * body:  'String', 'ByteString'
    * out:

        * [['String']]
        * [['ByteString']]
        * [['PosLen']]      -}
class MatchAll pattern body out where
    (~*)::pattern -> body -> out


{- | b: 'String', 'ByteString' 

    always succeeds               

==== precompiled regex as pattern

@    
let Right rx1 = makeRegexOpt (toByteString "左") [Utf8] []      --  add options as needed
    m1 = rx1 ~? (toByteString "100メートル左折後、左")::[ByteString]
m1 `shouldBe` [toByteString "左"]       
@ -}

instance R.RegexLike Re.Regex b => 
        MatchOnce Re.Regex b [b] where
    ~? :: Regex -> b -> [b]
(~?) pat0 :: Regex
pat0 body0 :: b
body0 = Regex -> Tagged Once b -> [b]
forall b. (R_ b, Extract b) => Regex -> Tagged Once b -> [b]
once Regex
pat0 (b -> Tagged Once b
forall k (s :: k) b. b -> Tagged s b
Tagged b
body0)


instance R.RegexLike Re.Regex b => 
        MatchOnce Re.Regex b Bool where
    ~? :: Regex -> b -> Bool
(~?) pat0 :: Regex
pat0 body0 :: b
body0 = Regex -> Tagged Test b -> Bool
forall b. (R_ b, Extract b) => Regex -> Tagged Test b -> Bool
test Regex
pat0 (b -> Tagged Test b
forall k (s :: k) b. b -> Tagged s b
Tagged b
body0)
{- ^ b: 'String', 'ByteString' 

always succeeds     -}


instance R.RegexLike Re.Regex b =>
        MatchOnce Re.Regex b [PosLen] where
    ~? :: Regex -> b -> [PosLen]
(~?) pat0 :: Regex
pat0 body0 :: b
body0 = [PosLen]
r1
        where tagOne::b -> Tagged Once b
              tagOne :: b -> Tagged Once b
tagOne = b -> Tagged Once b
forall k (s :: k) b. b -> Tagged s b
Tagged 
              Right r1 :: [PosLen]
r1 = E Regex -> Tagged Once b -> P (Tagged Once)
forall (hint :: * -> *) b.
(Matchf hint, R_ b) =>
E Regex -> hint b -> P hint
poslen_ (Regex -> E Regex
forall a b. b -> Either a b
Right Regex
pat0) (b -> Tagged Once b
tagOne b
body0)
{- ^ b: 'String', 'ByteString' 

always succeeds     -}


instance MatchOnce String String (E [String]) where
    ~? :: String -> String -> E [String]
(~?) pat0 :: String
pat0 body0 :: String
body0 = String
-> Tagged Once String
-> (Regex -> Tagged Once ByteString -> [ByteString])
-> E [String]
forall a out' out (hint :: * -> *).
(WithRegex a out' out, Regex a, RegexLike Regex a, Functor hint) =>
a -> hint a -> (Regex -> hint ByteString -> out') -> E out
withRegex String
pat0 (String -> Tagged Once String
forall b. b -> Tagged Once b
tagB String
body0) Regex -> Tagged Once ByteString -> [ByteString]
forall b. (R_ b, Extract b) => Regex -> Tagged Once b -> [b]
once
        where tagB::b -> Tagged Once b
              tagB :: b -> Tagged Once b
tagB = b -> Tagged Once b
forall k (s :: k) b. b -> Tagged s b
Tagged
{- ^ >>> ("^熱"::String) ~? ("熱い午後"::String)::E [String]

Right \["熱"]     -}


instance MatchOnce ByteString ByteString (E [ByteString]) where
    ~? :: ByteString -> ByteString -> E [ByteString]
(~?) pat0 :: ByteString
pat0 body0 :: ByteString
body0 = ByteString
-> Tagged Once ByteString
-> (Regex -> Tagged Once ByteString -> [ByteString])
-> E [ByteString]
forall a out' out (hint :: * -> *).
(WithRegex a out' out, Regex a, RegexLike Regex a, Functor hint) =>
a -> hint a -> (Regex -> hint ByteString -> out') -> E out
withRegex ByteString
pat0 (ByteString -> Tagged Once ByteString
forall b. b -> Tagged Once b
tagB ByteString
body0) Regex -> Tagged Once ByteString -> [ByteString]
forall b. (R_ b, Extract b) => Regex -> Tagged Once b -> [b]
once
        where tagB::b -> Tagged Once b
              tagB :: b -> Tagged Once b
tagB = b -> Tagged Once b
forall k (s :: k) b. b -> Tagged s b
Tagged


instance MatchOnce String String (E Bool) where
    ~? :: String -> String -> E Bool
(~?) pat0 :: String
pat0 body0 :: String
body0 = String
-> Tagged Test String
-> (Regex -> Tagged Test ByteString -> Bool)
-> E Bool
forall a out' out (hint :: * -> *).
(WithRegex a out' out, Regex a, RegexLike Regex a, Functor hint) =>
a -> hint a -> (Regex -> hint ByteString -> out') -> E out
withRegex String
pat0 (String -> Tagged Test String
forall b. b -> Tagged Test b
tagB String
body0) Regex -> Tagged Test ByteString -> Bool
forall b. (R_ b, Extract b) => Regex -> Tagged Test b -> Bool
test
        where tagB::b -> Tagged Test b
              tagB :: b -> Tagged Test b
tagB = b -> Tagged Test b
forall k (s :: k) b. b -> Tagged s b
Tagged
{- ^ test

>>>  ("в"::String) ~? ("тихо в лесу"::String)::E Bool

Right True        -}

instance MatchOnce ByteString ByteString (E Bool) where
    ~? :: ByteString -> ByteString -> E Bool
(~?) pat0 :: ByteString
pat0 body0 :: ByteString
body0 = ByteString
-> Tagged Test ByteString
-> (Regex -> Tagged Test ByteString -> Bool)
-> E Bool
forall a out' out (hint :: * -> *).
(WithRegex a out' out, Regex a, RegexLike Regex a, Functor hint) =>
a -> hint a -> (Regex -> hint ByteString -> out') -> E out
withRegex ByteString
pat0 (ByteString -> Tagged Test ByteString
forall b. b -> Tagged Test b
tagB ByteString
body0) Regex -> Tagged Test ByteString -> Bool
forall b. (R_ b, Extract b) => Regex -> Tagged Test b -> Bool
test
        where tagB::b -> Tagged Test b
              tagB :: b -> Tagged Test b
tagB = b -> Tagged Test b
forall k (s :: k) b. b -> Tagged s b
Tagged


instance MatchOnce ByteString ByteString (E [PosLen]) where
    ~? :: ByteString -> ByteString -> Either String [PosLen]
(~?) pat0 :: ByteString
pat0 body0 :: ByteString
body0 = ByteString
-> Tagged Once ByteString
-> (E Regex -> Tagged Once ByteString -> P (Tagged Once))
-> P (Tagged Once)
forall a (hint :: * -> *) b.
(Regex a, Matchf hint) =>
a -> hint b -> (E Regex -> hint b -> P hint) -> P hint
withRegex' ByteString
pat0 (ByteString -> Tagged Once ByteString
forall b. b -> Tagged Once b
tagOne ByteString
body0) E Regex -> Tagged Once ByteString -> P (Tagged Once)
forall (hint :: * -> *) b.
(Matchf hint, R_ b) =>
E Regex -> hint b -> P hint
poslen_
      where tagOne::b -> Tagged Once b
            tagOne :: b -> Tagged Once b
tagOne = b -> Tagged Once b
forall k (s :: k) b. b -> Tagged s b
Tagged


instance MatchOnce String String (E [PosLen]) where
    ~? :: String -> String -> Either String [PosLen]
(~?) pat0 :: String
pat0 body0 :: String
body0 = String
-> Tagged Once String
-> (E Regex -> Tagged Once String -> P (Tagged Once))
-> P (Tagged Once)
forall a (hint :: * -> *) b.
(Regex a, Matchf hint) =>
a -> hint b -> (E Regex -> hint b -> P hint) -> P hint
withRegex' String
pat0 (String -> Tagged Once String
forall b. b -> Tagged Once b
tagOne String
body0) E Regex -> Tagged Once String -> P (Tagged Once)
forall (hint :: * -> *) b.
(Matchf hint, R_ b) =>
E Regex -> hint b -> P hint
poslen_
      where tagOne::b -> Tagged Once b
            tagOne :: b -> Tagged Once b
tagOne = b -> Tagged Once b
forall k (s :: k) b. b -> Tagged s b
Tagged


instance R.RegexLike Re.Regex b =>
        MatchAll Re.Regex b [[b]] where
    ~* :: Regex -> b -> [[b]]
(~*) pat0 :: Regex
pat0 body0 :: b
body0 = Regex -> Tagged All b -> [[b]]
forall b. (R_ b, Extract b) => Regex -> Tagged All b -> [[b]]
F.all Regex
pat0 (b -> Tagged All b
forall k (s :: k) b. b -> Tagged s b
Tagged b
body0)
{- ^ b: 'String', 'ByteString' 

always succeeds     -}



instance MatchAll ByteString ByteString (E [[ByteString]]) where
    ~* :: ByteString -> ByteString -> E [[ByteString]]
(~*) pat0 :: ByteString
pat0 body0 :: ByteString
body0 = ByteString
-> Tagged All ByteString
-> (Regex -> Tagged All ByteString -> [[ByteString]])
-> E [[ByteString]]
forall a out' out (hint :: * -> *).
(WithRegex a out' out, Regex a, RegexLike Regex a, Functor hint) =>
a -> hint a -> (Regex -> hint ByteString -> out') -> E out
withRegex ByteString
pat0 (ByteString -> Tagged All ByteString
forall k (s :: k) b. b -> Tagged s b
Tagged ByteString
body0) Regex -> Tagged All ByteString -> [[ByteString]]
forall b. (R_ b, Extract b) => Regex -> Tagged All b -> [[b]]
F.all


instance MatchAll String String (E [[String]]) where
    ~* :: String -> String -> E [[String]]
(~*) pat0 :: String
pat0 body0 :: String
body0 = String
-> Tagged All String
-> (Regex -> Tagged All ByteString -> [[ByteString]])
-> E [[String]]
forall a out' out (hint :: * -> *).
(WithRegex a out' out, Regex a, RegexLike Regex a, Functor hint) =>
a -> hint a -> (Regex -> hint ByteString -> out') -> E out
withRegex String
pat0 (String -> Tagged All String
forall k (s :: k) b. b -> Tagged s b
Tagged String
body0) Regex -> Tagged All ByteString -> [[ByteString]]
forall b. (R_ b, Extract b) => Regex -> Tagged All b -> [[b]]
F.all
{- ^  >>> ("лес"::String) ~* ("Залесью, залесью…"::String)::E [[String]]

Right \[["лес"],["лес"]]        -}


instance R.RegexLike Re.Regex b =>
        MatchAll Re.Regex b [[PosLen]] where
    ~* :: Regex -> b -> [[PosLen]]
(~*) pat0 :: Regex
pat0 body0 :: b
body0 = [[PosLen]]
r1
        where tagOne::b -> Tagged All b
              tagOne :: b -> Tagged All b
tagOne = b -> Tagged All b
forall k (s :: k) b. b -> Tagged s b
Tagged
              Right r1 :: [[PosLen]]
r1 = E Regex -> Tagged All b -> P (Tagged All)
forall (hint :: * -> *) b.
(Matchf hint, R_ b) =>
E Regex -> hint b -> P hint
poslen_ (Regex -> E Regex
forall a b. b -> Either a b
Right Regex
pat0) (b -> Tagged All b
tagOne b
body0)
{- ^ b: 'String', 'ByteString' 

always succeeds     -}



instance MatchAll String String (E [[PosLen]]) where
    ~* :: String -> String -> Either String [[PosLen]]
(~*) pat0 :: String
pat0 body0 :: String
body0 = String
-> Tagged All String
-> (E Regex -> Tagged All String -> P (Tagged All))
-> P (Tagged All)
forall a (hint :: * -> *) b.
(Regex a, Matchf hint) =>
a -> hint b -> (E Regex -> hint b -> P hint) -> P hint
withRegex' String
pat0 (String -> Tagged All String
forall b. b -> Tagged All b
tagAll String
body0) E Regex -> Tagged All String -> P (Tagged All)
forall (hint :: * -> *) b.
(Matchf hint, R_ b) =>
E Regex -> hint b -> P hint
poslen_
      where tagAll::b -> Tagged All b
            tagAll :: b -> Tagged All b
tagAll = b -> Tagged All b
forall k (s :: k) b. b -> Tagged s b
Tagged


instance MatchAll ByteString ByteString (E [[PosLen]]) where
    ~* :: ByteString -> ByteString -> Either String [[PosLen]]
(~*) pat0 :: ByteString
pat0 body0 :: ByteString
body0 = ByteString
-> Tagged All ByteString
-> (E Regex -> Tagged All ByteString -> P (Tagged All))
-> P (Tagged All)
forall a (hint :: * -> *) b.
(Regex a, Matchf hint) =>
a -> hint b -> (E Regex -> hint b -> P hint) -> P hint
withRegex' ByteString
pat0 (ByteString -> Tagged All ByteString
forall b. b -> Tagged All b
tagAll ByteString
body0) E Regex -> Tagged All ByteString -> P (Tagged All)
forall (hint :: * -> *) b.
(Matchf hint, R_ b) =>
E Regex -> hint b -> P hint
poslen_
      where tagAll::b -> Tagged All b
            tagAll :: b -> Tagged All b
tagAll = b -> Tagged All b
forall k (s :: k) b. b -> Tagged s b
Tagged



class WithRegex a out' out where
    withRegex::(T.Regex a, R.RegexLike Re.Regex a, Functor hint) =>
        a ->        --  pattern 
        hint a ->   --  body
        (Re.Regex -> hint ByteString -> out') ->
            E out


instance WithRegex ByteString out out where
    withRegex :: ByteString
-> hint ByteString -> (Regex -> hint ByteString -> out) -> E out
withRegex p0 :: ByteString
p0 b0 :: hint ByteString
b0 fn0 :: Regex -> hint ByteString -> out
fn0 = ByteString -> [Comp] -> [Exec] -> E Regex
forall a. Regex a => a -> [Comp] -> [Exec] -> E Regex
makeRegexOpt ByteString
p0 [Comp
Utf8] [] E Regex -> (Regex -> E out) -> E out
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \p1 :: Regex
p1 ->
            out -> E out
forall a b. b -> Either a b
Right (out -> E out) -> out -> E out
forall a b. (a -> b) -> a -> b
$ Regex -> hint ByteString -> out
fn0 Regex
p1 hint ByteString
b0


instance WithRegex String [ByteString] [String] where
    withRegex :: String
-> hint String
-> (Regex -> hint ByteString -> [ByteString])
-> E [String]
withRegex p0 :: String
p0 b0 :: hint String
b0 fn0 :: Regex -> hint ByteString -> [ByteString]
fn0 = ByteString -> [Comp] -> [Exec] -> E Regex
forall a. Regex a => a -> [Comp] -> [Exec] -> E Regex
makeRegexOpt ByteString
p1 [Comp
Utf8] [] E Regex -> (Regex -> E [String]) -> E [String]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \p2 :: Regex
p2 ->
            [String] -> E [String]
forall a b. b -> Either a b
Right ([String] -> E [String]) -> [String] -> E [String]
forall a b. (a -> b) -> a -> b
$ ByteString -> String
toString (ByteString -> String) -> [ByteString] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Regex -> hint ByteString -> [ByteString]
fn0 Regex
p2 hint ByteString
b1)
        where p1 :: ByteString
p1 = String -> ByteString
toByteString String
p0
              b1 :: hint ByteString
b1 = String -> ByteString
toByteString (String -> ByteString) -> hint String -> hint ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> hint String
b0


instance WithRegex String [[ByteString]] [[String]] where
    withRegex :: String
-> hint String
-> (Regex -> hint ByteString -> [[ByteString]])
-> E [[String]]
withRegex p0 :: String
p0 b0 :: hint String
b0 fn0 :: Regex -> hint ByteString -> [[ByteString]]
fn0 = ByteString -> [Comp] -> [Exec] -> E Regex
forall a. Regex a => a -> [Comp] -> [Exec] -> E Regex
makeRegexOpt ByteString
p1 [Comp
Utf8] [] E Regex -> (Regex -> E [[String]]) -> E [[String]]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \p2 :: Regex
p2 ->
            [[String]] -> E [[String]]
forall a b. b -> Either a b
Right ([[String]] -> E [[String]]) -> [[String]] -> E [[String]]
forall a b. (a -> b) -> a -> b
$ [(ByteString -> String
toString (ByteString -> String) -> [ByteString] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)] [[ByteString] -> [String]] -> [[ByteString]] -> [[String]]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Regex -> hint ByteString -> [[ByteString]]
fn0 Regex
p2 hint ByteString
b1)
        where p1 :: ByteString
p1 = String -> ByteString
toByteString String
p0
              b1 :: hint ByteString
b1 = String -> ByteString
toByteString (String -> ByteString) -> hint String -> hint ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> hint String
b0


instance WithRegex String Bool Bool where
    withRegex :: String
-> hint String -> (Regex -> hint ByteString -> Bool) -> E Bool
withRegex p0 :: String
p0 b0 :: hint String
b0 fn0 :: Regex -> hint ByteString -> Bool
fn0 = ByteString -> [Comp] -> [Exec] -> E Regex
forall a. Regex a => a -> [Comp] -> [Exec] -> E Regex
makeRegexOpt ByteString
p1 [Comp
Utf8] [] E Regex -> (Regex -> E Bool) -> E Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \p2 :: Regex
p2 ->
            Bool -> E Bool
forall a b. b -> Either a b
Right (Bool -> E Bool) -> Bool -> E Bool
forall a b. (a -> b) -> a -> b
$ Regex -> hint ByteString -> Bool
fn0 Regex
p2 hint ByteString
b1
        where p1 :: ByteString
p1 = String -> ByteString
toByteString String
p0
              b1 :: hint ByteString
b1 = String -> ByteString
toByteString (String -> ByteString) -> hint String -> hint ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> hint String
b0


withRegex'::(T.Regex a, Matchf hint) =>
    a -> hint b ->
        (E Re.Regex -> hint b -> P hint) ->
        P hint
withRegex' :: a -> hint b -> (E Regex -> hint b -> P hint) -> P hint
withRegex' p0 :: a
p0 b0 :: hint b
b0 fn0 :: E Regex -> hint b -> P hint
fn0 =
        let er1 :: E Regex
er1 = a -> [Comp] -> [Exec] -> E Regex
forall a. Regex a => a -> [Comp] -> [Exec] -> E Regex
makeRegexOpt a
p0 [Comp
Utf8] []
        in E Regex -> hint b -> P hint
fn0 E Regex
er1 hint b
b0