{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

module Web.OpenWeatherMap.Types.Location
  ( Location(..)
  ) where

import Data.Proxy (Proxy(..))
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8)
import Servant.API ((:>))
import Servant.Client (Client, HasClient, clientWithRoute, hoistClientMonad)
import Servant.Client.Core.Request (Request, appendToQueryString)
import Web.HttpApiData (ToHttpApiData, toQueryParam)

-- | Various ways to specify location.
data Location
  = Name String -- ^ City name.
  | Coord Double Double -- ^ Geographic coordinates: latitude and longitude.

addParam :: ToHttpApiData a => Text -> a -> Request -> Request
addParam :: forall a. ToHttpApiData a => Text -> a -> Request -> Request
addParam Text
name = Text -> Maybe ByteString -> Request -> Request
appendToQueryString Text
name forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToHttpApiData a => a -> Text
toQueryParam

instance HasClient m api => HasClient m (Location :> api) where
  type Client m (Location :> api) = Location -> Client m api
  hoistClientMonad :: forall (mon :: * -> *) (mon' :: * -> *).
Proxy m
-> Proxy (Location :> api)
-> (forall x. mon x -> mon' x)
-> Client mon (Location :> api)
-> Client mon' (Location :> api)
hoistClientMonad Proxy m
pm Proxy (Location :> api)
_ forall x. mon x -> mon' x
f Client mon (Location :> api)
cl = forall (m :: * -> *) api (mon :: * -> *) (mon' :: * -> *).
HasClient m api =>
Proxy m
-> Proxy api
-> (forall x. mon x -> mon' x)
-> Client mon api
-> Client mon' api
hoistClientMonad Proxy m
pm (forall {k} (t :: k). Proxy t
Proxy :: Proxy api) forall x. mon x -> mon' x
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. Client mon (Location :> api)
cl
  clientWithRoute :: Proxy m
-> Proxy (Location :> api) -> Request -> Client m (Location :> api)
clientWithRoute Proxy m
pm Proxy (Location :> api)
Proxy Request
req Location
loc =
    forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
pm (forall {k} (t :: k). Proxy t
Proxy :: Proxy api) (Location -> Request -> Request
addParams Location
loc Request
req)
    where
      addParams :: Location -> Request -> Request
addParams (Name String
q) = forall a. ToHttpApiData a => Text -> a -> Request -> Request
addParam Text
"q" String
q
      addParams (Coord Double
lat Double
lon) = forall a. ToHttpApiData a => Text -> a -> Request -> Request
addParam Text
"lat" Double
lat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToHttpApiData a => Text -> a -> Request -> Request
addParam Text
"lon" Double
lon