on develop help sign in
Adding monoid service overrides via dual endofunctors
fe2a1d9Brendan Hay
core/src/Network/Google/Types.hs+18
@@ -184,6 +184,21 @@ defaultService i h p = Service
184 , _svcScopes = []
184 , _svcScopes = []
185 }
185 }
186
186
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+
187-- | An intermediary request builder.
202-- | An intermediary request builder.
188data Request = Request
203data Request = Request
189 { _rqPath :: Builder
204 { _rqPath :: Builder
@@ -230,6 +245,9 @@ data Client a = Client
230 , _cliResponse :: Stream -> ResourceT IO (Either String a)
245 , _cliResponse :: Stream -> ResourceT IO (Either String a)
231 }
246 }
232
247
248+clientService :: Lens' (Client a) Service
249+clientService = lens _cliService (\s a -> s { _cliService = a })
250+
233mime :: FromStream c a => Proxy c -> Method -> [Int] -> Request -> Service -> Client a
251mime :: FromStream c a => Proxy c -> Method -> [Int] -> Request -> Service -> Client a
234mime p = client (fromStream p) (Just (contentType p))
252mime p = client (fromStream p) (Just (contentType p))
235
253
gogol/src/Network/Google/Env.hs+44−10
@@ -13,15 +13,17 @@ import Control.Lens
13import Control.Monad.Catch
13import Control.Monad.Catch
14import Control.Monad.IO.Class
14import Control.Monad.IO.Class
15import Control.Monad.Reader
15import Control.Monad.Reader
16+import Data.Function (on)
17+import Data.Monoid
16import Network.Google.Auth
18import Network.Google.Auth
17import Network.Google.Types
19import Network.Google.Types
18import Network.HTTP.Conduit
20import Network.HTTP.Conduit
19
21
20-- | The environment containing the parameters required to make Google requests.
22-- | The environment containing the parameters required to make Google requests.
21data Env = Env
23data Env = Env
22− { _envTimeout :: !(Maybe Seconds)
24+ { _envOverride :: !(Dual (Endo Service))
23− , _envManager :: !Manager
25+ , _envManager :: !Manager
24− , _envAuth :: !Auth
26+ , _envAuth :: !Auth
25 }
27 }
26
28
27-- Note: The strictness annotations aobe are applied to ensure
29-- Note: The strictness annotations aobe are applied to ensure
@@ -31,8 +33,8 @@ class HasEnv a where
31 environment :: Lens' a Env
33 environment :: Lens' a Env
32 {-# MINIMAL environment #-}
34 {-# MINIMAL environment #-}
33
35
34− -- | TODO
36+ -- | The currently applied overrides to all 'Service' configuration.
35− envTimeout :: Lens' a (Maybe Seconds)
37+ envOverride :: Lens' a (Dual (Endo Service))
36
38
37 -- | The 'Manager' used to create and manage open HTTP connections.
39 -- | The 'Manager' used to create and manage open HTTP connections.
38 envManager :: Lens' a Manager
40 envManager :: Lens' a Manager
@@ -40,13 +42,45 @@ class HasEnv a where
40 -- | The credentials used to sign requests for authentication with Google.
42 -- | The credentials used to sign requests for authentication with Google.
41 envAuth :: Lens' a Auth
43 envAuth :: Lens' a Auth
42
44
43− envTimeout = environment . lens _envTimeout (\s a -> s { _envTimeout = a })
45+ envOverride = environment . lens _envOverride (\s a -> s { _envOverride = a })
44− envManager = environment . lens _envManager (\s a -> s { _envManager = a })
46+ envManager = environment . lens _envManager (\s a -> s { _envManager = a })
45− envAuth = environment . lens _envAuth (\s a -> s { _envAuth = a })
47+ envAuth = environment . lens _envAuth (\s a -> s { _envAuth = a })
46
48
47instance HasEnv Env where
49instance HasEnv Env where
48 environment = id
50 environment = id
49
51
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+
50-- | Scope an action such that any HTTP response will use this timeout value.
84-- | Scope an action such that any HTTP response will use this timeout value.
51--
85--
52-- Default timeouts are chosen by considering:
86-- Default timeouts are chosen by considering:
@@ -59,7 +93,7 @@ instance HasEnv Env where
59--
93--
60-- * The default 'ClientRequest' timeout. (Approximately 30s)
94-- * The default 'ClientRequest' timeout. (Approximately 30s)
61timeout :: (MonadReader r m, HasEnv r) => Seconds -> m a -> m a
95timeout :: (MonadReader r m, HasEnv r) => Seconds -> m a -> m a
62−timeout s = local (envTimeout ?~ s)
96+timeout s = local (override (serviceTimeout ?~ s))
63
97
64-- | Creates a new environment with a new 'Manager' without debug logging
98-- | Creates a new environment with a new 'Manager' without debug logging
65-- and uses 'getAuth' to expand/discover the supplied 'Credentials'.
99-- and uses 'getAuth' to expand/discover the supplied 'Credentials'.
@@ -71,4 +105,4 @@ newEnv c = liftIO (newManager tlsManagerSettings) >>= newEnvWith c
71
105
72-- | /See:/ 'newEnv'
106-- | /See:/ 'newEnv'
73newEnvWith :: (MonadIO m, MonadCatch m) => Credentials -> Manager -> m Env
107newEnvWith :: (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 @@
1{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE TypeFamilies #-}
3
4
4-- |
5-- |
5-- Module : Network.Google.Internal.HTTP
6-- Module : Network.Google.Internal.HTTP
@@ -11,7 +12,7 @@
11--
12--
12module Network.Google.Internal.HTTP where
13module Network.Google.Internal.HTTP where
13
14
14−import Control.Applicative
15+import Control.Lens
15import Control.Monad.Catch
16import Control.Monad.Catch
16import Control.Monad.Trans.Resource
17import Control.Monad.Trans.Resource
17import Data.Default.Class
18import Data.Default.Class
@@ -33,6 +34,12 @@ perform :: (MonadCatch m, MonadResource m, GoogleRequest a)
33 -> m (Either Error (Rs a))
34 -> m (Either Error (Rs a))
34perform Env{..} x = catches go handlers
35perform Env{..} x = catches go handlers
35 where
36 where
37+ Request {..} = _cliRequest
38+ Service {..} = _cliService
39+
40+ Client {..} = requestClient x
41+ & clientService %~ appEndo (getDual _envOverride)
42+
36 go = liftResourceT $ do
43 go = liftResourceT $ do
37 rs <- http rq _envManager
44 rs <- http rq _envManager
38 r <- _cliResponse (responseBody rs)
45 r <- _cliResponse (responseBody rs)
@@ -82,11 +89,7 @@ perform Env{..} x = catches go handlers
82 , _serviceBody = Nothing
89 , _serviceBody = Nothing
83 }
90 }
84
91
85− timeout = microseconds <$> (_envTimeout <|> _svcTimeout)
92+ timeout = microseconds <$> _svcTimeout
86−
87− Request {..} = _cliRequest
88− Service {..} = _cliService
89− Client {..} = requestClient x
90
93
91 handlers =
94 handlers =
92 [ Handler $ err
95 [ Handler $ err