packages feed

uri-templater 1.0.0 → 1.0.0.1

raw patch · 3 files changed

+74/−4 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

src/Network/URI/Template/Parser.hs view
@@ -172,7 +172,11 @@ -- | Parse a URI template segments {-# INLINE uriTemplate #-} uriTemplate :: Parser e (V.Vector TemplateSegment)-uriTemplate = V.fromList <$> (ws *> many (literal <|> embed))+uriTemplate = do+  ws+  segments <- many (literal <|> embed)+  eof  -- Ensure we consumed all input+  return (V.fromList segments)   -- | Helper to separate a parser by a separator@@ -181,13 +185,33 @@ sepBy1 p sep = (:) <$> p <*> many (sep *> p)  +-- | Analyze parse failure to provide a better error message+analyzeParseFailure :: String -> ParseError+analyzeParseFailure input = go 0 0 input+ where+  go depth pos []+    | depth > 0 = UnterminatedExpression (findLastOpen input)+    | otherwise = GenericParseError ("Parse error in URI template: " ++ input)+  go depth pos ('{' : rest) = go (depth + 1) (pos + 1) rest+  go depth pos ('}' : rest)+    | depth <= 0 = UnexpectedCharacter pos '}' "Unexpected closing brace without matching opening brace"+    | otherwise = go (depth - 1) (pos + 1) rest+  go depth pos (_ : rest) = go depth (pos + 1) rest++  findLastOpen = go' 0 0+   where+    go' pos lastPos [] = lastPos+    go' pos lastPos ('{' : rest) = go' (pos + 1) pos rest+    go' pos lastPos (_ : rest) = go' (pos + 1) lastPos rest++ -- | Parse a template from a String parseTemplate :: String -> Either ParseError UriTemplate parseTemplate input =   case runParser uriTemplate (TE.encodeUtf8 $ T.pack input) of     OK result _ -> Right (UriTemplate result)-    Err _ -> Left (GenericParseError ("Parse error in URI template: " ++ input))-    Fail -> Left (GenericParseError ("Parse error in URI template: " ++ input))+    Err _ -> Left (analyzeParseFailure input)+    Fail -> Left (analyzeParseFailure input)   {- | 'IsString' instance for 'UriTemplate' allows using string literals directly as templates
test/Test.hs view
@@ -18,6 +18,7 @@ import qualified Data.Vector as V import GHC.Generics (Generic, Rep) import Network.URI.Template+import Network.URI.Template.Error import Network.URI.Template.Parser import Network.URI.Template.TH import Network.URI.Template.Types@@ -191,6 +192,50 @@       rendered @?= ("?gen_product_name=Gadget&gen_product_price=200" :: Text)  +parseErrorTests :: TestRegistry ()+parseErrorTests = label "Parse Error Tests" $+  suite $ do+    label "Unclosed template expression (missing closing brace)" $ test $ do+      case parseTemplate "http://example.com/dictionary/{term:1}/{term" of+        Left (UnterminatedExpression _) -> return ()+        Left err -> assertFailure $ "Expected UnterminatedExpression, got: " ++ show err+        Right _ -> assertFailure "Should fail to parse template with missing closing brace"++    label "Unopened closing brace (orphan closing brace)" $ test $ do+      case parseTemplate "http://example.com/dictionary/{term:1}/term}" of+        Left (UnexpectedCharacter _ '}' _) -> return ()+        Left err -> assertFailure $ "Expected UnexpectedCharacter for '}', got: " ++ show err+        Right _ -> assertFailure "Should fail to parse template with extra closing brace"++    label "Multiple unclosed braces" $ test $ do+      case parseTemplate "{foo}{bar" of+        Left (UnterminatedExpression _) -> return ()+        Left err -> assertFailure $ "Expected UnterminatedExpression, got: " ++ show err+        Right _ -> assertFailure "Should fail to parse template with unclosed brace"++    label "Nested braces (invalid)" $ test $ do+      case parseTemplate "{foo{bar}}" of+        Left _ -> return ()+        Right _ -> assertFailure "Should fail to parse template with nested braces"++    label "Only opening brace" $ test $ do+      case parseTemplate "{" of+        Left (UnterminatedExpression _) -> return ()+        Left err -> assertFailure $ "Expected UnterminatedExpression, got: " ++ show err+        Right _ -> assertFailure "Should fail to parse template with only opening brace"++    label "Only closing brace" $ test $ do+      case parseTemplate "}" of+        Left (UnexpectedCharacter _ '}' _) -> return ()+        Left err -> assertFailure $ "Expected UnexpectedCharacter for '}', got: " ++ show err+        Right _ -> assertFailure "Should fail to parse template with only closing brace"++    label "Valid template should still parse correctly" $ test $ do+      case parseTemplate "http://example.com/dictionary/{term:1}/{term}" of+        Right _ -> return ()+        Left err -> assertFailure $ "Valid template should parse, got error: " ++ show err++ main :: IO () main = do   counts <- testRun@@ -210,6 +255,7 @@     thDerivationTests     genericsDerivationTests     percentEncodingTests+    parseErrorTests     label "RFC 6570 Core Examples" $       suite $ do         label "unescaped" $ test $ unescaped strEq
uri-templater.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                uri-templater-version:             1.0.0+version:             1.0.0.1 synopsis:            Parsing & Quasiquoting for RFC 6570 URI Templates description:         Parsing & Quasiquoting for RFC 6570 URI Templates homepage:            https://github.com/iand675/uri-templater