google_groupsmigration1/
api.rs

1#![allow(clippy::ptr_arg)]
2
3use std::collections::{BTreeSet, HashMap};
4
5use tokio::time::sleep;
6
7// ##############
8// UTILITIES ###
9// ############
10
11/// Identifies the an OAuth2 authorization scope.
12/// A scope is needed when requesting an
13/// [authorization token](https://developers.google.com/youtube/v3/guides/authentication).
14#[derive(PartialEq, Eq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
15pub enum Scope {
16    /// Upload messages to any Google group in your domain
17    AppGroupMigration,
18}
19
20impl AsRef<str> for Scope {
21    fn as_ref(&self) -> &str {
22        match *self {
23            Scope::AppGroupMigration => "https://www.googleapis.com/auth/apps.groups.migration",
24        }
25    }
26}
27
28#[allow(clippy::derivable_impls)]
29impl Default for Scope {
30    fn default() -> Scope {
31        Scope::AppGroupMigration
32    }
33}
34
35// ########
36// HUB ###
37// ######
38
39/// Central instance to access all GroupsMigration related resource activities
40///
41/// # Examples
42///
43/// Instantiate a new hub
44///
45/// ```test_harness,no_run
46/// extern crate hyper;
47/// extern crate hyper_rustls;
48/// extern crate google_groupsmigration1 as groupsmigration1;
49/// use groupsmigration1::{Result, Error};
50/// use std::fs;
51/// # async fn dox() {
52/// use groupsmigration1::{GroupsMigration, FieldMask, hyper_rustls, hyper_util, yup_oauth2};
53///
54/// // Get an ApplicationSecret instance by some means. It contains the `client_id` and
55/// // `client_secret`, among other things.
56/// let secret: yup_oauth2::ApplicationSecret = Default::default();
57/// // Instantiate the authenticator. It will choose a suitable authentication flow for you,
58/// // unless you replace  `None` with the desired Flow.
59/// // Provide your own `AuthenticatorDelegate` to adjust the way it operates and get feedback about
60/// // what's going on. You probably want to bring in your own `TokenStorage` to persist tokens and
61/// // retrieve them from storage.
62/// let connector = hyper_rustls::HttpsConnectorBuilder::new()
63///     .with_native_roots()
64///     .unwrap()
65///     .https_only()
66///     .enable_http2()
67///     .build();
68///
69/// let executor = hyper_util::rt::TokioExecutor::new();
70/// let auth = yup_oauth2::InstalledFlowAuthenticator::with_client(
71///     secret,
72///     yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
73///     yup_oauth2::client::CustomHyperClientBuilder::from(
74///         hyper_util::client::legacy::Client::builder(executor).build(connector),
75///     ),
76/// ).build().await.unwrap();
77///
78/// let client = hyper_util::client::legacy::Client::builder(
79///     hyper_util::rt::TokioExecutor::new()
80/// )
81/// .build(
82///     hyper_rustls::HttpsConnectorBuilder::new()
83///         .with_native_roots()
84///         .unwrap()
85///         .https_or_http()
86///         .enable_http2()
87///         .build()
88/// );
89/// let mut hub = GroupsMigration::new(client, auth);
90/// // You can configure optional parameters by calling the respective setters at will, and
91/// // execute the final call using `upload(...)`.
92/// // Values shown here are possibly random and not representative !
93/// let result = hub.archive().insert("groupId")
94///              .upload(fs::File::open("file.ext").unwrap(), "application/octet-stream".parse().unwrap()).await;
95///
96/// match result {
97///     Err(e) => match e {
98///         // The Error enum provides details about what exactly happened.
99///         // You can also just use its `Debug`, `Display` or `Error` traits
100///          Error::HttpError(_)
101///         |Error::Io(_)
102///         |Error::MissingAPIKey
103///         |Error::MissingToken(_)
104///         |Error::Cancelled
105///         |Error::UploadSizeLimitExceeded(_, _)
106///         |Error::Failure(_)
107///         |Error::BadRequest(_)
108///         |Error::FieldClash(_)
109///         |Error::JsonDecodeError(_, _) => println!("{}", e),
110///     },
111///     Ok(res) => println!("Success: {:?}", res),
112/// }
113/// # }
114/// ```
115#[derive(Clone)]
116pub struct GroupsMigration<C> {
117    pub client: common::Client<C>,
118    pub auth: Box<dyn common::GetToken>,
119    _user_agent: String,
120    _base_url: String,
121    _root_url: String,
122}
123
124impl<C> common::Hub for GroupsMigration<C> {}
125
126impl<'a, C> GroupsMigration<C> {
127    pub fn new<A: 'static + common::GetToken>(
128        client: common::Client<C>,
129        auth: A,
130    ) -> GroupsMigration<C> {
131        GroupsMigration {
132            client,
133            auth: Box::new(auth),
134            _user_agent: "google-api-rust-client/7.0.0".to_string(),
135            _base_url: "https://groupsmigration.googleapis.com/".to_string(),
136            _root_url: "https://groupsmigration.googleapis.com/".to_string(),
137        }
138    }
139
140    pub fn archive(&'a self) -> ArchiveMethods<'a, C> {
141        ArchiveMethods { hub: self }
142    }
143
144    /// Set the user-agent header field to use in all requests to the server.
145    /// It defaults to `google-api-rust-client/7.0.0`.
146    ///
147    /// Returns the previously set user-agent.
148    pub fn user_agent(&mut self, agent_name: String) -> String {
149        std::mem::replace(&mut self._user_agent, agent_name)
150    }
151
152    /// Set the base url to use in all requests to the server.
153    /// It defaults to `https://groupsmigration.googleapis.com/`.
154    ///
155    /// Returns the previously set base url.
156    pub fn base_url(&mut self, new_base_url: String) -> String {
157        std::mem::replace(&mut self._base_url, new_base_url)
158    }
159
160    /// Set the root url to use in all requests to the server.
161    /// It defaults to `https://groupsmigration.googleapis.com/`.
162    ///
163    /// Returns the previously set root url.
164    pub fn root_url(&mut self, new_root_url: String) -> String {
165        std::mem::replace(&mut self._root_url, new_root_url)
166    }
167}
168
169// ############
170// SCHEMAS ###
171// ##########
172/// JSON response template for groups migration API.
173///
174/// # Activities
175///
176/// This type is used in activities, which are methods you may call on this type or where this type is involved in.
177/// The list links the activity name, along with information about where it is used (one of *request* and *response*).
178///
179/// * [insert archive](ArchiveInsertCall) (response)
180#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
181#[serde_with::serde_as]
182#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
183pub struct Groups {
184    /// The kind of insert resource this is.
185    pub kind: Option<String>,
186    /// The status of the insert request.
187    #[serde(rename = "responseCode")]
188    pub response_code: Option<String>,
189}
190
191impl common::ResponseResult for Groups {}
192
193// ###################
194// MethodBuilders ###
195// #################
196
197/// A builder providing access to all methods supported on *archive* resources.
198/// It is not used directly, but through the [`GroupsMigration`] hub.
199///
200/// # Example
201///
202/// Instantiate a resource builder
203///
204/// ```test_harness,no_run
205/// extern crate hyper;
206/// extern crate hyper_rustls;
207/// extern crate google_groupsmigration1 as groupsmigration1;
208///
209/// # async fn dox() {
210/// use groupsmigration1::{GroupsMigration, FieldMask, hyper_rustls, hyper_util, yup_oauth2};
211///
212/// let secret: yup_oauth2::ApplicationSecret = Default::default();
213/// let connector = hyper_rustls::HttpsConnectorBuilder::new()
214///     .with_native_roots()
215///     .unwrap()
216///     .https_only()
217///     .enable_http2()
218///     .build();
219///
220/// let executor = hyper_util::rt::TokioExecutor::new();
221/// let auth = yup_oauth2::InstalledFlowAuthenticator::with_client(
222///     secret,
223///     yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
224///     yup_oauth2::client::CustomHyperClientBuilder::from(
225///         hyper_util::client::legacy::Client::builder(executor).build(connector),
226///     ),
227/// ).build().await.unwrap();
228///
229/// let client = hyper_util::client::legacy::Client::builder(
230///     hyper_util::rt::TokioExecutor::new()
231/// )
232/// .build(
233///     hyper_rustls::HttpsConnectorBuilder::new()
234///         .with_native_roots()
235///         .unwrap()
236///         .https_or_http()
237///         .enable_http2()
238///         .build()
239/// );
240/// let mut hub = GroupsMigration::new(client, auth);
241/// // Usually you wouldn't bind this to a variable, but keep calling *CallBuilders*
242/// // like `insert(...)`
243/// // to build up your call.
244/// let rb = hub.archive();
245/// # }
246/// ```
247pub struct ArchiveMethods<'a, C>
248where
249    C: 'a,
250{
251    hub: &'a GroupsMigration<C>,
252}
253
254impl<'a, C> common::MethodsBuilder for ArchiveMethods<'a, C> {}
255
256impl<'a, C> ArchiveMethods<'a, C> {
257    /// Create a builder to help you perform the following task:
258    ///
259    /// Inserts a new mail into the archive of the Google group.
260    ///
261    /// # Arguments
262    ///
263    /// * `groupId` - The group ID
264    pub fn insert(&self, group_id: &str) -> ArchiveInsertCall<'a, C> {
265        ArchiveInsertCall {
266            hub: self.hub,
267            _group_id: group_id.to_string(),
268            _delegate: Default::default(),
269            _additional_params: Default::default(),
270            _scopes: Default::default(),
271        }
272    }
273}
274
275// ###################
276// CallBuilders   ###
277// #################
278
279/// Inserts a new mail into the archive of the Google group.
280///
281/// A builder for the *insert* method supported by a *archive* resource.
282/// It is not used directly, but through a [`ArchiveMethods`] instance.
283///
284/// # Example
285///
286/// Instantiate a resource method builder
287///
288/// ```test_harness,no_run
289/// # extern crate hyper;
290/// # extern crate hyper_rustls;
291/// # extern crate google_groupsmigration1 as groupsmigration1;
292/// use std::fs;
293/// # async fn dox() {
294/// # use groupsmigration1::{GroupsMigration, FieldMask, hyper_rustls, hyper_util, yup_oauth2};
295///
296/// # let secret: yup_oauth2::ApplicationSecret = Default::default();
297/// # let connector = hyper_rustls::HttpsConnectorBuilder::new()
298/// #     .with_native_roots()
299/// #     .unwrap()
300/// #     .https_only()
301/// #     .enable_http2()
302/// #     .build();
303///
304/// # let executor = hyper_util::rt::TokioExecutor::new();
305/// # let auth = yup_oauth2::InstalledFlowAuthenticator::with_client(
306/// #     secret,
307/// #     yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
308/// #     yup_oauth2::client::CustomHyperClientBuilder::from(
309/// #         hyper_util::client::legacy::Client::builder(executor).build(connector),
310/// #     ),
311/// # ).build().await.unwrap();
312///
313/// # let client = hyper_util::client::legacy::Client::builder(
314/// #     hyper_util::rt::TokioExecutor::new()
315/// # )
316/// # .build(
317/// #     hyper_rustls::HttpsConnectorBuilder::new()
318/// #         .with_native_roots()
319/// #         .unwrap()
320/// #         .https_or_http()
321/// #         .enable_http2()
322/// #         .build()
323/// # );
324/// # let mut hub = GroupsMigration::new(client, auth);
325/// // You can configure optional parameters by calling the respective setters at will, and
326/// // execute the final call using `upload(...)`.
327/// // Values shown here are possibly random and not representative !
328/// let result = hub.archive().insert("groupId")
329///              .upload(fs::File::open("file.ext").unwrap(), "application/octet-stream".parse().unwrap()).await;
330/// # }
331/// ```
332pub struct ArchiveInsertCall<'a, C>
333where
334    C: 'a,
335{
336    hub: &'a GroupsMigration<C>,
337    _group_id: String,
338    _delegate: Option<&'a mut dyn common::Delegate>,
339    _additional_params: HashMap<String, String>,
340    _scopes: BTreeSet<String>,
341}
342
343impl<'a, C> common::CallBuilder for ArchiveInsertCall<'a, C> {}
344
345impl<'a, C> ArchiveInsertCall<'a, C>
346where
347    C: common::Connector,
348{
349    /// Perform the operation you have build so far.
350    async fn doit<RS>(
351        mut self,
352        mut reader: RS,
353        reader_mime_type: mime::Mime,
354        protocol: common::UploadProtocol,
355    ) -> common::Result<(common::Response, Groups)>
356    where
357        RS: common::ReadSeek,
358    {
359        use std::borrow::Cow;
360        use std::io::{Read, Seek};
361
362        use common::{url::Params, ToParts};
363        use hyper::header::{AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, LOCATION, USER_AGENT};
364
365        let mut dd = common::DefaultDelegate;
366        let mut dlg: &mut dyn common::Delegate = self._delegate.unwrap_or(&mut dd);
367        dlg.begin(common::MethodInfo {
368            id: "groupsmigration.archive.insert",
369            http_method: hyper::Method::POST,
370        });
371
372        for &field in ["alt", "groupId"].iter() {
373            if self._additional_params.contains_key(field) {
374                dlg.finished(false);
375                return Err(common::Error::FieldClash(field));
376            }
377        }
378
379        let mut params = Params::with_capacity(3 + self._additional_params.len());
380        params.push("groupId", self._group_id);
381
382        params.extend(self._additional_params.iter());
383
384        params.push("alt", "json");
385        let (mut url, upload_type) = if protocol == common::UploadProtocol::Simple {
386            (
387                self.hub._root_url.clone() + "upload/groups/v1/groups/{groupId}/archive",
388                "multipart",
389            )
390        } else {
391            unreachable!()
392        };
393        params.push("uploadType", upload_type);
394        if self._scopes.is_empty() {
395            self._scopes
396                .insert(Scope::AppGroupMigration.as_ref().to_string());
397        }
398
399        #[allow(clippy::single_element_loop)]
400        for &(find_this, param_name) in [("{groupId}", "groupId")].iter() {
401            url = params.uri_replacement(url, param_name, find_this, false);
402        }
403        {
404            let to_remove = ["groupId"];
405            params.remove_params(&to_remove);
406        }
407
408        let url = params.parse_with_url(&url);
409
410        loop {
411            let token = match self
412                .hub
413                .auth
414                .get_token(&self._scopes.iter().map(String::as_str).collect::<Vec<_>>()[..])
415                .await
416            {
417                Ok(token) => token,
418                Err(e) => match dlg.token(e) {
419                    Ok(token) => token,
420                    Err(e) => {
421                        dlg.finished(false);
422                        return Err(common::Error::MissingToken(e));
423                    }
424                },
425            };
426            let mut req_result = {
427                let client = &self.hub.client;
428                dlg.pre_request();
429                let mut req_builder = hyper::Request::builder()
430                    .method(hyper::Method::POST)
431                    .uri(url.as_str())
432                    .header(USER_AGENT, self.hub._user_agent.clone());
433
434                if let Some(token) = token.as_ref() {
435                    req_builder = req_builder.header(AUTHORIZATION, format!("Bearer {}", token));
436                }
437
438                let request = if protocol == common::UploadProtocol::Simple {
439                    let size = reader.seek(std::io::SeekFrom::End(0)).unwrap();
440                    reader.seek(std::io::SeekFrom::Start(0)).unwrap();
441                    if size > 26214400 {
442                        return Err(common::Error::UploadSizeLimitExceeded(size, 26214400));
443                    }
444                    let mut bytes = Vec::with_capacity(size as usize);
445                    reader.read_to_end(&mut bytes)?;
446                    req_builder
447                        .header(CONTENT_TYPE, reader_mime_type.to_string())
448                        .header(CONTENT_LENGTH, size)
449                        .body(common::to_body(bytes.into()))
450                } else {
451                    req_builder.body(common::to_body::<String>(None))
452                };
453
454                client.request(request.unwrap()).await
455            };
456
457            match req_result {
458                Err(err) => {
459                    if let common::Retry::After(d) = dlg.http_error(&err) {
460                        sleep(d).await;
461                        continue;
462                    }
463                    dlg.finished(false);
464                    return Err(common::Error::HttpError(err));
465                }
466                Ok(res) => {
467                    let (mut parts, body) = res.into_parts();
468                    let mut body = common::Body::new(body);
469                    if !parts.status.is_success() {
470                        let bytes = common::to_bytes(body).await.unwrap_or_default();
471                        let error = serde_json::from_str(&common::to_string(&bytes));
472                        let response = common::to_response(parts, bytes.into());
473
474                        if let common::Retry::After(d) =
475                            dlg.http_failure(&response, error.as_ref().ok())
476                        {
477                            sleep(d).await;
478                            continue;
479                        }
480
481                        dlg.finished(false);
482
483                        return Err(match error {
484                            Ok(value) => common::Error::BadRequest(value),
485                            _ => common::Error::Failure(response),
486                        });
487                    }
488                    let response = {
489                        let bytes = common::to_bytes(body).await.unwrap_or_default();
490                        let encoded = common::to_string(&bytes);
491                        match serde_json::from_str(&encoded) {
492                            Ok(decoded) => (common::to_response(parts, bytes.into()), decoded),
493                            Err(error) => {
494                                dlg.response_json_decode_error(&encoded, &error);
495                                return Err(common::Error::JsonDecodeError(
496                                    encoded.to_string(),
497                                    error,
498                                ));
499                            }
500                        }
501                    };
502
503                    dlg.finished(true);
504                    return Ok(response);
505                }
506            }
507        }
508    }
509
510    /// Upload media all at once.
511    /// If the upload fails for whichever reason, all progress is lost.
512    ///
513    /// * *multipart*: yes
514    /// * *max size*: 26214400
515    /// * *valid mime types*: 'message/rfc822'
516    pub async fn upload<RS>(
517        self,
518        stream: RS,
519        mime_type: mime::Mime,
520    ) -> common::Result<(common::Response, Groups)>
521    where
522        RS: common::ReadSeek,
523    {
524        self.doit(stream, mime_type, common::UploadProtocol::Simple)
525            .await
526    }
527
528    /// The group ID
529    ///
530    /// Sets the *group id* path property to the given value.
531    ///
532    /// Even though the property as already been set when instantiating this call,
533    /// we provide this method for API completeness.
534    pub fn group_id(mut self, new_value: &str) -> ArchiveInsertCall<'a, C> {
535        self._group_id = new_value.to_string();
536        self
537    }
538    /// The delegate implementation is consulted whenever there is an intermediate result, or if something goes wrong
539    /// while executing the actual API request.
540    ///
541    /// ````text
542    ///                   It should be used to handle progress information, and to implement a certain level of resilience.
543    /// ````
544    ///
545    /// Sets the *delegate* property to the given value.
546    pub fn delegate(mut self, new_value: &'a mut dyn common::Delegate) -> ArchiveInsertCall<'a, C> {
547        self._delegate = Some(new_value);
548        self
549    }
550
551    /// Set any additional parameter of the query string used in the request.
552    /// It should be used to set parameters which are not yet available through their own
553    /// setters.
554    ///
555    /// Please note that this method must not be used to set any of the known parameters
556    /// which have their own setter method. If done anyway, the request will fail.
557    ///
558    /// # Additional Parameters
559    ///
560    /// * *$.xgafv* (query-string) - V1 error format.
561    /// * *access_token* (query-string) - OAuth access token.
562    /// * *alt* (query-string) - Data format for response.
563    /// * *callback* (query-string) - JSONP
564    /// * *fields* (query-string) - Selector specifying which fields to include in a partial response.
565    /// * *key* (query-string) - API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.
566    /// * *oauth_token* (query-string) - OAuth 2.0 token for the current user.
567    /// * *prettyPrint* (query-boolean) - Returns response with indentations and line breaks.
568    /// * *quotaUser* (query-string) - Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters.
569    /// * *uploadType* (query-string) - Legacy upload protocol for media (e.g. "media", "multipart").
570    /// * *upload_protocol* (query-string) - Upload protocol for media (e.g. "raw", "multipart").
571    pub fn param<T>(mut self, name: T, value: T) -> ArchiveInsertCall<'a, C>
572    where
573        T: AsRef<str>,
574    {
575        self._additional_params
576            .insert(name.as_ref().to_string(), value.as_ref().to_string());
577        self
578    }
579
580    /// Identifies the authorization scope for the method you are building.
581    ///
582    /// Use this method to actively specify which scope should be used, instead of the default [`Scope`] variant
583    /// [`Scope::AppGroupMigration`].
584    ///
585    /// The `scope` will be added to a set of scopes. This is important as one can maintain access
586    /// tokens for more than one scope.
587    ///
588    /// Usually there is more than one suitable scope to authorize an operation, some of which may
589    /// encompass more rights than others. For example, for listing resources, a *read-only* scope will be
590    /// sufficient, a read-write scope will do as well.
591    pub fn add_scope<St>(mut self, scope: St) -> ArchiveInsertCall<'a, C>
592    where
593        St: AsRef<str>,
594    {
595        self._scopes.insert(String::from(scope.as_ref()));
596        self
597    }
598    /// Identifies the authorization scope(s) for the method you are building.
599    ///
600    /// See [`Self::add_scope()`] for details.
601    pub fn add_scopes<I, St>(mut self, scopes: I) -> ArchiveInsertCall<'a, C>
602    where
603        I: IntoIterator<Item = St>,
604        St: AsRef<str>,
605    {
606        self._scopes
607            .extend(scopes.into_iter().map(|s| String::from(s.as_ref())));
608        self
609    }
610
611    /// Removes all scopes, and no default scope will be used either.
612    /// In this case, you have to specify your API-key using the `key` parameter (see [`Self::param()`]
613    /// for details).
614    pub fn clear_scopes(mut self) -> ArchiveInsertCall<'a, C> {
615        self._scopes.clear();
616        self
617    }
618}