module Bird.Request.QueryStringParser( parseQueryString ) where import Text.ParserCombinators.Parsec import Numeric parseQueryString :: String -> [(String, Maybe String)] parseQueryString q = case (parse (keyValuePair `sepBy` char '&') "Exception: Invalid Query String" q) of Left e -> error $ show e Right queryMap -> queryMap keyValuePair = do k <- many1 keyCharacters v <- optionMaybe (char '=' >> many valueCharacters) return (k, v) keyCharacters :: CharParser () Char keyCharacters = oneOf urlBaseChars <|> (char '+' >> return ' ') <|> hexValue where urlBaseChars = ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ "$-_.!*'()," valueCharacters = keyCharacters hexValue :: CharParser () Char hexValue = do char '%' a <- hexDigit b <- hexDigit let ((d, _):_) = readHex [a,b] return . toEnum $ d