packages feed

uri-templater 0.1.0.0 → 0.2.0.0

raw patch · 6 files changed

+135/−97 lines, 6 filesdep +containersdep +textdep +unordered-containersdep ~trifectaPVP ok

version bump matches the API change (PVP)

Dependencies added: containers, text, unordered-containers, vector

Dependency ranges changed: trifecta

API changes (from Hackage documentation)

- Network.URI.Template.Types: AssociativeVal :: [(String, String)] -> InternalTemplateValue
- Network.URI.Template.Types: ListElem :: a -> ListElem a
- Network.URI.Template.Types: ListVal :: [String] -> InternalTemplateValue
- Network.URI.Template.Types: SingleVal :: String -> InternalTemplateValue
- Network.URI.Template.Types: data AssociativeListElement
- Network.URI.Template.Types: data InternalTemplateValue
- Network.URI.Template.Types: data ListElement
- Network.URI.Template.Types: data SingleElement
- Network.URI.Template.Types: fromListElem :: ListElem a -> a
- Network.URI.Template.Types: fromSingle :: TemplateValue SingleElement -> String
- Network.URI.Template.Types: fromSingleVal :: InternalTemplateValue -> String
- Network.URI.Template.Types: instance Eq Modifier
- Network.URI.Template.Types: instance Eq TemplateSegment
- Network.URI.Template.Types: instance Eq ValueModifier
- Network.URI.Template.Types: instance Eq Variable
- Network.URI.Template.Types: instance Read Modifier
- Network.URI.Template.Types: instance Read TemplateSegment
- Network.URI.Template.Types: instance Read ValueModifier
- Network.URI.Template.Types: instance Read Variable
- Network.URI.Template.Types: instance Show Modifier
- Network.URI.Template.Types: instance Show TemplateSegment
- Network.URI.Template.Types: instance Show ValueModifier
- Network.URI.Template.Types: instance Show Variable
- Network.URI.Template.Types: instance ToTemplateValue Int SingleElement
- Network.URI.Template.Types: instance ToTemplateValue String SingleElement
- Network.URI.Template.Types: instance ToTemplateValue a SingleElement => ToTemplateValue (ListElem [a]) ListElement
- Network.URI.Template.Types: instance ToTemplateValue a SingleElement => ToTemplateValue [(String, a)] AssociativeListElement
- Network.URI.Template.Types: internalize :: TemplateValue a -> InternalTemplateValue
- Network.URI.Template.Types: newtype ListElem a
+ Network.URI.Template: AList :: [(k, v)] -> AList k v
+ Network.URI.Template: String :: String -> TemplateString
+ Network.URI.Template: fromAList :: AList k v -> [(k, v)]
+ Network.URI.Template: fromString :: TemplateString -> String
+ Network.URI.Template: newtype AList k v
+ Network.URI.Template: newtype TemplateString
+ Network.URI.Template.Internal: type BoundValue = (String, WrappedValue)
+ Network.URI.Template.Types: AList :: [(k, v)] -> AList k v
+ Network.URI.Template.Types: String :: String -> TemplateString
+ Network.URI.Template.Types: WrappedValue :: TemplateValue a -> WrappedValue
+ Network.URI.Template.Types: data Associative
+ Network.URI.Template.Types: data List
+ Network.URI.Template.Types: data Single
+ Network.URI.Template.Types: data WrappedValue
+ Network.URI.Template.Types: fromAList :: AList k v -> [(k, v)]
+ Network.URI.Template.Types: fromString :: TemplateString -> String
+ Network.URI.Template.Types: instance [overlap ok] (ToTemplateValue a, TemplateRep a ~ Single) => ToTemplateValue (Vector a)
+ Network.URI.Template.Types: instance [overlap ok] (ToTemplateValue a, TemplateRep a ~ Single) => ToTemplateValue [a]
+ Network.URI.Template.Types: instance [overlap ok] (ToTemplateValue k, TemplateRep k ~ Single, ToTemplateValue v, TemplateRep v ~ Single) => ToTemplateValue (AList k v)
+ Network.URI.Template.Types: instance [overlap ok] (ToTemplateValue k, TemplateRep k ~ Single, ToTemplateValue v, TemplateRep v ~ Single) => ToTemplateValue (HashMap k v)
+ Network.URI.Template.Types: instance [overlap ok] (ToTemplateValue k, TemplateRep k ~ Single, ToTemplateValue v, TemplateRep v ~ Single) => ToTemplateValue (Map k v)
+ Network.URI.Template.Types: instance [overlap ok] Eq Modifier
+ Network.URI.Template.Types: instance [overlap ok] Eq TemplateSegment
+ Network.URI.Template.Types: instance [overlap ok] Eq TemplateString
+ Network.URI.Template.Types: instance [overlap ok] Eq ValueModifier
+ Network.URI.Template.Types: instance [overlap ok] Eq Variable
+ Network.URI.Template.Types: instance [overlap ok] IsString TemplateString
+ Network.URI.Template.Types: instance [overlap ok] Read Modifier
+ Network.URI.Template.Types: instance [overlap ok] Read TemplateSegment
+ Network.URI.Template.Types: instance [overlap ok] Read TemplateString
+ Network.URI.Template.Types: instance [overlap ok] Read ValueModifier
+ Network.URI.Template.Types: instance [overlap ok] Read Variable
+ Network.URI.Template.Types: instance [overlap ok] Show (TemplateValue a)
+ Network.URI.Template.Types: instance [overlap ok] Show Modifier
+ Network.URI.Template.Types: instance [overlap ok] Show TemplateSegment
+ Network.URI.Template.Types: instance [overlap ok] Show TemplateString
+ Network.URI.Template.Types: instance [overlap ok] Show ValueModifier
+ Network.URI.Template.Types: instance [overlap ok] Show Variable
+ Network.URI.Template.Types: instance [overlap ok] ToTemplateValue Int
+ Network.URI.Template.Types: instance [overlap ok] ToTemplateValue TemplateString
+ Network.URI.Template.Types: instance [overlap ok] ToTemplateValue Text
+ Network.URI.Template.Types: newtype AList k v
+ Network.URI.Template.Types: newtype TemplateString
- Network.URI.Template: Associative :: [(String, TemplateValue SingleElement)] -> TemplateValue AssociativeListElement
+ Network.URI.Template: Associative :: [(TemplateValue Single, TemplateValue Single)] -> TemplateValue Associative
- Network.URI.Template: List :: [TemplateValue SingleElement] -> TemplateValue ListElement
+ Network.URI.Template: List :: [TemplateValue Single] -> TemplateValue List
- Network.URI.Template: Single :: String -> TemplateValue SingleElement
+ Network.URI.Template: Single :: String -> TemplateValue Single
- Network.URI.Template: class ToTemplateValue a e | a -> e
+ Network.URI.Template: class ToTemplateValue a where type family TemplateRep a
- Network.URI.Template: render :: UriTemplate -> [(String, TemplateValue a)] -> String
+ Network.URI.Template: render :: UriTemplate -> [BoundValue] -> String
- Network.URI.Template: toTemplateValue :: ToTemplateValue a e => a -> TemplateValue e
+ Network.URI.Template: toTemplateValue :: ToTemplateValue a => a -> TemplateValue (TemplateRep a)
- Network.URI.Template.Internal: namePrefix :: ProcessingOptions -> String -> InternalTemplateValue -> StringBuilder ()
+ Network.URI.Template.Internal: namePrefix :: ProcessingOptions -> String -> TemplateValue a -> StringBuilder ()
- Network.URI.Template.Internal: processVariable :: Modifier -> Bool -> Variable -> InternalTemplateValue -> StringBuilder ()
+ Network.URI.Template.Internal: processVariable :: Modifier -> Bool -> Variable -> WrappedValue -> StringBuilder ()
- Network.URI.Template.Internal: processVariables :: [(String, InternalTemplateValue)] -> Modifier -> [Variable] -> StringBuilder ()
+ Network.URI.Template.Internal: processVariables :: [(String, WrappedValue)] -> Modifier -> [Variable] -> StringBuilder ()
- Network.URI.Template.Internal: render :: UriTemplate -> [(String, TemplateValue a)] -> String
+ Network.URI.Template.Internal: render :: UriTemplate -> [BoundValue] -> String
- Network.URI.Template.Internal: render' :: UriTemplate -> [(String, InternalTemplateValue)] -> String
+ Network.URI.Template.Internal: render' :: UriTemplate -> [BoundValue] -> String
- Network.URI.Template.Internal: templateValueIsEmpty :: InternalTemplateValue -> Bool
+ Network.URI.Template.Internal: templateValueIsEmpty :: TemplateValue a -> Bool
- Network.URI.Template.Types: Associative :: [(String, TemplateValue SingleElement)] -> TemplateValue AssociativeListElement
+ Network.URI.Template.Types: Associative :: [(TemplateValue Single, TemplateValue Single)] -> TemplateValue Associative
- Network.URI.Template.Types: List :: [TemplateValue SingleElement] -> TemplateValue ListElement
+ Network.URI.Template.Types: List :: [TemplateValue Single] -> TemplateValue List
- Network.URI.Template.Types: Single :: String -> TemplateValue SingleElement
+ Network.URI.Template.Types: Single :: String -> TemplateValue Single
- Network.URI.Template.Types: class ToTemplateValue a e | a -> e
+ Network.URI.Template.Types: class ToTemplateValue a where type family TemplateRep a
- Network.URI.Template.Types: toTemplateValue :: ToTemplateValue a e => a -> TemplateValue e
+ Network.URI.Template.Types: toTemplateValue :: ToTemplateValue a => a -> TemplateValue (TemplateRep a)

