@@ -1,8 +1,10 @@
11{-# LANGUAGE DataKinds #-}
22{-# LANGUAGE FlexibleContexts #-}
33{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE FunctionalDependencies #-}
45{-# LANGUAGE GeneralizedNewtypeDeriving #-}
56{-# LANGUAGE MultiParamTypeClasses #-}
7+{-# LANGUAGE PolyKinds #-}
68{-# LANGUAGE ScopedTypeVariables #-}
79{-# LANGUAGE TypeFamilies #-}
810{-# LANGUAGE UndecidableInstances #-}
@@ -24,71 +26,75 @@
2426-- A 'MonadGoogle' typeclass is used as a function constraint to provide automatic
2527-- lifting of functions when embedding 'Google' as a layer inside your own
2628-- application stack.
27−module Network.Google where
28− -- (
29− -- -- * Running Google Actions
30− -- Google (..)
31− -- , MonadGoogle (..)
32− -- , runGoogle
33− -- , runResourceT
29+module Network.Google
30+ (
31+ -- * Running Google Actions
32+ Google (..)
33+ , MonadGoogle (..)
34+ , runGoogle
35+ , runResourceT
3436
35− -- -- * Authentication and Environment
36− -- , newEnv
37− -- , Env
38− -- , HasEnv (..)
37+ -- * Authentication and Environment
38+ , Env
39+ , HasEnv (..)
40+ , newEnv
3941
40− -- -- * Sending Requests
41− -- , send
42+ -- ** Customized Environment
43+ , newEnvWith
44+ , getApplicationDefault
4245
43− -- -- ** Media Downloads
44− -- , download
46+ -- * Sending Requests
47+ , send
4548
46− -- -- ** Media Uploads
47− -- , upload
49+ -- ** Media Downloads
50+ , download
4851
49− -- , ToBody (..)
50− -- , RequestBody
51− -- , sourceBody
52+ -- ** Media Uploads
53+ , upload
5254
53− -- -- ** Service Configuration
54− -- -- ** Overriding Defaults
55− -- , configure
56− -- , override
55+ , ToBody (..)
56+ , RequestBody
57+ , sourceBody
5758
58− -- -- *** Scoped Actions
59− -- , reconfigure
60− -- , timeout
59+ -- ** Service Configuration
60+ -- ** Overriding Defaults
61+ , configure
62+ , override
6163
62− -- -- * Running Asynchronous Actions
63− -- -- $async
64+ -- *** Scoped Actions
65+ , reconfigure
66+ , timeout
6467
65− -- -- * Handling Errors
66− -- , AsError (..)
67− -- , AsAuthError (..)
68+ -- * Running Asynchronous Actions
69+ -- $async
6870
69− -- , trying
70− -- , catching
71+ -- * Handling Errors
72+ , AsError (..)
73+ , AsAuthError (..)
7174
72− -- -- * Logging
73− -- -- $logging
75+ , trying
76+ , catching
7477
75− -- , Logger
76− -- , LogLevel (..)
78+ -- * Logging
79+ -- $logging
7780
78− -- -- ** Constructing a Logger
79− -- , newLogger
81+ , Logger
82+ , LogLevel (..)
8083
81− -- -- * Constructing a HTTP Manager
82− -- , newManager
83− -- , tlsManagerSettings
84+ -- ** Constructing a Logger
85+ , newLogger
8486
85− -- -- * Re-exported Types
86− -- , Proxy (..)
87− -- , OctetStream
88− -- , PlainText
89− -- , JSON
90− -- , module Network.Google.Types
91− -- ) where
87+ -- * Constructing a HTTP Manager
88+ , newManager
89+ , tlsManagerSettings
90+
91+ -- * Re-exported Types
92+ , Proxy (..)
93+ , OctetStream
94+ , PlainText
95+ , JSON
96+ , module Network.Google.Types
97+ ) where
9298
9399import Control.Applicative
94100import Control.Exception.Lens
@@ -129,131 +135,120 @@ newtype Google s a = Google { unGoogle :: ReaderT (Env s) (ResourceT IO) a }
129135 , MonadCatch
130136 , MonadMask
131137 , MonadBase IO
132−-- , MonadReader (Env s)
138+ , MonadReader (Env s)
133139 , MonadResource
134140 )
135141
136−-- | Run a 'Google' aciton using the specified environment.
137−-- runGoogle :: (MonadResource m, HasEnv s r) => r -> Google s a -> m a
138−-- runGoogle e m = liftResourceT $ runReaderT (unGoogle m) (e ^. environment)
139−
140−runGoogle :: MonadResource m => Env s -> Google s a -> m a
141−runGoogle e m = liftResourceT $ runReaderT (unGoogle m) e
142−
143−test :: IO ()
144−test = runResourceT $ do
145− e <- newEnv
146− runGoogle e $ do
147− Bar <- send Foo
148− pure ()
149−
150−send :: (GoogleRequest a, IsSubList s (Ss a)) => a -> Google s (Rs a)
151−send = undefined
152−
153−-- do
154− -- e <- ask
155− -- r <- perform e x
156− -- hoistError r
157−
158−data Foo = Foo
159−data Bar = Bar
160−
161−instance GoogleRequest Foo where
162− type Rs Foo = Bar
163− type Ss Foo = '[Foo]
164−
165− requestClient = undefined
166−
167−
168−-- instance MonadBaseControl IO Google where
169−-- type StM Google a = StM (ReaderT Env (ResourceT IO)) a
170−
171−-- liftBaseWith f = Google . liftBaseWith $ \g -> f (g . unGoogle)
172−-- restoreM = Google . restoreM
173−
174−-- -- | Monads in which 'Google' actions may be embedded.
175−-- class ( Functor m
176−-- , Applicative m
177−-- , Monad m
178−-- , MonadIO m
179−-- , MonadCatch m
180−-- ) => MonadGoogle m where
181−-- -- | Lift a computation to the 'Google' monad.
182−-- liftGoogle :: Google a -> m a
183−
184−-- instance MonadGoogle Google where
185−-- liftGoogle = id
186−
187−-- instance MonadGoogle m => MonadGoogle (IdentityT m) where liftGoogle = lift . liftGoogle
188−-- instance MonadGoogle m => MonadGoogle (ListT m) where liftGoogle = lift . liftGoogle
189−-- instance MonadGoogle m => MonadGoogle (MaybeT m) where liftGoogle = lift . liftGoogle
190−-- instance MonadGoogle m => MonadGoogle (ExceptT e m) where liftGoogle = lift . liftGoogle
191−-- instance MonadGoogle m => MonadGoogle (ReaderT r m) where liftGoogle = lift . liftGoogle
192−-- instance MonadGoogle m => MonadGoogle (S.StateT s m) where liftGoogle = lift . liftGoogle
193−-- instance MonadGoogle m => MonadGoogle (LS.StateT s m) where liftGoogle = lift . liftGoogle
194−
195−-- instance (Monoid w, MonadGoogle m) => MonadGoogle (W.WriterT w m) where
196−-- liftGoogle = lift . liftGoogle
197−
198−-- instance (Monoid w, MonadGoogle m) => MonadGoogle (LW.WriterT w m) where
199−-- liftGoogle = lift . liftGoogle
200−
201−-- instance (Monoid w, MonadGoogle m) => MonadGoogle (RW.RWST r w s m) where
202−-- liftGoogle = lift . liftGoogle
203−
204−-- instance (Monoid w, MonadGoogle m) => MonadGoogle (LRW.RWST r w s m) where
205−-- liftGoogle = lift . liftGoogle
206−
207−-- -- | Run a 'Google' aciton using the specified environment.
208−-- runGoogle :: (MonadResource m, HasEnv r) => r -> Google a -> m a
209−-- runGoogle e m = liftResourceT $ runReaderT (unGoogle m) (e ^. environment)
210−
211−-- -- | Send a request, returning the associated response if successful.
212−-- --
213−-- -- Throws 'Error'.
214−-- send :: (MonadGoogle m, GoogleRequest a) => a -> m (Rs a)
215−-- send x = liftGoogle $ do
216−-- e <- ask
217−-- r <- perform e x
218−-- hoistError r
219−
220−-- -- | Send a request returning the associated streaming media response if successful.
221−-- --
222−-- -- Some request data types have two possible responses, the JSON metadata and
223−-- -- a streaming media response. Use 'send' to retrieve the metadata and 'download'
224−-- -- to retrieve the streaming media.
225−-- --
226−-- -- Throws 'Error'.
227−-- download :: (MonadGoogle m, GoogleRequest (MediaDownload a))
228−-- => a
229−-- -> m (Rs (MediaDownload a))
230−-- download = send . MediaDownload
231−
232−-- -- | Send a request with an attached multipart/related media upload.
233−-- --
234−-- -- Throws 'Error'.
235−-- upload :: (MonadGoogle m, GoogleRequest (MediaUpload a))
236−-- => a
237−-- -> RequestBody
238−-- -> m (Rs (MediaUpload a))
239−-- upload x = send . MediaUpload x
240−
241−-- hoistError :: MonadThrow m => Either Error a -> m a
242−-- hoistError = either (throwingM _Error) return
243−
244−-- {- $async
245−-- Requests can be sent asynchronously, but due to guarantees about resource closure
246−-- require the use of <http://hackage.haskell.org/package/lifted-async lifted-async>.
247−-- -}
248−
249−-- {- $logging
250−-- The exposed logging interface is a primitive 'Logger' function which gets
251−-- threaded through service calls and serialisation routines. This allows the
252−-- library to output useful information and diagnostics.
253−
254−-- The 'newLogger' function can be used to construct a simple logger which writes
255−-- output to a 'Handle', but in most production code you should probably consider
256−-- using a more robust logging library such as
257−-- <http://hackage.haskell.org/package/tiny-log tiny-log> or
258−-- <http://hackage.haskell.org/package/fast-logger fast-logger>.
259−-- -}
142+-- | Run a 'Google' aciton using the specified environment containing
143+-- credentials with sufficient authorization scopes.
144+runGoogle :: (MonadResource m, HasEnv s r) => r -> Google s a -> m a
145+runGoogle e m = liftResourceT $ runReaderT (unGoogle m) (e ^. environment)
146+
147+-- | Monads in which 'Google' actions may be embedded.
148+class ( Allow s
149+ , Functor m
150+ , Applicative m
151+ , Monad m
152+ , MonadIO m
153+ , MonadCatch m
154+ ) => MonadGoogle s m | m -> s where
155+ -- | Lift a computation to the 'Google' monad.
156+ liftGoogle :: Google s a -> m a
157+
158+instance Allow s => MonadGoogle s (Google s) where
159+ liftGoogle = id
160+
161+instance MonadBaseControl IO (Google s) where
162+ type StM (Google s) a = StM (ReaderT (Env s) (ResourceT IO)) a
163+
164+ liftBaseWith f = Google . liftBaseWith $ \g -> f (g . unGoogle)
165+ restoreM = Google . restoreM
166+
167+instance MonadGoogle s m => MonadGoogle s (IdentityT m) where
168+ liftGoogle = lift . liftGoogle
169+
170+instance MonadGoogle s m => MonadGoogle s (ListT m) where
171+ liftGoogle = lift . liftGoogle
172+
173+instance MonadGoogle s m => MonadGoogle s (MaybeT m) where
174+ liftGoogle = lift . liftGoogle
175+
176+instance MonadGoogle s m => MonadGoogle s (ExceptT e m) where
177+ liftGoogle = lift . liftGoogle
178+
179+instance MonadGoogle s m => MonadGoogle s (ReaderT r m) where
180+ liftGoogle = lift . liftGoogle
181+
182+instance MonadGoogle s m => MonadGoogle s (S.StateT s' m) where
183+ liftGoogle = lift . liftGoogle
184+
185+instance MonadGoogle s m => MonadGoogle s (LS.StateT s' m) where
186+ liftGoogle = lift . liftGoogle
187+
188+instance (Monoid w, MonadGoogle s m) => MonadGoogle s (W.WriterT w m) where
189+ liftGoogle = lift . liftGoogle
190+
191+instance (Monoid w, MonadGoogle s m) => MonadGoogle s (LW.WriterT w m) where
192+ liftGoogle = lift . liftGoogle
193+
194+instance (Monoid w, MonadGoogle s m) => MonadGoogle s (RW.RWST r w s' m) where
195+ liftGoogle = lift . liftGoogle
196+
197+instance (Monoid w, MonadGoogle s m) => MonadGoogle s (LRW.RWST r w s' m) where
198+ liftGoogle = lift . liftGoogle
199+
200+-- | Send a request, returning the associated response if successful.
201+--
202+-- Throws 'Error'.
203+send :: (MonadGoogle s m, Authorize s a, GoogleRequest a) => a -> m (Rs a)
204+send x = liftGoogle $ do
205+ e <- ask
206+ r <- perform e x
207+ hoistError r
208+
209+-- | Send a request returning the associated streaming media response if successful.
210+--
211+-- Some request data types have two possible responses, the JSON metadata and
212+-- a streaming media response. Use 'send' to retrieve the metadata and 'download'
213+-- to retrieve the streaming media.
214+--
215+-- Throws 'Error'.
216+download :: ( MonadGoogle s m
217+ , Authorize s (MediaDownload a)
218+ , GoogleRequest (MediaDownload a)
219+ )
220+ => a
221+ -> m (Rs (MediaDownload a))
222+download = send . MediaDownload
223+
224+-- | Send a request with an attached multipart/related media upload.
225+--
226+-- Throws 'Error'.
227+upload :: ( MonadGoogle s m
228+ , Authorize s (MediaUpload a)
229+ , GoogleRequest (MediaUpload a)
230+ )
231+ => a
232+ -> RequestBody
233+ -> m (Rs (MediaUpload a))
234+upload x = send . MediaUpload x
235+
236+hoistError :: MonadThrow m => Either Error a -> m a
237+hoistError = either (throwingM _Error) return
238+
239+{- $async
240+Requests can be sent asynchronously, but due to guarantees about resource closure
241+require the use of <http://hackage.haskell.org/package/lifted-async lifted-async>.
242+-}
243+
244+{- $logging
245+The exposed logging interface is a primitive 'Logger' function which gets
246+threaded through service calls and serialisation routines. This allows the
247+library to output useful information and diagnostics.
248+
249+The 'newLogger' function can be used to construct a simple logger which writes
250+output to a 'Handle', but in most production code you should probably consider
251+using a more robust logging library such as
252+<http://hackage.haskell.org/package/tiny-log tiny-log> or
253+<http://hackage.haskell.org/package/fast-logger fast-logger>.
254+-}