module Simplex.Messaging.Agent.QueryString ( QueryStringParams (..), QSPEscaping (..), queryParam, queryParamParser, queryParam_, queryParamStr, ) where import Data.Attoparsec.ByteString.Char8 (Parser) import qualified Data.Attoparsec.ByteString.Char8 as A import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as B import Data.List (find) import qualified Network.HTTP.Types as Q import Simplex.Messaging.Encoding.String import Simplex.Messaging.Parsers (parseAll) data QueryStringParams = QSP QSPEscaping Q.SimpleQuery deriving (Show) data QSPEscaping = QEscape | QNoEscaping deriving (Show) instance StrEncoding QueryStringParams where strEncode (QSP esc q) = case esc of QEscape -> Q.renderSimpleQuery False q QNoEscaping -> Q.renderQueryPartialEscape False $ map (\(n, v) -> (n, [Q.QN v])) q strP = QSP QEscape . Q.parseSimpleQuery <$> A.takeTill (\c -> c == ' ' || c == '\n') queryParam :: StrEncoding a => ByteString -> QueryStringParams -> Parser a queryParam = queryParamParser strP queryParamParser :: Parser a -> ByteString -> QueryStringParams -> Parser a queryParamParser p name q = case queryParamStr name q of Just s -> either fail pure $ parseAll p s _ -> fail $ "no qs param " <> B.unpack name queryParam_ :: StrEncoding a => ByteString -> QueryStringParams -> Parser (Maybe a) queryParam_ name q = case queryParamStr name q of Just p -> either fail pure $ parseAll strP p _ -> pure Nothing queryParamStr :: ByteString -> QueryStringParams -> Maybe ByteString queryParamStr name (QSP _ q) = snd <$> find ((== name) . fst) q