Files

src/Network/URI/Template.hs view
@@ -8,6 +8,8 @@   , ValueModifier(..)   , TemplateValue(..)   , ToTemplateValue(..)+  , AList(..)+  , TemplateString(..) ) where import Network.URI.Template.Internal import Network.URI.Template.Parser
src/Network/URI/Template/Internal.hs view
@@ -18,7 +18,7 @@  data Allow = Unreserved | UnreservedOrReserved -allowEncoder Unreserved = urlEncode+allowEncoder Unreserved           = urlEncode allowEncoder UnreservedOrReserved = id  data ProcessingOptions = ProcessingOptions@@ -29,34 +29,36 @@   , modifierAllow :: Allow   } +type BoundValue = (String, WrappedValue)+ option :: Maybe Char -> Char -> Bool -> Maybe Char -> Allow -> ProcessingOptions option = ProcessingOptions  options :: Modifier -> ProcessingOptions options m = case m of-  Simple            -> option Nothing    ',' False Nothing    Unreserved-  Reserved          -> option Nothing    ',' False Nothing    UnreservedOrReserved-  Label             -> option (Just '.') '.' False Nothing    Unreserved-  PathSegment       -> option (Just '/') '/' False Nothing    Unreserved-  PathParameter     -> option (Just ';') ';' True  Nothing    Unreserved-  Query             -> option (Just '?') '&' True  (Just '=') Unreserved-  QueryContinuation -> option (Just '&') '&' True  (Just '=') Unreserved-  Fragment          -> option (Just '#') ',' False Nothing    UnreservedOrReserved+  Simple            -> option  Nothing   ',' False  Nothing    Unreserved+  Reserved          -> option  Nothing   ',' False  Nothing    UnreservedOrReserved+  Label             -> option (Just '.') '.' False  Nothing    Unreserved+  PathSegment       -> option (Just '/') '/' False  Nothing    Unreserved+  PathParameter     -> option (Just ';') ';' True   Nothing    Unreserved+  Query             -> option (Just '?') '&' True  (Just '=')  Unreserved+  QueryContinuation -> option (Just '&') '&' True  (Just '=')  Unreserved+  Fragment          -> option (Just '#') ',' False  Nothing    UnreservedOrReserved -templateValueIsEmpty :: InternalTemplateValue -> Bool-templateValueIsEmpty (SingleVal s) = null s-templateValueIsEmpty (AssociativeVal s) = null s-templateValueIsEmpty (ListVal s) = null s+templateValueIsEmpty :: TemplateValue a -> Bool+templateValueIsEmpty (Single s)      = null s+templateValueIsEmpty (Associative s) = null s+templateValueIsEmpty (List s)        = null s -namePrefix :: ProcessingOptions -> String -> InternalTemplateValue -> StringBuilder ()+namePrefix :: ProcessingOptions -> String -> TemplateValue a -> StringBuilder () namePrefix opts name val = do   addString name   if templateValueIsEmpty val     then maybe (return ()) addChar $ modifierIfEmpty opts     else addChar '=' -processVariable :: Modifier -> Bool -> Variable -> InternalTemplateValue -> StringBuilder ()-processVariable m isFirst (Variable varName varMod) val = do+processVariable :: Modifier -> Bool -> Variable -> WrappedValue -> StringBuilder ()+processVariable m isFirst (Variable varName varMod) (WrappedValue val) = do   if isFirst     then maybe (return ()) addChar $ modifierPrefix settings     else addChar $ modifierSeparator settings@@ -68,46 +70,60 @@     (MaxLength l) -> do       when (modifierSupportsNamed settings) (namePrefix settings varName val)       -- TODO: this is wrong. we need to truncate prior to encoding.-      censor (fromList . take l . toList) unexploded+      censor (fromList . take l . Data.DList.toList) unexploded   where     settings = options m++    addEncodeString :: String -> StringBuilder ()     addEncodeString = addString . (allowEncoder $ modifierAllow settings)+     sepByCommas = sequence_ . intersperse (addChar ',')-    associativeCommas (n, v) = addEncodeString n >> addChar ',' >> addEncodeString v++    associativeCommas :: (TemplateValue Single, TemplateValue Single) -> StringBuilder ()+    associativeCommas (Single n, Single v) = addEncodeString n >> addChar ',' >> addEncodeString v+     unexploded = case val of-      (AssociativeVal l) -> sepByCommas $ map associativeCommas l-      (ListVal l) -> sepByCommas $ map addEncodeString l-      (SingleVal s) -> addEncodeString s-    explodedAssociative (k, v) = do+      (Associative l) -> sepByCommas $ map associativeCommas l+      (List l) -> sepByCommas $ map (\(Single s) -> addEncodeString s) l+      (Single s) -> addEncodeString s++    explodedAssociative :: (TemplateValue Single, TemplateValue Single) -> StringBuilder ()+    explodedAssociative (Single k, Single v) = do       addEncodeString k       addChar '='       addEncodeString v+           exploded :: StringBuilder ()     exploded = case val of-      (SingleVal s) -> do+      (Single s) -> do         when (modifierSupportsNamed settings) (namePrefix settings varName val)         addEncodeString s-      (AssociativeVal l) -> sequence_ $ intersperse (addChar $ modifierSeparator settings) $ map explodedAssociative l-      (ListVal l) -> sequence_ $ intersperse (addChar $ modifierSeparator settings) $ map addEncodeString l+      (Associative l) -> sequence_ $ intersperse (addChar $ modifierSeparator settings) $ map explodedAssociative l+      (List l) -> sequence_ $ intersperse (addChar $ modifierSeparator settings) $ map (\(Single s) -> addEncodeString s) l -processVariables :: [(String, InternalTemplateValue)] -> Modifier -> [Variable] -> StringBuilder ()+processVariables :: [(String, WrappedValue)] -> Modifier -> [Variable] -> StringBuilder () processVariables env m vs = sequence_ $ processedVariables   where     findValue (Variable varName _) = lookup varName env-    nonEmptyVariables :: [(Variable, InternalTemplateValue)]++    nonEmptyVariables :: [(Variable, WrappedValue)]     nonEmptyVariables = catMaybes $ map (\v -> fmap (\mv -> (v, mv)) $ findValue v) vs-    processors :: [Variable -> InternalTemplateValue -> StringBuilder ()]++    processors :: [Variable -> WrappedValue -> StringBuilder ()]     processors = (processVariable m True) : repeat (processVariable m False)+     processedVariables :: [StringBuilder ()]     processedVariables = zipWith uncurry processors nonEmptyVariables -render :: forall a. UriTemplate -> [(String, TemplateValue a)] -> String-render tpl env = render' tpl $ map (\(l, r) -> (l, internalize r)) env+render :: UriTemplate -> [BoundValue] -> String+render tpl env = render' tpl env -render' :: UriTemplate -> [(String, InternalTemplateValue)] -> String-render' tpl env = toList $ execWriter $ mapM_ go tpl+render' :: UriTemplate -> [BoundValue] -> String+render' tpl env = Data.DList.toList $ execWriter $ mapM_ go tpl   where     go :: TemplateSegment -> StringBuilder ()     go (Literal s) = addString s     go (Embed m vs) = processVariables env m vs-      {-(processVariable m True) : repeat (processVariable m False)-}+++
src/Network/URI/Template/TH.hs view
@@ -9,16 +9,6 @@ import Network.URI.Template.Parser import Network.URI.Template.Types -{--  mTpl <- parse qqInput-  case mTpl of-    Left err -> error err-    Right tpl -> do-      varNames <- distinct <$> getAllVariableNames-      convert varNames to [(varName, toTemplateValue $ varExpr for varName)]-      render tpl convertedValues--}- variableNames :: UriTemplate -> [String] variableNames = nub . foldr go []   where@@ -29,7 +19,11 @@ segmentToExpr (Literal str) = appE (conE 'Literal) (litE $ StringL str) segmentToExpr (Embed m vs) = appE (appE (conE 'Embed) modifier) $ listE $ map variableToExpr vs   where-    modifier = conE $ mkName ("Network.URI.Template.Types." ++ show m)+    modifier = do+      mname <- lookupValueName (show m)+      case mname of+        Nothing -> fail (show m ++ " is not a valid modifier")+        Just n -> conE n     variableToExpr (Variable varName varModifier) = [| Variable $(litE $ StringL varName) $(varModifierE varModifier) |]     varModifierE vm = case vm of       Normal -> conE 'Normal@@ -41,16 +35,7 @@   where     templateValues = listE $ map makePair vns     vns = variableNames ts-    makePair str = [| ($(litE $ StringL str), internalize $ toTemplateValue $ $(varE $ mkName str)) |]---- AppE (VarE 'concat) $ ListE $ concatMap segmentToExp ts--{-segmentToExp (Literal s) = [LitE $ StringL s]-}-{-segmentToExp (Embed m v) = map (AppE prefix . enc . VarE . mkName) v-}-  {-where-}-    {-enc = AppE (VarE $ encoder m)-}-    {--- cons the prefix onto the beginning of each embedded segment-}-    {-prefix = InfixE (Just $ LitE $ CharL $ subsequentSeparator m) (ConE $ '(:)) Nothing-}+    makePair str = [| ($(litE $ StringL str), WrappedValue $ toTemplateValue $ $(varE $ mkName str)) |]  quasiEval :: String -> Q Exp quasiEval str = do
src/Network/URI/Template/Types.hs view
@@ -1,47 +1,78 @@-{-# LANGUAGE EmptyDataDecls, GADTs, FunctionalDependencies, MultiParamTypeClasses, FlexibleContexts, TypeSynonymInstances, FlexibleInstances #-}+{-# LANGUAGE EmptyDataDecls, GADTs, FunctionalDependencies, MultiParamTypeClasses, FlexibleContexts, TypeSynonymInstances, FlexibleInstances, TypeFamilies, OverlappingInstances, GeneralizedNewtypeDeriving #-} module Network.URI.Template.Types where--data SingleElement-data AssociativeListElement-data ListElement+import Control.Arrow+import Data.Foldable as F+import Data.List+import qualified Data.String as S+import qualified Data.HashMap.Strict as HS+import qualified Data.Map.Strict as MS+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Vector as V -newtype ListElem a = ListElem { fromListElem :: a }+data Single+data Associative+data List  data TemplateValue a where-  Single :: String -> TemplateValue SingleElement-  Associative :: [(String, TemplateValue SingleElement)] -> TemplateValue AssociativeListElement-  List :: [TemplateValue SingleElement] -> TemplateValue ListElement+  Single :: String -> TemplateValue Single+  Associative :: [(TemplateValue Single, TemplateValue Single)] -> TemplateValue Associative+  List :: [TemplateValue Single] -> TemplateValue List -data InternalTemplateValue-  = SingleVal String-  | AssociativeVal [(String, String)]-  | ListVal [String]+instance Show (TemplateValue a) where+  show (Single s) = "Single " ++ s+  show (Associative as) = "Associative [" ++ intercalate ", " (map formatTuple as) ++ "]"+    where+      formatTuple (k, v) = "(" ++ show k ++ ", " ++ show v ++ ")"+  show (List s) = "List [" ++ intercalate ", " (map show s) ++ "]" -fromSingle :: TemplateValue SingleElement -> String-fromSingle (Single s) = s+data WrappedValue where+  WrappedValue :: TemplateValue a -> WrappedValue -fromSingleVal :: InternalTemplateValue -> String-fromSingleVal (SingleVal s) = s+newtype TemplateString = String { fromString :: String }+  deriving (Read, Show, Eq, S.IsString) -internalize :: TemplateValue a -> InternalTemplateValue-internalize (Single s) = SingleVal s-internalize (Associative ls) = AssociativeVal $ map (\(l, r) -> (l, fromSingleVal $ internalize r)) ls-internalize (List l) = ListVal $ map (fromSingleVal . internalize) l+newtype AList k v = AList { fromAList :: [(k, v)] } -class ToTemplateValue a e | a -> e where-  toTemplateValue :: a -> TemplateValue e+class ToTemplateValue a where+  type TemplateRep a+  toTemplateValue :: a -> TemplateValue (TemplateRep a) -instance ToTemplateValue Int SingleElement where+instance ToTemplateValue Int where+  type TemplateRep Int = Single   toTemplateValue = Single . show -instance ToTemplateValue a SingleElement => ToTemplateValue (ListElem [a]) ListElement where-  toTemplateValue = List . map toTemplateValue . fromListElem+instance ToTemplateValue TemplateString where+  type TemplateRep TemplateString = Single+  toTemplateValue = Single . fromString -instance ToTemplateValue a SingleElement => ToTemplateValue [(String, a)] AssociativeListElement where-  toTemplateValue = Associative . map (\(l, r) -> (l, toTemplateValue r))+instance (ToTemplateValue a, (TemplateRep a) ~ Single) => ToTemplateValue [a] where+  type TemplateRep [a] = List+  toTemplateValue = List . map toTemplateValue -instance ToTemplateValue String SingleElement where-  toTemplateValue = Single+instance (ToTemplateValue k, (TemplateRep k) ~ Single, ToTemplateValue v, (TemplateRep v) ~ Single) => ToTemplateValue (AList k v) where+  type TemplateRep (AList k v) = Associative+  toTemplateValue = Associative . map (toTemplateValue *** toTemplateValue) . fromAList++instance (ToTemplateValue a, (TemplateRep a) ~ Single) => ToTemplateValue (V.Vector a) where+  type TemplateRep (V.Vector a) = List+  toTemplateValue = List . F.toList . fmap toTemplateValue++instance ToTemplateValue T.Text where+  type TemplateRep T.Text = Single+  toTemplateValue = Single . T.unpack++instance ToTemplateValue TL.Text where+  type TemplateRep TL.Text = Single+  toTemplateValue = Single . TL.unpack++instance (ToTemplateValue k, (TemplateRep k) ~ Single, ToTemplateValue v, (TemplateRep v) ~ Single) => ToTemplateValue (HS.HashMap k v) where+  type TemplateRep (HS.HashMap k v) = Associative+  toTemplateValue = toTemplateValue . AList . HS.toList++instance (ToTemplateValue k, (TemplateRep k) ~ Single, ToTemplateValue v, (TemplateRep v) ~ Single) => ToTemplateValue (MS.Map k v) where+  type TemplateRep (MS.Map k v) = Associative+  toTemplateValue = toTemplateValue . AList . MS.toList  data ValueModifier   = Normal
test/Test.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE QuasiQuotes, OverloadedStrings #-} module Main where+import Control.Arrow import Control.Monad.Writer.Strict import Network.URI.Template.Parser import Network.URI.Template@@ -67,7 +68,7 @@   label "Explode" $ embedTest "{foo*}" "bar"   label "Max Length" $ embedTest "{foo:1}" "b" -embedTestEnv = [("foo", Single "bar")]+embedTestEnv = [("foo", WrappedValue $ Single "bar")]  embedTest :: String -> String -> TestRegistry () embedTest t expect = test $ do@@ -75,20 +76,20 @@   let rendered = render tpl embedTestEnv   rendered @?= expect -var :: String+var :: TemplateString var = "value" -hello :: String+hello :: TemplateString hello = "Hello World!" -path :: String+path :: TemplateString path = "/foo/bar" -list :: ListElem [String]-list = ListElem ["red", "green", "blue"]+list :: [TemplateString]+list = ["red", "green", "blue"] -keys :: [(String, String)]-keys = [("semi", ";"), ("dot", "."), ("comma", ",")]+keys :: AList TemplateString TemplateString+keys = AList [("semi", ";"), ("dot", "."), ("comma", ",")]  quasiQuoterTests = label "QuasiQuoter Tests" $ suite $ do   label "Simple" $ test ([uri|{var}|] @?= "value")
uri-templater.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                uri-templater-version:             0.1.0.0+version:             0.2.0.0 synopsis:            Parsing & Quasiquoting for RFC 6570 URI Templates description:         Parsing & Quasiquoting for RFC 6570 URI Templates homepage:            http://github.com/sanetracker/uri-templater@@ -10,7 +10,7 @@ license-file:        LICENSE author:              Ian Duncan maintainer:          ian@iankduncan.com-copyright:           SaneTracker+copyright:           Ian Duncan category:            Network build-type:          Simple cabal-version:       >=1.8@@ -18,7 +18,6 @@   type:                git   location:            http://github.com/sanetracker/uri-templater - library   exposed-modules:   Network.URI.Template,                      Network.URI.Template.TH,@@ -33,7 +32,11 @@                      HTTP,                      dlist,                      mtl,-                     ansi-wl-pprint+                     ansi-wl-pprint,+                     vector,+                     containers,+                     unordered-containers,+                     text   hs-source-dirs:    src  test-suite test-uri-templates