module RFC.Google.Places.NearbySearch
( module RFC.Google.Places.NearbySearch
, module RFC.Google.Places.SearchResults
, module RFC.Data.LatLng
, HasAPIClient
) where
import qualified Data.List as List
import qualified Data.Maybe as Maybe
import RFC.Data.LatLng
import RFC.Google.Places.SearchResults
import RFC.HTTP.Client
import RFC.Log
import RFC.Prelude
endpoint :: URL
endpoint =
case importURL endpointStr of
Nothing -> error $ "Could not parse the Google Places API endpoint into a URL: " ++ endpointStr
(Just it) -> it
where
endpointStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"
data Params = Params
{ apiKey :: String
, location :: LatLng
, radiusMeters :: Integer
, rankBy :: RankBy
, keyword :: Maybe String
, language :: Maybe String
, region :: Maybe String
, placeType :: Maybe PlaceType
}
data RankBy = Distance | Prominence
rankByToString :: RankBy -> String
rankByToString Distance = "distance"
rankByToString Prominence = "prominence"
data OptionalParams = OptionalParams
data PlaceType =
Hospital | Doctor
placeTypeToString :: PlaceType -> String
placeTypeToString Hospital = "hospital"
placeTypeToString Doctor = "doctor"
paramsToPairs :: Params -> [(String,String)]
paramsToPairs params =
[ ("key", apiKey params)
, ("location", (show lat) ++ "," ++ (show lng))
, ("radius", show $ radiusMeters params)
, ("rankBy", rankByToString $ rankBy params)
] ++ optionalPairs
where
loc = location params
(lat,lng) = (latitude loc, longitude loc)
toPair = optionalParamToPair params
optionalPairs = Maybe.catMaybes
[ toPair keyword "keyword"
, toPair language "language"
, toPair region "region"
, toPair (fmap placeTypeToString . placeType) "type"
]
optionalParamToPair :: Params -> (Params -> Maybe String) -> String -> Maybe (String,String)
optionalParamToPair param field paramName = (\paramVal -> (paramName, paramVal)) <$> field param
paramsToUrl :: Params -> URL
paramsToUrl params =
List.foldr fold endpoint $ paramsToPairs params
where
fold = flip add_param
query :: (HasAPIClient m, MonadCatch m) => Params -> m Results
query params = apiGet (paramsToUrl params) onError
where
onError :: (MonadIO m) => SomeException -> m Results
onError err = do
logWarn . cs $ "Error performing Google Nearby Search: " ++ (show err)
return $ Results (show err, [])