packages feed

regex-do 2.6.1 → 2.6.2

raw patch · 13 files changed

+176/−46 lines, 13 filesdep +mtl

Dependencies added: mtl

Files

changelog.md view
@@ -1,3 +1,8 @@+#####   2.6.2+  compatible with 2.6.1+  +  add makeRegexM, makeRegexOptM, RegexResult to catch regex construction errors+ #####   2.6.1   compatible with 2.6   
regex-do.cabal view
@@ -1,5 +1,5 @@ name:                regex-do-version:             2.6.1+version:             2.6.2 synopsis:            PCRE wrapper description:         format, search, replace (String | ByteString) with PCRE regex. Utf8-safe author:              Imants Cekusins@@ -40,7 +40,6 @@    other-modules:           Text.Regex.Do.Result-   ghc-options:  -fwarn-unused-imports        build-depends:  base <= 5.0,@@ -48,6 +47,7 @@               regex-pcre,               stringsearch,               bytestring,+              mtl,               array,               text @@ -92,6 +92,7 @@         TestRegex.TestTrim         TestRegex.TestReplaceOpen         TestRegex.TestReplaceUtf+        TestRegex.TestMakeRegexM    build-depends:  base <= 5.0,                   hspec,@@ -99,6 +100,7 @@                   regex-base,                   regex-pcre,                   stringsearch,+                  mtl,                   bytestring,                   array,                   text,
src/Text/Regex/Do/Format.hs view
@@ -1,3 +1,17 @@+{- | ==== placeholder syntax:++       * index based++            { Int }++       * key based++            { 'String' | 'ByteString' | 'Text' }++    other placeholders may be implemented with++    "Text.Regex.Do.Pcre.Ascii.Replace" or "Text.Regex.Do.Pcre.Utf8.Replace"       -}+ module Text.Regex.Do.Format     (Format(..),     ReplaceOne(..),@@ -20,7 +34,9 @@     * 'Text'      -}  class Format a arg where-   format::a -> arg -> a+   format::a    -- ^ text to format e.g. "today is {0}"+        -> arg  -- ^ replacement: [a] or [(a,a)]+        -> a    -- ^ formatted text   instance ReplaceOne Int a =>
src/Text/Regex/Do/Pcre/Ascii/Match.hs view
@@ -19,31 +19,37 @@ import Text.Regex.Do.Type.MatchHint  +{- | short version of 'match': arg without newtypes++    is borrowed from "Text.Regex.PCRE.Wrap"    -}+(=~)::Match a b out =>+    a     -- ^ pattern+    -> b    -- ^ body+    -> out+(=~) p0 b0 = match (Pattern p0) (Body b0)+++ {- | * a:  'String', 'ByteString', 'Regex'     * b:  'String', 'ByteString'-    * out: ['String'], [['String']], ['ByteString'], [['ByteString']], 'Bool', ['PosLen'], [['PosLen']]+    * out: -    'match' covers all result types+        * ['String'], [['String']]+        * ['ByteString'], [['ByteString']]+        * 'Bool'+        * ['PosLen'], [['PosLen']] -    compiler looks up the appropriate function depending on the result type -    '=~' is borrowed from "Text.Regex.PCRE.Wrap",-    is a short version of 'match'-     precompiled Regex may be used as pattern too. see "Text.Regex.Do.Pcre.Utf8.Match" -    See also "Text.Regex.Do.Pcre.Ascii.MatchHint"       -}+    See also "Text.Regex.Do.Pcre.Ascii.MatchHint" +    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'     -}+ class Match a b out where     match::Pattern a -> Body b -> out  --- | synonym for 'match'. arg without newtypes-(=~)::Match a b out =>-    a     -- ^ pattern-    -> b    -- ^ body-    -> out-(=~) p0 b0 = match (Pattern p0) (Body b0)   -- | match once@@ -56,16 +62,16 @@     match p0 (Body b0) = R.matchTest (makeRegex p0) b0 {- ^ test -    >>> "в" =~ "тихо в лесу"::Bool+    >>> "chilly" =~ "it's chilly inside, chilly outside"::Bool      True    -}  -- | match all instance Rx_ a b => Match a b [[b]] where     match p0 = F.all (makeRegex' p0)-{- ^  >>> "well" =~ "all is well that ends well"::[[ByteString]]+{- ^  >>> "chilly" =~ "it's chilly inside, chilly outside"::[[ByteString]] -     \[["well"\],\["well"\]]        -}+     \[["chilly"\],\["chilly"\]]        -}  -- | match once instance Rx_ a b => Match a b [PosLen] where
src/Text/Regex/Do/Pcre/Ascii/MatchHint.hs view
@@ -3,15 +3,24 @@      this module is similar to "Text.Regex.Do.Pcre.Ascii.Match". The differences are: -    "Text.Regex.Do.Pcre.Ascii.Match" is more flexible:+    * "Text.Regex.Do.Pcre.Ascii.Match" is more flexible:+         accepts 'Pattern' Regex,+         accepts 'Pattern' and 'Body' of different types -    "Text.Regex.Do.Pcre.Ascii.Match" needs to infer result type+    * "Text.Regex.Do.Pcre.Ascii.Match" needs to infer result type -    in this module the result type is determined by the hint-    -}+    this module: +    * 'Pattern' and 'Body' are of the same type++    * 'Hint' and inferrable 'Pattern' or 'Body' type determine the instance++        the result type is determined by the hint++    * handy when working with 'OverloadedStrings', in other cases when compiler needs a hint  -}+ module Text.Regex.Do.Pcre.Ascii.MatchHint where  import Text.Regex.Do.Type.Do hiding (Once,All)@@ -23,13 +32,7 @@  {- | * hint: 'Once', 'All', 'Test', 'PosLen'', 'PosLen_'     * a: 'String', 'ByteString'--    picks 'M.Match' instance where 'Pattern' and 'Body' are of the same type--    'Hint' and inferrable 'Pattern' or 'Body' type determine the instance--    handy when working with 'OverloadedStrings', in other cases when compiler needs a hint  -}-+-}   class (Hint hint, M.Match a a (F hint a)) =>
src/Text/Regex/Do/Pcre/Ascii/Replace.hs view
@@ -25,6 +25,8 @@         * ('All' | 'Once' (a))         * ('All' | 'Once' ('Pattern' a)) +    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'+     * repl:  b: 'String' | 'ByteString'          * ('Replacement' b)
src/Text/Regex/Do/Pcre/Utf8/Match.hs view
@@ -24,20 +24,30 @@ import Data.ByteString  -{- | * enc: 'Utf8_'-    * a:  'String', 'ByteString', 'Regex'-    * b:  'String', 'ByteString'-    * out: ['String'], [['String']], ['ByteString'], [['ByteString']], 'Bool', ['PosLen'], [['PosLen']]-    -}-class Match enc a b out where-    match::Pattern (enc a) -> Body (enc b) -> out- -- | synonym for 'match'. arg without newtypes (=~)::Match Utf8_ a b out =>     a     -- ^ pattern     -> b    -- ^ body     -> out (=~) p0 b0 = match (Pattern $ Utf8_ p0) (Body $ Utf8_ b0)++++{- | * enc: 'Utf8_'+    * a:  'String', 'ByteString', 'Regex'++    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'++    * b:  'String', 'ByteString'+    * out:++        * ['String'], [['String']]+        * ['ByteString'], [['ByteString']]+        * 'Bool'+        * ['PosLen'], [['PosLen']]      -}++class Match enc a b out where+    match::Pattern (enc a) -> Body (enc b) -> out   {- | match once
src/Text/Regex/Do/Pcre/Utf8/MatchHint.hs view
@@ -15,12 +15,8 @@ {- | * hint: 'Once', 'All', 'Test', 'PosLen'', 'PosLen_'     * a: 'String', 'ByteString'     * enc: 'Utf8_'--    picks 'M.Match' instance where 'Pattern' and 'Body' are of the same type--    'Hint' and inferrable 'Pattern' or 'Body' type determine the instance+-} -    handy when working with 'OverloadedStrings', in other cases when compiler needs a hint  -} class (Hint hint, M.Match enc a a (F hint a)) =>     MatchHint hint enc a where     type F hint a
src/Text/Regex/Do/Pcre/Utf8/Replace.hs view
@@ -20,6 +20,8 @@  {- | see "Text.Regex.Do.Pcre.Ascii.Replace" for implemented types +    to catch regex construction __errors__, precompile 'Regex' with 'makeRegexM' or 'makeRegexOptM'+     in full typed instance every b is wrapped in 'Utf8_' newtype      'GroupReplacer' is implemented only for 'ByteString'    -}
src/Text/Regex/Do/Type/Regex.hs view
@@ -2,6 +2,7 @@     (Regex(..),     makeRegex',     makeRegexOpt',+    RegexResult(..),     Rx_, Opt_, Ro_) where  import qualified Text.Regex.Base.RegexLike as R@@ -13,9 +14,34 @@  class Regex a where    makeRegex::Pattern a -> R.Regex+   makeRegexM::Monad m => Pattern a -> m R.Regex    makeRegexOpt::Pattern a -> [Comp] -> [Exec] -> R.Regex+   makeRegexOptM::Monad m => Pattern a -> [Comp] -> [Exec] -> m R.Regex +{- ^ monadic +        * 'makeRegexM'+        * 'makeRegexOptM'++        let catch regex construction errors++    for 'm' to catch errors, implement 'fail' in 'm'++    default 'm' implementation: 'RegexResult'++    ==== makeRegexM test case:++    >>>  it "RegexResult test case" $ do+            rx1 `shouldNotSatisfy` isok1+            rx2 `shouldSatisfy` isok1+        where rx1 = T.makeRegexM $ Pattern "[["::RegexResult R.Regex+              rx2 = T.makeRegexM $ Pattern "."::RegexResult R.Regex+              isok1 (RegexResult (Left e1)) = traceShow e1 False+              isok1 _ = True++    >>> instance Show (RegexResult R.Regex) where+            show _ = "bon"       -}+ makeRegex'::Regex a => Pattern a -> Pattern R.Regex makeRegex' = Pattern . makeRegex @@ -26,22 +52,30 @@  instance Regex a => Regex (Utf8_ a) where    makeRegex p0 = makeRegexOpt (Pattern val <*> p0) [Utf8] []+   makeRegexM p0 = makeRegexOptM (Pattern val <*> p0) [Utf8] []    makeRegexOpt p0 c0 e0 = makeRegexOpt (Pattern val <*> p0) (Utf8:c0) e0+   makeRegexOptM p0 c0 e0 = makeRegexOptM (Pattern val <*> p0) (Utf8:c0) e0   instance Regex ByteString where    makeRegex (Pattern p0) = R.makeRegex p0+   makeRegexM (Pattern p0) = R.makeRegexM p0    makeRegexOpt = makeRegexOpts+   makeRegexOptM = makeRegexOptsM   instance Regex String where    makeRegex (Pattern p0) = R.makeRegex p0+   makeRegexM (Pattern p0) = R.makeRegexM p0    makeRegexOpt = makeRegexOpts+   makeRegexOptM = makeRegexOptsM   instance Regex R.Regex where    makeRegex (Pattern p0) = p0+   makeRegexM (Pattern p0) = pure p0    makeRegexOpt (Pattern p0) _ _ = p0+   makeRegexOptM (Pattern p0) _ _ = pure p0   -- | tweak Regex with options@@ -55,6 +89,33 @@          rx1 = R.makeRegexOpts c1 e1 pat0  +makeRegexOptsM::(Monad m, Opt_ a) =>+    Pattern a ->+        [Comp] -> [Exec] ->+            m R.Regex+makeRegexOptsM (Pattern pat0) comp0 exec0 = rx1+   where c1 = comp comp0+         e1 = exec exec0+         rx1 = R.makeRegexOptsM c1 e1 pat0+++ type Rx_ a b = (Regex a, R.Extract b, R.RegexLike R.Regex b) type Opt_ a = R.RegexMaker R.Regex R.CompOption R.ExecOption a type Ro_ rx = (Regex rx, Opt_ rx)+++{- | catches regex construction __errors__  -}+newtype RegexResult a = RegexResult (Either [String] a) deriving (Functor)++instance Applicative RegexResult where+    pure = RegexResult . Right+    (<*>) (RegexResult (Left e1)) (RegexResult (Left e2)) = RegexResult $ Left $ e1 ++ e2+    (<*>) (RegexResult (Right fn0)) (RegexResult (Left e1)) = RegexResult $ Left e1+    (<*>) (RegexResult (Left e1)) (RegexResult (Right r1)) = RegexResult $ Left e1+    (<*>) (RegexResult (Right fn0)) (RegexResult (Right a0)) = pure $ fn0 a0++instance Monad RegexResult where+    (>>=) (RegexResult (Left e1)) fn0 = RegexResult $ Left e1+    (>>=) (RegexResult (Right a0)) fn0 = fn0 a0+    fail s0 = RegexResult $ Left [s0]
test/Main.hs view
@@ -7,7 +7,7 @@ import qualified TestRegex.TestReplaceOpen as O import qualified TestRegex.TestSplit as S import qualified TestRegex.TestTrim as T-+import qualified TestRegex.TestMakeRegexM as E  main::IO() main = do@@ -18,3 +18,4 @@             O.main             R.main             U.main+            E.main
+ test/TestRegex/TestMakeRegexM.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE NoOverloadedStrings #-}+module TestRegex.TestMakeRegexM where++import Test.Hspec+import Text.Regex.Do.Type.Reexport as R+import Text.Regex.Do.Type.Regex as T+import Text.Regex.Do.Type.Do as T+import Debug.Trace+++main::IO()+main = hspec $ do+       describe "TestRegex.TestMakeRegexM" $ do+          it "RegexResult test case" $ do+            rx1 `shouldNotSatisfy` isok1+            rx2 `shouldSatisfy` isok1+        where rx1 = T.makeRegexM $ Pattern "[["::RegexResult R.Regex+              rx2 = T.makeRegexM $ Pattern "."::RegexResult R.Regex++              isok1 (RegexResult (Left e1)) = traceShow e1 False+              isok1 _ = True+++instance Show (RegexResult R.Regex) where+    show _ = "rx"
test/TestRegex/TestPcre.hs view
@@ -23,10 +23,11 @@      it " cd " $ S.match (PosLen' $ Pattern ("^cd"::String)) (Body "abcde") `shouldBe` []      it " ab " $ S.match (Test $ Pattern ("^ab"::String)) (Body "abc") `shouldBe` True      it "doc 1" $ Test ("в"::ByteString) S.=~ "тихо в лесу" `shouldBe` True-     it "doc 1" $ Test (toByteString "в") Su.=~ toByteString "тихо в лесу" `shouldBe` True+     it "doc 1.2" $ Test ("chilly"::ByteString) S.=~ "it's chilly inside, chilly outside" `shouldBe` True+     it "doc 1.3" $ Test (toByteString "в") Su.=~ toByteString "тихо в лесу" `shouldBe` True      it "doc 2" $ S.Once ("^all"::String) S.=~ "all the time" `shouldBe` ["all"]      it "doc 3" $ S.Once ("^all"::ByteString) S.=~ "all the time" `shouldBe` ["all"]-     it "doc 4" $ S.All ("well"::ByteString) S.=~ "all is well that ends well" `shouldBe` ([["well"],["well"]])+     it "doc 4" $ S.All ("chilly"::ByteString) S.=~ "it's chilly inside, chilly outside" `shouldBe` ([["chilly"],["chilly"]])      it "doc 5" $ PosLen' ("и"::String) S.=~ "бывает и хуже" `shouldBe` [(13,2)]      it "doc 6" $ PosLen' ("à"::String) S.=~ "tourner à gauche" `shouldBe` [(8,2)]      it "doc 7" $ do