on develop help sign in
Adding monoid service overrides via dual endofunctors
commitfe2a1d91ccc57dcf808596ba73cc26380b80f3b0 authorBrendan Hay <brendan.g.hay@gmail.com> dateThu 15 Oct 2015, 14:40 (11 years ago) parent8b0f8ee
3 files changed+71−16
core/src/Network/Google/Types.hs+18 gogol/src/Network/Google/Env.hs+44−10 gogol/src/Network/Google/Internal/HTTP.hs+9−6
core/src/Network/Google/Types.hs+18
@@ -184,6 +184,21 @@ defaultService i h p = Service
184184 , _svcScopes = []
185185 }
186186
187+serviceHost :: Lens' Service ByteString
188+serviceHost = lens _svcHost (\s a -> s { _svcHost = a })
189+
190+servicePath :: Lens' Service Builder
191+servicePath = lens _svcPath (\s a -> s { _svcPath = a })
192+
193+servicePort :: Lens' Service Int
194+servicePort = lens _svcPort (\s a -> s { _svcPort = a })
195+
196+serviceSecure :: Lens' Service Bool
197+serviceSecure = lens _svcSecure (\s a -> s { _svcSecure = a })
198+
199+serviceTimeout :: Lens' Service (Maybe Seconds)
200+serviceTimeout = lens _svcTimeout (\s a -> s { _svcTimeout = a })
201+
187202-- | An intermediary request builder.
188203data Request = Request
189204 { _rqPath :: Builder
@@ -230,6 +245,9 @@ data Client a = Client
230245 , _cliResponse :: Stream -> ResourceT IO (Either String a)
231246 }
232247
248+clientService :: Lens' (Client a) Service
249+clientService = lens _cliService (\s a -> s { _cliService = a })
250+
233251mime :: FromStream c a => Proxy c -> Method -> [Int] -> Request -> Service -> Client a
234252mime p = client (fromStream p) (Just (contentType p))
235253
gogol/src/Network/Google/Env.hs+44−10
@@ -13,15 +13,17 @@ import Control.Lens
1313import Control.Monad.Catch
1414import Control.Monad.IO.Class
1515import Control.Monad.Reader
16+import Data.Function (on)
17+import Data.Monoid
1618import Network.Google.Auth
1719import Network.Google.Types
1820import Network.HTTP.Conduit
1921
2022-- | The environment containing the parameters required to make Google requests.
2123data Env = Env
22− { _envTimeout :: !(Maybe Seconds)
23− , _envManager :: !Manager
24− , _envAuth :: !Auth
24+ { _envOverride :: !(Dual (Endo Service))
25+ , _envManager :: !Manager
26+ , _envAuth :: !Auth
2527 }
2628
2729-- Note: The strictness annotations aobe are applied to ensure
@@ -31,8 +33,8 @@ class HasEnv a where
3133 environment :: Lens' a Env
3234 {-# MINIMAL environment #-}
3335
34− -- | TODO
35− envTimeout :: Lens' a (Maybe Seconds)
36+ -- | The currently applied overrides to all 'Service' configuration.
37+ envOverride :: Lens' a (Dual (Endo Service))
3638
3739 -- | The 'Manager' used to create and manage open HTTP connections.
3840 envManager :: Lens' a Manager
@@ -40,13 +42,45 @@ class HasEnv a where
4042 -- | The credentials used to sign requests for authentication with Google.
4143 envAuth :: Lens' a Auth
4244
43− envTimeout = environment . lens _envTimeout (\s a -> s { _envTimeout = a })
44− envManager = environment . lens _envManager (\s a -> s { _envManager = a })
45− envAuth = environment . lens _envAuth (\s a -> s { _envAuth = a })
45+ envOverride = environment . lens _envOverride (\s a -> s { _envOverride = a })
46+ envManager = environment . lens _envManager (\s a -> s { _envManager = a })
47+ envAuth = environment . lens _envAuth (\s a -> s { _envAuth = a })
4648
4749instance HasEnv Env where
4850 environment = id
4951
52+-- | Provide a function which will be added to the existing stack
53+-- of overrides applied to all service configuration.
54+--
55+-- To override a specific service, it's suggested you use
56+-- either 'configure' or 'reconfigure' with a modified version of the default
57+-- service, such as @Network.Google.Gmail.gmail@.
58+override :: HasEnv a => (Service -> Service) -> a -> a
59+override f = envOverride <>~ Dual (Endo f)
60+
61+-- | Configure a specific service. All requests belonging to the
62+-- supplied service will use this configuration instead of the default.
63+--
64+-- It's suggested you use a modified version of the default service, such
65+-- as @Network.Google.Gmail.gmail@.
66+--
67+-- /See:/ 'reconfigure'.
68+configure :: HasEnv a => Service -> a -> a
69+configure s = override f
70+ where
71+ f x | on (==) _svcId s x = s
72+ | otherwise = x
73+
74+-- | Scope an action such that all requests belonging to the supplied service
75+-- will use this configuration instead of the default.
76+--
77+-- It's suggested you use a modified version of the default service, such
78+-- as @Network.Google.Gmail.gmail@.
79+--
80+-- /See:/ 'configure'.
81+reconfigure :: (MonadReader r m, HasEnv r) => Service -> m a -> m a
82+reconfigure = local . configure
83+
5084-- | Scope an action such that any HTTP response will use this timeout value.
5185--
5286-- Default timeouts are chosen by considering:
@@ -59,7 +93,7 @@ instance HasEnv Env where
5993--
6094-- * The default 'ClientRequest' timeout. (Approximately 30s)
6195timeout :: (MonadReader r m, HasEnv r) => Seconds -> m a -> m a
62−timeout s = local (envTimeout ?~ s)
96+timeout s = local (override (serviceTimeout ?~ s))
6397
6498-- | Creates a new environment with a new 'Manager' without debug logging
6599-- and uses 'getAuth' to expand/discover the supplied 'Credentials'.
@@ -71,4 +105,4 @@ newEnv c = liftIO (newManager tlsManagerSettings) >>= newEnvWith c
71105
72106-- | /See:/ 'newEnv'
73107newEnvWith :: (MonadIO m, MonadCatch m) => Credentials -> Manager -> m Env
74−newEnvWith c m = Env Nothing m <$> getAuth m c
108+newEnvWith c m = Env mempty m <$> getAuth m c
gogol/src/Network/Google/Internal/HTTP.hs+9−6
@@ -1,5 +1,6 @@
11{-# LANGUAGE FlexibleContexts #-}
22{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE TypeFamilies #-}
34
45-- |
56-- Module : Network.Google.Internal.HTTP
@@ -11,7 +12,7 @@
1112--
1213module Network.Google.Internal.HTTP where
1314
14−import Control.Applicative
15+import Control.Lens
1516import Control.Monad.Catch
1617import Control.Monad.Trans.Resource
1718import Data.Default.Class
@@ -33,6 +34,12 @@ perform :: (MonadCatch m, MonadResource m, GoogleRequest a)
3334 -> m (Either Error (Rs a))
3435perform Env{..} x = catches go handlers
3536 where
37+ Request {..} = _cliRequest
38+ Service {..} = _cliService
39+
40+ Client {..} = requestClient x
41+ & clientService %~ appEndo (getDual _envOverride)
42+
3643 go = liftResourceT $ do
3744 rs <- http rq _envManager
3845 r <- _cliResponse (responseBody rs)
@@ -82,11 +89,7 @@ perform Env{..} x = catches go handlers
8289 , _serviceBody = Nothing
8390 }
8491
85− timeout = microseconds <$> (_envTimeout <|> _svcTimeout)
86−
87− Request {..} = _cliRequest
88− Service {..} = _cliService
89− Client {..} = requestClient x
92+ timeout = microseconds <$> _svcTimeout
9093
9194 handlers =
9295 [ Handler $ err