{-# LANGUAGE
OverloadedStrings
, RecordWildCards
#-}
module Chevalier.Util where
import qualified Data.ByteString as S
import Data.HashMap.Strict(fromList)
import Data.Locator
import Data.Monoid
import Data.ProtocolBuffers hiding (field)
import Data.Serialize
import Data.Text(splitOn, unpack, append, Text)
import Chevalier.Types
import Vaultaire.Types
-- |Building SourceRequests
buildRequestFromQuery :: SourceQuery -> SourceRequest
buildRequestFromQuery (SourceQuery tags address page page_size _ _) =
SourceRequest
{ requestTags = putField tags
, startPage = putField $ Just $ fromIntegral page
, sourcesPerPage = putField $ Just $ fromIntegral page_size
, addressKey = putField address'
}
where
address' = case address of
"*" -> Nothing
a -> Just $ fromIntegral $ fromBase62 $ unpack a
-- strict
buildTag :: Text -> Text -> SourceTag
buildTag key value = SourceTag
(putField key)
(putField value)
buildRequestFromPairs :: [(Text, Text)] -> SourceRequest
buildRequestFromPairs = buildRequestFromTags . map (uncurry buildTag)
-- fuzzy
buildFuzzyRequestTag :: Text -> Text -> SourceTag
buildFuzzyRequestTag key value = SourceTag
(putField key)
(putField $ "*" <> value <> "*")
buildFuzzyRequestFromPairs :: [(Text, Text)] -> SourceRequest
buildFuzzyRequestFromPairs = buildRequestFromTags . map (uncurry buildFuzzyRequestTag)
-- wild
buildWildcardTag :: Text -> SourceTag
buildWildcardTag value = SourceTag
(putField "*")
(putField $ "*" <> value <> "*")
buildWildRequestFromPairs :: [(Text, Text)] -> SourceRequest
buildWildRequestFromPairs = buildRequestFromTags . map (buildWildcardTag . snd)
wildcardQuery :: [Text] -> SourceRequest
wildcardQuery = buildRequestFromTags . map buildWildcardTag
decodeTag :: SourceTag -> (Text, Text)
decodeTag (SourceTag key value) = (getField key, getField value)
buildRequestFromTags :: [SourceTag] -> SourceRequest
buildRequestFromTags tags =
SourceRequest (putField tags) (putField Nothing) (putField Nothing) (putField Nothing)
buildRequestFromAddress :: Address -> SourceRequest
buildRequestFromAddress (Address address) =
SourceRequest (putField []) (putField Nothing) (putField Nothing) (putField $ Just $ fromIntegral $ address)
-- |Converts a Chevalier Source into a Vaultaire (Address, SourceDict) tuple
convertSource :: Source -> Either String (Address, SourceDict)
convertSource Source{..} =
either
Left
(\sd -> Right (Address . fromIntegral $ getField address, sd))
(makeSourceDict $ fromList $ map decodeTag $ getField tags)
-- |Encodes a SourceRequest into its wire format
encodeRequest :: SourceRequest -> S.ByteString
encodeRequest = runPut . encodeMessage
-- |Decodes a wire format SourceResponse into a list of Sources
decodeResponse :: S.ByteString -> Either ChevalierException [Source]
decodeResponse bs =
case runGet decodeMessage bs of
Left err -> Left $ BurstDecodeFailure err
Right decoded ->
case getField $ chevalierError decoded of
Just err -> Left $ ChevalierFailure err
Nothing -> Right $ getField (sources decoded)