diff --git a/src/Data/URI/Common.js b/src/Data/URI/Common.js deleted file mode 100644 index ac17ea5..0000000 --- a/src/Data/URI/Common.js +++ /dev/null @@ -1,23 +0,0 @@ -/* global exports */ -"use strict"; - -// module Data.URI.Common - -exports.match1FromImpl = function (just) { - return function (nothing) { - return function (rx) { - var rxStr = rx.toString(); - var flagIndex = rxStr.lastIndexOf("/"); - var pattern = rxStr.substring(1, flagIndex); - var flags = rxStr.substring(flagIndex + 1); - return function (i) { - var rx = new RegExp(pattern, flags.indexOf("g") === -1 ? flags + "g" : flags); - return function (str) { - rx.lastIndex = i; - var result = rx.exec(str); - return result && result.index === i ? just(result[0]) : nothing; - }; - }; - }; - }; -}; diff --git a/src/Data/URI/Common.purs b/src/Data/URI/Common.purs index 7525e91..3e86785 100644 --- a/src/Data/URI/Common.purs +++ b/src/Data/URI/Common.purs @@ -3,7 +3,8 @@ module Data.URI.Common where import Prelude import Control.Alt ((<|>)) -import Data.Array (fromFoldable) +import Control.MonadZero (guard) +import Data.Array (fromFoldable, head) import Data.Either (Either(..), fromRight) import Data.List (List) import Data.Maybe (Maybe(..)) @@ -78,12 +79,12 @@ anyMatch rx = Parser \{ str: str, pos: i } → case match1From rx i str of Nothing → Left { error: (ParseError $ "Expected " <> show rx), pos: i } match1From ∷ RX.Regex → Int → String → Maybe String -match1From = match1FromImpl Just Nothing - -foreign import match1FromImpl - ∷ (∀ a. a → Maybe a) - → (∀ a. Maybe a) - → RX.Regex - → Int - → String - → (Maybe String) +match1From rx' n str' = + case RX.regex (RX.source rx') (RXF.global <> RX.flags rx') of + Left _ -> Nothing + Right rx -> do + let str = S.drop n str' + i <- RX.search rx str + guard $ i == 0 + matches <- RX.match rx str + join $ head matches diff --git a/test/Main.purs b/test/Main.purs index 4e1fd54..82d19d4 100755 --- a/test/Main.purs +++ b/test/Main.purs @@ -13,10 +13,13 @@ import Data.List (List(..), singleton, (:)) import Data.Maybe (Maybe(Nothing, Just)) import Data.Monoid (mempty) import Data.Path.Pathy (currentDir, parentDir', file, dir, rootDir, ()) +import Data.String.Regex (Regex, regex) +import Data.String.Regex.Flags (global, noFlags) import Data.Tuple (Tuple(..)) import Data.URI (AbsoluteURI(..), Authority(..), Fragment(..), HierarchicalPart(..), Host(..), Port(..), Query(..), RelativePart(..), RelativeRef(..), Scheme(..), URI(..), UserInfo(..)) import Data.URI.AbsoluteURI as AbsoluteURI import Data.URI.Authority as Authority +import Data.URI.Common as Common import Data.URI.Host as Host import Data.URI.Host.Gen as Host.Gen import Data.URI.Port as Port @@ -74,6 +77,22 @@ testParseQueryParses uri query = ("parses: \"" <> uri <> "\"") (equal (Right query) (runParser Query.parser uri)) +testMatch1FromMatches :: forall a. Either String Regex -> Int -> String -> Maybe String -> TestSuite a +testMatch1FromMatches rx' n str expected = case rx' of + Left error -> test "faulty regex given" (assert error false) + Right rx -> + test + ("matches: " <> show rx <> " at " <> show n <> " in " <> show str) + (equal expected $ Common.match1From rx n str) + +testMatch1FromMisses :: forall a. Either String Regex -> Int -> String -> TestSuite a +testMatch1FromMisses rx' n str = case rx' of + Left error -> test "faulty regex given" (assert error false) + Right rx -> + test + ("does not match: " <> show rx <> " at " <> show n <> " in " <> show str) + (equal Nothing $ Common.match1From rx n str) + main :: forall eff. Eff (console :: CONSOLE, testOutput :: TESTOUTPUT, avar :: AVAR, exception :: EXCEPTION, random :: RANDOM | eff) Unit main = runTest $ suite "Data.URI" do @@ -443,6 +462,17 @@ main = runTest $ suite "Data.URI" do "key1=&key2=" (Query (Tuple "key1" (Just "") : Tuple "key2" (Just "") : Nil)) + suite "Common.match1From" do + testMatch1FromMisses (regex "key1" noFlags) 0 "" + testMatch1FromMisses (regex "key1" noFlags) 1 "key1" + testMatch1FromMisses (regex "key1" noFlags) 1 "key1=&key1=" + testMatch1FromMisses (regex "key1" global) 1 "key1=&key1=" + testMatch1FromMisses (regex "key1|key2" noFlags) 1 "key1=&key2=" + + testMatch1FromMatches (regex "key1" noFlags) 0 "key1" (Just "key1") + testMatch1FromMatches (regex "key1" noFlags) 6 "key1=&key1=" (Just "key1") + testMatch1FromMatches (regex "key1|key2" noFlags) 6 "key1=&key2=" (Just "key2") + forAll :: forall eff prop. QC.Testable prop => QCG.Gen prop -> Test (console :: CONSOLE, random :: RANDOM, exception :: EXCEPTION | eff) forAll = quickCheck