{-# LANGUAGE CPP #-}
module Database.Redis.URL
( parseConnectInfo
) where
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>))
#endif
import Control.Error.Util (note)
import Control.Monad (guard)
#if __GLASGOW_HASKELL__ < 808
import Data.Monoid ((<>))
#endif
import Database.Redis.Core (ConnectInfo(..), defaultConnectInfo)
import Database.Redis.ProtocolPipelining
import Network.HTTP.Base
import Network.URI (parseURI, uriPath, uriScheme)
import Text.Read (readMaybe)
import qualified Data.ByteString.Char8 as C8
parseConnectInfo :: String -> Either String ConnectInfo
parseConnectInfo url = do
uri <- note "Invalid URI" $ parseURI url
note "Wrong scheme" $ guard $ uriScheme uri == "redis:"
uriAuth <- note "Missing or invalid Authority"
$ parseURIAuthority
$ uriToAuthorityString uri
let h = host uriAuth
dbNumPart = dropWhile (== '/') (uriPath uri)
db <- if null dbNumPart
then return $ connectDatabase defaultConnectInfo
else note ("Invalid port: " <> dbNumPart) $ readMaybe dbNumPart
return defaultConnectInfo
{ connectHost = if null h
then connectHost defaultConnectInfo
else h
, connectPort = maybe (connectPort defaultConnectInfo) (PortNumber . fromIntegral) (port uriAuth)
, connectAuth = C8.pack <$> password uriAuth
, connectDatabase = db
}