Skip to main content

io_msgraph/v1/
client.rs

1//! Std-blocking Microsoft Graph client: wraps a `Read + Write` stream
2//! plus the bearer credential and runs the coroutines against
3//! `graph.microsoft.com`. Gated behind the `client` feature.
4
5#[cfg(any(
6    feature = "rustls-aws",
7    feature = "rustls-ring",
8    feature = "native-tls"
9))]
10use core::time::Duration;
11use core::{any::Any, error::Error, fmt};
12
13use alloc::{
14    boxed::Box,
15    string::{String, ToString},
16    vec::Vec,
17};
18use std::io::{self, Read, Write};
19
20use io_http::rfc6750::bearer::HttpAuthBearer;
21/// TLS backend selection re-exported from pimalaya-stream, feeding
22/// [`MsgraphClientStdConnectOptions::tls`].
23#[cfg(any(
24    feature = "rustls-aws",
25    feature = "rustls-ring",
26    feature = "native-tls"
27))]
28pub use pimalaya_stream::tls::*;
29#[cfg(any(
30    feature = "rustls-aws",
31    feature = "rustls-ring",
32    feature = "native-tls"
33))]
34use pimalaya_stream::{
35    proxy::Proxy,
36    stream::{Stream, TcpConnectOptions, TlsConnectOptions},
37};
38#[cfg(any(
39    feature = "rustls-aws",
40    feature = "rustls-ring",
41    feature = "native-tls"
42))]
43use url::Url;
44
45#[cfg(any(
46    feature = "rustls-aws",
47    feature = "rustls-ring",
48    feature = "native-tls"
49))]
50use crate::v1::send::MSGRAPH_API_BASE;
51use crate::{
52    coroutine::*,
53    v1::rest::batch::{MsgraphBatch, MsgraphBatchRequest, MsgraphBatchResponses},
54    v1::rest::users::{
55        MsgraphUser,
56        calendars::{
57            MsgraphCalendar,
58            create::MsgraphCalendarCreate,
59            delete::MsgraphCalendarDelete,
60            get::MsgraphCalendarGet,
61            list::{
62                MsgraphCalendarsList, MsgraphCalendarsListParams, MsgraphCalendarsListResponse,
63            },
64            update::MsgraphCalendarUpdate,
65        },
66        contact_folders::{
67            MsgraphContactFolder,
68            child_folders::MsgraphContactChildFoldersList,
69            create::MsgraphContactFolderCreate,
70            delete::MsgraphContactFolderDelete,
71            get::MsgraphContactFolderGet,
72            list::{
73                MsgraphContactFoldersList, MsgraphContactFoldersListParams,
74                MsgraphContactFoldersListResponse,
75            },
76            update::MsgraphContactFolderUpdate,
77        },
78        contacts::{
79            MsgraphContact,
80            create::MsgraphContactCreate,
81            delete::MsgraphContactDelete,
82            delta::{MsgraphContactsDelta, MsgraphContactsDeltaResponse},
83            get::MsgraphContactGet,
84            list::{MsgraphContactsList, MsgraphContactsListParams, MsgraphContactsListResponse},
85            update::MsgraphContactUpdate,
86        },
87        events::{
88            MsgraphEvent,
89            calendar_view::MsgraphCalendarView,
90            create::MsgraphEventCreate,
91            delete::MsgraphEventDelete,
92            delta::{MsgraphEventsDelta, MsgraphEventsDeltaResponse},
93            get::MsgraphEventGet,
94            instances::MsgraphEventInstances,
95            list::{MsgraphEventsList, MsgraphEventsListParams, MsgraphEventsListResponse},
96            update::MsgraphEventUpdate,
97        },
98        get::MsgraphUserGet,
99        mail_folders::{
100            MsgraphMailFolder,
101            child_folders::MsgraphMailChildFoldersList,
102            copy::MsgraphMailFolderCopy,
103            create::MsgraphMailFolderCreate,
104            delete::MsgraphMailFolderDelete,
105            get::MsgraphMailFolderGet,
106            list::{
107                MsgraphMailFoldersList, MsgraphMailFoldersListParams,
108                MsgraphMailFoldersListResponse,
109            },
110            r#move::MsgraphMailFolderMove,
111            update::MsgraphMailFolderUpdate,
112        },
113        messages::{
114            MsgraphMessage,
115            attachments::{
116                MsgraphAttachment,
117                create::MsgraphAttachmentCreate,
118                delete::MsgraphAttachmentDelete,
119                get_raw::MsgraphAttachmentGetRaw,
120                list::{MsgraphAttachmentsList, MsgraphAttachmentsListResponse},
121            },
122            copy::MsgraphMessageCopy,
123            create::MsgraphMessageCreate,
124            create_mime::MsgraphMessageCreateMime,
125            delete::MsgraphMessageDelete,
126            delta::{
127                MsgraphMessagesDelta, MsgraphMessagesDeltaParams, MsgraphMessagesDeltaResponse,
128            },
129            get::MsgraphMessageGet,
130            get_raw::MsgraphMessageGetRaw,
131            list::{MsgraphMessagesList, MsgraphMessagesListParams, MsgraphMessagesListResponse},
132            r#move::MsgraphMessageMove,
133            send::MsgraphMessageSend,
134            update::MsgraphMessageUpdate,
135        },
136        send_mail::{MsgraphMailSend, MsgraphMailSendMime},
137    },
138    v1::send::{MsgraphNoResponse, MsgraphSendError, MsgraphSendOutput},
139};
140
141/// Error returned by [`MsgraphClientStd`] operations.
142#[derive(Debug)]
143pub enum MsgraphClientStdError {
144    /// A coroutine completed with an error.
145    Send(MsgraphSendError),
146    /// Reading from or writing to the stream failed.
147    Io(io::Error),
148    /// Opening the TCP/TLS connection failed.
149    #[cfg(any(
150        feature = "rustls-aws",
151        feature = "rustls-ring",
152        feature = "native-tls"
153    ))]
154    Tls(anyhow::Error),
155    /// The API base URL has no host to connect to.
156    #[cfg(any(
157        feature = "rustls-aws",
158        feature = "rustls-ring",
159        feature = "native-tls"
160    ))]
161    UrlMissingHost(String),
162    /// The API base URL scheme is neither http nor https.
163    #[cfg(any(
164        feature = "rustls-aws",
165        feature = "rustls-ring",
166        feature = "native-tls"
167    ))]
168    UrlUnsupportedScheme {
169        /// The rejected API base URL.
170        url: String,
171        /// The scheme of the rejected URL.
172        scheme: String,
173    },
174}
175
176impl fmt::Display for MsgraphClientStdError {
177    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178        match self {
179            Self::Send(err) => err.fmt(f),
180            Self::Io(err) => err.fmt(f),
181            #[cfg(any(
182                feature = "rustls-aws",
183                feature = "rustls-ring",
184                feature = "native-tls"
185            ))]
186            Self::Tls(err) => err.fmt(f),
187            #[cfg(any(
188                feature = "rustls-aws",
189                feature = "rustls-ring",
190                feature = "native-tls"
191            ))]
192            Self::UrlMissingHost(url) => write!(f, "Microsoft Graph URL `{url}` has no host"),
193            #[cfg(any(
194                feature = "rustls-aws",
195                feature = "rustls-ring",
196                feature = "native-tls"
197            ))]
198            Self::UrlUnsupportedScheme { url, scheme } => write!(
199                f,
200                "Microsoft Graph URL `{url}` has unsupported scheme `{scheme}` (expected `http` or `https`)"
201            ),
202        }
203    }
204}
205
206impl Error for MsgraphClientStdError {
207    fn source(&self) -> Option<&(dyn Error + 'static)> {
208        match self {
209            Self::Send(err) => err.source(),
210            Self::Io(err) => err.source(),
211            #[cfg(any(
212                feature = "rustls-aws",
213                feature = "rustls-ring",
214                feature = "native-tls"
215            ))]
216            Self::Tls(err) => err.source(),
217            #[cfg(any(
218                feature = "rustls-aws",
219                feature = "rustls-ring",
220                feature = "native-tls"
221            ))]
222            _ => None,
223        }
224    }
225}
226
227impl From<MsgraphSendError> for MsgraphClientStdError {
228    fn from(err: MsgraphSendError) -> Self {
229        Self::Send(err)
230    }
231}
232
233impl From<io::Error> for MsgraphClientStdError {
234    fn from(err: io::Error) -> Self {
235        Self::Io(err)
236    }
237}
238
239#[cfg(any(
240    feature = "rustls-aws",
241    feature = "rustls-ring",
242    feature = "native-tls"
243))]
244impl From<anyhow::Error> for MsgraphClientStdError {
245    fn from(err: anyhow::Error) -> Self {
246        Self::Tls(err)
247    }
248}
249
250/// Optional settings for [`MsgraphClientStd::connect`]; every field has a
251/// default (the TLS backend default, and `me` as the mailbox owner).
252pub struct MsgraphClientStdConnectOptions {
253    /// The TLS backend configuration used to open the connection.
254    #[cfg(any(
255        feature = "rustls-aws",
256        feature = "rustls-ring",
257        feature = "native-tls"
258    ))]
259    pub tls: Tls,
260    /// How the connection reaches the API: [`Proxy::System`] resolves it
261    /// from the environment, [`Proxy::None`] connects directly.
262    #[cfg(any(
263        feature = "rustls-aws",
264        feature = "rustls-ring",
265        feature = "native-tls"
266    ))]
267    pub proxy: Proxy,
268    /// The mailbox owner: `me`, a user id or a principal name.
269    pub user_id: String,
270}
271
272impl Default for MsgraphClientStdConnectOptions {
273    fn default() -> Self {
274        Self {
275            #[cfg(any(
276                feature = "rustls-aws",
277                feature = "rustls-ring",
278                feature = "native-tls"
279            ))]
280            tls: Tls::default(),
281            #[cfg(any(
282                feature = "rustls-aws",
283                feature = "rustls-ring",
284                feature = "native-tls"
285            ))]
286            proxy: Proxy::default(),
287            user_id: String::from("me"),
288        }
289    }
290}
291
292const READ_BUFFER_SIZE: usize = 16 * 1024;
293
294/// Std blocking Microsoft Graph client: a stream, the bearer
295/// credential and the mailbox owner, with one method per operation.
296pub struct MsgraphClientStd {
297    /// The stream carrying the HTTPS connection to the Graph API.
298    pub stream: Box<dyn MsgraphStream>,
299    /// The bearer credential added to every request.
300    pub auth: HttpAuthBearer,
301    /// The mailbox owner: `me`, a user id or a principal name.
302    pub user_id: String,
303}
304
305impl MsgraphClientStd {
306    /// Builds a client over a caller-managed stream.
307    pub fn new<S: Read + Write + Send + 'static>(
308        stream: S,
309        token: impl ToString,
310        options: MsgraphClientStdConnectOptions,
311    ) -> Self {
312        Self {
313            stream: Box::new(stream),
314            auth: HttpAuthBearer::new(token.to_string()),
315            user_id: options.user_id,
316        }
317    }
318
319    /// Builds a client by opening a TCP/TLS connection to the Graph
320    /// API endpoint through pimalaya-stream.
321    #[cfg(any(
322        feature = "rustls-aws",
323        feature = "rustls-ring",
324        feature = "native-tls"
325    ))]
326    pub fn connect(
327        token: impl ToString,
328        options: MsgraphClientStdConnectOptions,
329    ) -> Result<Self, MsgraphClientStdError> {
330        let MsgraphClientStdConnectOptions {
331            tls,
332            proxy,
333            user_id,
334        } = options;
335
336        let url = Url::parse(MSGRAPH_API_BASE).expect("Microsoft Graph API base URL is valid");
337        let host = url
338            .host_str()
339            .ok_or_else(|| MsgraphClientStdError::UrlMissingHost(url.to_string()))?;
340
341        let stream = match url.scheme() {
342            "http" => {
343                let port = url.port().unwrap_or(80);
344                let opts = TcpConnectOptions {
345                    proxy,
346                    ..Default::default()
347                };
348
349                Stream::connect_tcp(host, port, opts)?
350            }
351            "https" => {
352                let port = url.port().unwrap_or(443);
353                let opts = TlsConnectOptions {
354                    tls: tls.clone(),
355                    proxy,
356                    ..Default::default()
357                };
358
359                Stream::connect_tls(host, port, opts)?
360            }
361            scheme => {
362                return Err(MsgraphClientStdError::UrlUnsupportedScheme {
363                    url: url.to_string(),
364                    scheme: scheme.to_string(),
365                });
366            }
367        };
368
369        stream.set_read_timeout(Some(Duration::from_secs(30)))?;
370
371        Ok(Self {
372            stream: Box::new(stream),
373            auth: HttpAuthBearer::new(token.to_string()),
374            user_id,
375        })
376    }
377
378    /// Replaces the underlying stream (e.g. after a connection reset).
379    pub fn set_stream<S: Read + Write + Send + 'static>(&mut self, stream: S) {
380        self.stream = Box::new(stream);
381    }
382
383    /// Runs the given coroutine to completion against the stream,
384    /// fulfilling its read and write requests.
385    pub fn run<C, T>(
386        &mut self,
387        mut coroutine: C,
388    ) -> Result<MsgraphSendOutput<T>, MsgraphClientStdError>
389    where
390        C: MsgraphCoroutine<
391                Yield = MsgraphYield,
392                Return = Result<MsgraphSendOutput<T>, MsgraphSendError>,
393            >,
394    {
395        let mut buf = [0u8; READ_BUFFER_SIZE];
396        let mut arg: Option<&[u8]> = None;
397
398        loop {
399            match coroutine.resume(arg.take()) {
400                MsgraphCoroutineState::Complete(Ok(out)) => return Ok(out),
401                MsgraphCoroutineState::Complete(Err(err)) => return Err(err.into()),
402                MsgraphCoroutineState::Yielded(MsgraphYield::WantsRead) => {
403                    let n = self.stream.read(&mut buf)?;
404                    arg = Some(&buf[..n]);
405                }
406                MsgraphCoroutineState::Yielded(MsgraphYield::WantsWrite(bytes)) => {
407                    self.stream.write_all(&bytes)?;
408                    arg = None;
409                }
410            }
411        }
412    }
413
414    /// Sends several requests in one HTTP call.
415    pub fn batch(
416        &mut self,
417        requests: &[MsgraphBatchRequest],
418    ) -> Result<MsgraphSendOutput<MsgraphBatchResponses>, MsgraphClientStdError> {
419        let coroutine = MsgraphBatch::new(&self.auth, requests)?;
420        self.run(coroutine)
421    }
422
423    /// Gets the profile of the mailbox owner.
424    pub fn me(&mut self) -> Result<MsgraphSendOutput<MsgraphUser>, MsgraphClientStdError> {
425        let coroutine = MsgraphUserGet::new(&self.auth, &self.user_id)?;
426        self.run(coroutine)
427    }
428
429    /// Lists the mail folders of the mailbox.
430    pub fn mail_folders_list(
431        &mut self,
432        params: &MsgraphMailFoldersListParams,
433    ) -> Result<MsgraphSendOutput<MsgraphMailFoldersListResponse>, MsgraphClientStdError> {
434        let coroutine = MsgraphMailFoldersList::new(&self.auth, &self.user_id, params)?;
435        self.run(coroutine)
436    }
437
438    /// Gets a mail folder by id.
439    pub fn mail_folder_get(
440        &mut self,
441        id: &str,
442    ) -> Result<MsgraphSendOutput<MsgraphMailFolder>, MsgraphClientStdError> {
443        let coroutine = MsgraphMailFolderGet::new(&self.auth, &self.user_id, id)?;
444        self.run(coroutine)
445    }
446
447    /// Creates a mail folder.
448    pub fn mail_folder_create(
449        &mut self,
450        folder: &MsgraphMailFolder,
451    ) -> Result<MsgraphSendOutput<MsgraphMailFolder>, MsgraphClientStdError> {
452        let coroutine = MsgraphMailFolderCreate::new(&self.auth, &self.user_id, folder)?;
453        self.run(coroutine)
454    }
455
456    /// Updates a mail folder by id.
457    pub fn mail_folder_update(
458        &mut self,
459        id: &str,
460        folder: &MsgraphMailFolder,
461    ) -> Result<MsgraphSendOutput<MsgraphMailFolder>, MsgraphClientStdError> {
462        let coroutine = MsgraphMailFolderUpdate::new(&self.auth, &self.user_id, id, folder)?;
463        self.run(coroutine)
464    }
465
466    /// Deletes a mail folder by id.
467    pub fn mail_folder_delete(
468        &mut self,
469        id: &str,
470    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
471        let coroutine = MsgraphMailFolderDelete::new(&self.auth, &self.user_id, id)?;
472        self.run(coroutine)
473    }
474
475    /// Copies a mail folder into a destination folder.
476    pub fn mail_folder_copy(
477        &mut self,
478        id: &str,
479        destination: &str,
480    ) -> Result<MsgraphSendOutput<MsgraphMailFolder>, MsgraphClientStdError> {
481        let coroutine = MsgraphMailFolderCopy::new(&self.auth, &self.user_id, id, destination)?;
482        self.run(coroutine)
483    }
484
485    /// Moves a mail folder into a destination folder.
486    pub fn mail_folder_move(
487        &mut self,
488        id: &str,
489        destination: &str,
490    ) -> Result<MsgraphSendOutput<MsgraphMailFolder>, MsgraphClientStdError> {
491        let coroutine = MsgraphMailFolderMove::new(&self.auth, &self.user_id, id, destination)?;
492        self.run(coroutine)
493    }
494
495    /// Lists the child folders of a mail folder.
496    pub fn mail_child_folders_list(
497        &mut self,
498        id: &str,
499        params: &MsgraphMailFoldersListParams,
500    ) -> Result<MsgraphSendOutput<MsgraphMailFoldersListResponse>, MsgraphClientStdError> {
501        let coroutine = MsgraphMailChildFoldersList::new(&self.auth, &self.user_id, id, params)?;
502        self.run(coroutine)
503    }
504
505    /// Lists the contact folders of the mailbox.
506    pub fn contact_folders_list(
507        &mut self,
508        params: &MsgraphContactFoldersListParams,
509    ) -> Result<MsgraphSendOutput<MsgraphContactFoldersListResponse>, MsgraphClientStdError> {
510        let coroutine = MsgraphContactFoldersList::new(&self.auth, &self.user_id, params)?;
511        self.run(coroutine)
512    }
513
514    /// Gets a contact folder by id.
515    pub fn contact_folder_get(
516        &mut self,
517        id: &str,
518    ) -> Result<MsgraphSendOutput<MsgraphContactFolder>, MsgraphClientStdError> {
519        let coroutine = MsgraphContactFolderGet::new(&self.auth, &self.user_id, id)?;
520        self.run(coroutine)
521    }
522
523    /// Creates a contact folder.
524    pub fn contact_folder_create(
525        &mut self,
526        folder: &MsgraphContactFolder,
527    ) -> Result<MsgraphSendOutput<MsgraphContactFolder>, MsgraphClientStdError> {
528        let coroutine = MsgraphContactFolderCreate::new(&self.auth, &self.user_id, folder)?;
529        self.run(coroutine)
530    }
531
532    /// Updates a contact folder by id.
533    pub fn contact_folder_update(
534        &mut self,
535        id: &str,
536        folder: &MsgraphContactFolder,
537    ) -> Result<MsgraphSendOutput<MsgraphContactFolder>, MsgraphClientStdError> {
538        let coroutine = MsgraphContactFolderUpdate::new(&self.auth, &self.user_id, id, folder)?;
539        self.run(coroutine)
540    }
541
542    /// Deletes a contact folder by id.
543    pub fn contact_folder_delete(
544        &mut self,
545        id: &str,
546    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
547        let coroutine = MsgraphContactFolderDelete::new(&self.auth, &self.user_id, id)?;
548        self.run(coroutine)
549    }
550
551    /// Lists the child folders of a contact folder.
552    pub fn contact_child_folders_list(
553        &mut self,
554        id: &str,
555        params: &MsgraphContactFoldersListParams,
556    ) -> Result<MsgraphSendOutput<MsgraphContactFoldersListResponse>, MsgraphClientStdError> {
557        let coroutine = MsgraphContactChildFoldersList::new(&self.auth, &self.user_id, id, params)?;
558        self.run(coroutine)
559    }
560
561    /// Lists the contacts of the default Contacts folder, or of the
562    /// given contact folder.
563    pub fn contacts_list(
564        &mut self,
565        folder: Option<&str>,
566        params: &MsgraphContactsListParams,
567    ) -> Result<MsgraphSendOutput<MsgraphContactsListResponse>, MsgraphClientStdError> {
568        let coroutine = MsgraphContactsList::new(&self.auth, &self.user_id, folder, params)?;
569        self.run(coroutine)
570    }
571
572    /// Gets a contact by id, optionally expanding the given relations.
573    pub fn contact_get(
574        &mut self,
575        id: &str,
576        expand: Option<&str>,
577    ) -> Result<MsgraphSendOutput<MsgraphContact>, MsgraphClientStdError> {
578        let coroutine = MsgraphContactGet::new(&self.auth, &self.user_id, id, expand)?;
579        self.run(coroutine)
580    }
581
582    /// Creates a contact in the default Contacts folder, or in the
583    /// given contact folder.
584    pub fn contact_create(
585        &mut self,
586        folder: Option<&str>,
587        contact: &MsgraphContact,
588    ) -> Result<MsgraphSendOutput<MsgraphContact>, MsgraphClientStdError> {
589        let coroutine = MsgraphContactCreate::new(&self.auth, &self.user_id, folder, contact)?;
590        self.run(coroutine)
591    }
592
593    /// Updates a contact by id.
594    pub fn contact_update(
595        &mut self,
596        id: &str,
597        contact: &MsgraphContact,
598    ) -> Result<MsgraphSendOutput<MsgraphContact>, MsgraphClientStdError> {
599        let coroutine = MsgraphContactUpdate::new(&self.auth, &self.user_id, id, contact)?;
600        self.run(coroutine)
601    }
602
603    /// Deletes a contact by id.
604    pub fn contact_delete(
605        &mut self,
606        id: &str,
607    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
608        let coroutine = MsgraphContactDelete::new(&self.auth, &self.user_id, id)?;
609        self.run(coroutine)
610    }
611
612    /// Starts a contacts delta round over the default Contacts folder,
613    /// or over the given contact folder.
614    pub fn contacts_delta(
615        &mut self,
616        folder: Option<&str>,
617        select: Option<&str>,
618    ) -> Result<MsgraphSendOutput<MsgraphContactsDeltaResponse>, MsgraphClientStdError> {
619        let coroutine = MsgraphContactsDelta::new(&self.auth, &self.user_id, folder, select)?;
620        self.run(coroutine)
621    }
622
623    /// Continues a contacts delta round from an `@odata.nextLink`, or
624    /// starts the next round from a saved `@odata.deltaLink`.
625    pub fn contacts_delta_from_link(
626        &mut self,
627        link: &str,
628    ) -> Result<MsgraphSendOutput<MsgraphContactsDeltaResponse>, MsgraphClientStdError> {
629        let coroutine = MsgraphContactsDelta::from_link(&self.auth, link)?;
630        self.run(coroutine)
631    }
632
633    /// Starts a contacts delta round like
634    /// [`contacts_delta`](Self::contacts_delta), asking for at most
635    /// `max_page_size` contacts per page when given.
636    pub fn contacts_delta_with_page_size(
637        &mut self,
638        folder: Option<&str>,
639        select: Option<&str>,
640        max_page_size: Option<u32>,
641    ) -> Result<MsgraphSendOutput<MsgraphContactsDeltaResponse>, MsgraphClientStdError> {
642        let mut coroutine = MsgraphContactsDelta::new(&self.auth, &self.user_id, folder, select)?;
643        if let Some(size) = max_page_size {
644            coroutine = coroutine.max_page_size(size);
645        }
646        self.run(coroutine)
647    }
648
649    /// Follows a contacts delta link like
650    /// [`contacts_delta_from_link`](Self::contacts_delta_from_link),
651    /// asking for at most `max_page_size` items per page when given.
652    pub fn contacts_delta_from_link_with_page_size(
653        &mut self,
654        link: &str,
655        max_page_size: Option<u32>,
656    ) -> Result<MsgraphSendOutput<MsgraphContactsDeltaResponse>, MsgraphClientStdError> {
657        let mut coroutine = MsgraphContactsDelta::from_link(&self.auth, link)?;
658        if let Some(size) = max_page_size {
659            coroutine = coroutine.max_page_size(size);
660        }
661        self.run(coroutine)
662    }
663
664    /// Lists the user's calendars.
665    pub fn calendars_list(
666        &mut self,
667        params: &MsgraphCalendarsListParams,
668    ) -> Result<MsgraphSendOutput<MsgraphCalendarsListResponse>, MsgraphClientStdError> {
669        let coroutine = MsgraphCalendarsList::new(&self.auth, &self.user_id, params)?;
670        self.run(coroutine)
671    }
672
673    /// Gets the calendar `id`.
674    pub fn calendar_get(
675        &mut self,
676        id: &str,
677    ) -> Result<MsgraphSendOutput<MsgraphCalendar>, MsgraphClientStdError> {
678        let coroutine = MsgraphCalendarGet::new(&self.auth, &self.user_id, id)?;
679        self.run(coroutine)
680    }
681
682    /// Creates a calendar.
683    pub fn calendar_create(
684        &mut self,
685        calendar: &MsgraphCalendar,
686    ) -> Result<MsgraphSendOutput<MsgraphCalendar>, MsgraphClientStdError> {
687        let coroutine = MsgraphCalendarCreate::new(&self.auth, &self.user_id, calendar)?;
688        self.run(coroutine)
689    }
690
691    /// Patches the calendar `id`.
692    pub fn calendar_update(
693        &mut self,
694        id: &str,
695        calendar: &MsgraphCalendar,
696    ) -> Result<MsgraphSendOutput<MsgraphCalendar>, MsgraphClientStdError> {
697        let coroutine = MsgraphCalendarUpdate::new(&self.auth, &self.user_id, id, calendar)?;
698        self.run(coroutine)
699    }
700
701    /// Deletes the calendar `id`.
702    pub fn calendar_delete(
703        &mut self,
704        id: &str,
705    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
706        let coroutine = MsgraphCalendarDelete::new(&self.auth, &self.user_id, id)?;
707        self.run(coroutine)
708    }
709
710    /// Lists the lone events and series masters of a calendar, the default
711    /// one when `calendar` is `None`.
712    pub fn events_list(
713        &mut self,
714        calendar: Option<&str>,
715        params: &MsgraphEventsListParams,
716    ) -> Result<MsgraphSendOutput<MsgraphEventsListResponse>, MsgraphClientStdError> {
717        let coroutine = MsgraphEventsList::new(&self.auth, &self.user_id, calendar, params)?;
718        self.run(coroutine)
719    }
720
721    /// Continues an events listing from an `@odata.nextLink`.
722    pub fn events_list_from_link(
723        &mut self,
724        link: &str,
725    ) -> Result<MsgraphSendOutput<MsgraphEventsListResponse>, MsgraphClientStdError> {
726        let coroutine = MsgraphEventsList::from_link(&self.auth, link)?;
727        self.run(coroutine)
728    }
729
730    /// Gets the event `id`, selecting `select` and expanding `expand` when
731    /// given.
732    pub fn event_get(
733        &mut self,
734        id: &str,
735        select: Option<&str>,
736        expand: Option<&str>,
737    ) -> Result<MsgraphSendOutput<MsgraphEvent>, MsgraphClientStdError> {
738        let coroutine = MsgraphEventGet::new(&self.auth, &self.user_id, id, select, expand)?;
739        self.run(coroutine)
740    }
741
742    /// Creates an event in a calendar, the default one when `calendar` is
743    /// `None`.
744    pub fn event_create(
745        &mut self,
746        calendar: Option<&str>,
747        event: &MsgraphEvent,
748    ) -> Result<MsgraphSendOutput<MsgraphEvent>, MsgraphClientStdError> {
749        let coroutine = MsgraphEventCreate::new(&self.auth, &self.user_id, calendar, event)?;
750        self.run(coroutine)
751    }
752
753    /// Patches the event `id`.
754    pub fn event_update(
755        &mut self,
756        id: &str,
757        event: &MsgraphEvent,
758    ) -> Result<MsgraphSendOutput<MsgraphEvent>, MsgraphClientStdError> {
759        let coroutine = MsgraphEventUpdate::new(&self.auth, &self.user_id, id, event)?;
760        self.run(coroutine)
761    }
762
763    /// Deletes the event `id`, the whole series for a series master.
764    pub fn event_delete(
765        &mut self,
766        id: &str,
767    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
768        let coroutine = MsgraphEventDelete::new(&self.auth, &self.user_id, id)?;
769        self.run(coroutine)
770    }
771
772    /// Lists the instances of the series master `id` within a window.
773    pub fn event_instances(
774        &mut self,
775        id: &str,
776        start: &str,
777        end: &str,
778        params: &MsgraphEventsListParams,
779    ) -> Result<MsgraphSendOutput<MsgraphEventsListResponse>, MsgraphClientStdError> {
780        let coroutine =
781            MsgraphEventInstances::new(&self.auth, &self.user_id, id, start, end, params)?;
782        self.run(coroutine)
783    }
784
785    /// Lists a calendar view, every event expanded within a window.
786    pub fn calendar_view(
787        &mut self,
788        calendar: Option<&str>,
789        start: &str,
790        end: &str,
791        params: &MsgraphEventsListParams,
792    ) -> Result<MsgraphSendOutput<MsgraphEventsListResponse>, MsgraphClientStdError> {
793        let coroutine =
794            MsgraphCalendarView::new(&self.auth, &self.user_id, calendar, start, end, params)?;
795        self.run(coroutine)
796    }
797
798    /// Starts a calendar view delta round over a window.
799    pub fn events_delta(
800        &mut self,
801        calendar: Option<&str>,
802        start: &str,
803        end: &str,
804    ) -> Result<MsgraphSendOutput<MsgraphEventsDeltaResponse>, MsgraphClientStdError> {
805        let coroutine = MsgraphEventsDelta::new(&self.auth, &self.user_id, calendar, start, end)?;
806        self.run(coroutine)
807    }
808
809    /// Continues or restarts a calendar view delta round from a link.
810    pub fn events_delta_from_link(
811        &mut self,
812        link: &str,
813    ) -> Result<MsgraphSendOutput<MsgraphEventsDeltaResponse>, MsgraphClientStdError> {
814        let coroutine = MsgraphEventsDelta::from_link(&self.auth, link)?;
815        self.run(coroutine)
816    }
817
818    /// Starts a calendar view delta round like
819    /// [`events_delta`](Self::events_delta), asking for at most
820    /// `max_page_size` events per page when given.
821    pub fn events_delta_with_page_size(
822        &mut self,
823        calendar: Option<&str>,
824        start: &str,
825        end: &str,
826        max_page_size: Option<u32>,
827    ) -> Result<MsgraphSendOutput<MsgraphEventsDeltaResponse>, MsgraphClientStdError> {
828        let mut coroutine =
829            MsgraphEventsDelta::new(&self.auth, &self.user_id, calendar, start, end)?;
830        if let Some(size) = max_page_size {
831            coroutine = coroutine.max_page_size(size);
832        }
833        self.run(coroutine)
834    }
835
836    /// Follows a calendar view delta link like
837    /// [`events_delta_from_link`](Self::events_delta_from_link),
838    /// asking for at most `max_page_size` items per page when given.
839    pub fn events_delta_from_link_with_page_size(
840        &mut self,
841        link: &str,
842        max_page_size: Option<u32>,
843    ) -> Result<MsgraphSendOutput<MsgraphEventsDeltaResponse>, MsgraphClientStdError> {
844        let mut coroutine = MsgraphEventsDelta::from_link(&self.auth, link)?;
845        if let Some(size) = max_page_size {
846            coroutine = coroutine.max_page_size(size);
847        }
848        self.run(coroutine)
849    }
850
851    /// Lists the messages of the whole mailbox, or of the given mail
852    /// folder.
853    pub fn messages_list(
854        &mut self,
855        folder: Option<&str>,
856        params: &MsgraphMessagesListParams,
857    ) -> Result<MsgraphSendOutput<MsgraphMessagesListResponse>, MsgraphClientStdError> {
858        let coroutine = MsgraphMessagesList::new(&self.auth, &self.user_id, folder, params)?;
859        self.run(coroutine)
860    }
861
862    /// Gets a message by id.
863    pub fn message_get(
864        &mut self,
865        id: &str,
866    ) -> Result<MsgraphSendOutput<MsgraphMessage>, MsgraphClientStdError> {
867        let coroutine = MsgraphMessageGet::new(&self.auth, &self.user_id, id)?;
868        self.run(coroutine)
869    }
870
871    /// Gets the raw RFC 5322 MIME content of a message by id.
872    pub fn message_get_raw(
873        &mut self,
874        id: &str,
875    ) -> Result<MsgraphSendOutput<Vec<u8>>, MsgraphClientStdError> {
876        let coroutine = MsgraphMessageGetRaw::new(&self.auth, &self.user_id, id)?;
877        self.run(coroutine)
878    }
879
880    /// Creates a draft message from JSON in the Drafts folder, or in
881    /// the given mail folder.
882    pub fn message_create(
883        &mut self,
884        folder: Option<&str>,
885        message: &MsgraphMessage,
886    ) -> Result<MsgraphSendOutput<MsgraphMessage>, MsgraphClientStdError> {
887        let coroutine = MsgraphMessageCreate::new(&self.auth, &self.user_id, folder, message)?;
888        self.run(coroutine)
889    }
890
891    /// Creates a draft message from raw RFC 5322 MIME bytes in the
892    /// Drafts folder, or in the given mail folder.
893    pub fn message_create_mime(
894        &mut self,
895        folder: Option<&str>,
896        raw: &[u8],
897    ) -> Result<MsgraphSendOutput<MsgraphMessage>, MsgraphClientStdError> {
898        let coroutine = MsgraphMessageCreateMime::new(&self.auth, &self.user_id, folder, raw)?;
899        self.run(coroutine)
900    }
901
902    /// Updates a message by id.
903    pub fn message_update(
904        &mut self,
905        id: &str,
906        message: &MsgraphMessage,
907    ) -> Result<MsgraphSendOutput<MsgraphMessage>, MsgraphClientStdError> {
908        let coroutine = MsgraphMessageUpdate::new(&self.auth, &self.user_id, id, message)?;
909        self.run(coroutine)
910    }
911
912    /// Deletes a message by id.
913    pub fn message_delete(
914        &mut self,
915        id: &str,
916    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
917        let coroutine = MsgraphMessageDelete::new(&self.auth, &self.user_id, id)?;
918        self.run(coroutine)
919    }
920
921    /// Moves a message into a destination folder.
922    pub fn message_move(
923        &mut self,
924        id: &str,
925        destination: &str,
926    ) -> Result<MsgraphSendOutput<MsgraphMessage>, MsgraphClientStdError> {
927        let coroutine = MsgraphMessageMove::new(&self.auth, &self.user_id, id, destination)?;
928        self.run(coroutine)
929    }
930
931    /// Copies a message into a destination folder.
932    pub fn message_copy(
933        &mut self,
934        id: &str,
935        destination: &str,
936    ) -> Result<MsgraphSendOutput<MsgraphMessage>, MsgraphClientStdError> {
937        let coroutine = MsgraphMessageCopy::new(&self.auth, &self.user_id, id, destination)?;
938        self.run(coroutine)
939    }
940
941    /// Starts a messages delta round over the whole mailbox, or over
942    /// the given mail folder.
943    pub fn messages_delta(
944        &mut self,
945        folder: Option<&str>,
946        select: Option<&str>,
947    ) -> Result<MsgraphSendOutput<MsgraphMessagesDeltaResponse>, MsgraphClientStdError> {
948        let coroutine = MsgraphMessagesDelta::new(&self.auth, &self.user_id, folder, select)?;
949        self.run(coroutine)
950    }
951
952    /// Continues a messages delta round from an `@odata.nextLink`, or
953    /// starts the next round from a saved `@odata.deltaLink`.
954    pub fn messages_delta_from_link(
955        &mut self,
956        link: &str,
957    ) -> Result<MsgraphSendOutput<MsgraphMessagesDeltaResponse>, MsgraphClientStdError> {
958        let coroutine = MsgraphMessagesDelta::from_link(&self.auth, link)?;
959        self.run(coroutine)
960    }
961
962    /// Starts a messages delta round with the OData options and page
963    /// size of `params`.
964    pub fn messages_delta_with_params(
965        &mut self,
966        folder: Option<&str>,
967        params: &MsgraphMessagesDeltaParams,
968    ) -> Result<MsgraphSendOutput<MsgraphMessagesDeltaResponse>, MsgraphClientStdError> {
969        let coroutine =
970            MsgraphMessagesDelta::with_params(&self.auth, &self.user_id, folder, params)?;
971        self.run(coroutine)
972    }
973
974    /// Follows a messages delta link like
975    /// [`messages_delta_from_link`](Self::messages_delta_from_link),
976    /// asking for at most `max_page_size` messages per page when given.
977    pub fn messages_delta_from_link_with_page_size(
978        &mut self,
979        link: &str,
980        max_page_size: Option<u32>,
981    ) -> Result<MsgraphSendOutput<MsgraphMessagesDeltaResponse>, MsgraphClientStdError> {
982        let mut coroutine = MsgraphMessagesDelta::from_link(&self.auth, link)?;
983        if let Some(size) = max_page_size {
984            coroutine = coroutine.max_page_size(size);
985        }
986        self.run(coroutine)
987    }
988
989    /// Creates a file attachment on a message.
990    pub fn attachment_create(
991        &mut self,
992        message_id: &str,
993        name: &str,
994        content: &[u8],
995        content_type: Option<&str>,
996    ) -> Result<MsgraphSendOutput<MsgraphAttachment>, MsgraphClientStdError> {
997        let coroutine = MsgraphAttachmentCreate::new(
998            &self.auth,
999            &self.user_id,
1000            message_id,
1001            name,
1002            content,
1003            content_type,
1004        )?;
1005        self.run(coroutine)
1006    }
1007
1008    /// Lists the attachments of a message.
1009    pub fn attachments_list(
1010        &mut self,
1011        message_id: &str,
1012    ) -> Result<MsgraphSendOutput<MsgraphAttachmentsListResponse>, MsgraphClientStdError> {
1013        let coroutine = MsgraphAttachmentsList::new(&self.auth, &self.user_id, message_id)?;
1014        self.run(coroutine)
1015    }
1016
1017    /// Gets the raw content of an attachment.
1018    pub fn attachment_get_raw(
1019        &mut self,
1020        message_id: &str,
1021        attachment_id: &str,
1022    ) -> Result<MsgraphSendOutput<Vec<u8>>, MsgraphClientStdError> {
1023        let coroutine =
1024            MsgraphAttachmentGetRaw::new(&self.auth, &self.user_id, message_id, attachment_id)?;
1025        self.run(coroutine)
1026    }
1027
1028    /// Deletes an attachment of a message.
1029    pub fn attachment_delete(
1030        &mut self,
1031        message_id: &str,
1032        attachment_id: &str,
1033    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
1034        let coroutine =
1035            MsgraphAttachmentDelete::new(&self.auth, &self.user_id, message_id, attachment_id)?;
1036        self.run(coroutine)
1037    }
1038
1039    /// Sends an existing draft message by id.
1040    pub fn message_send(
1041        &mut self,
1042        id: &str,
1043    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
1044        let coroutine = MsgraphMessageSend::new(&self.auth, &self.user_id, id)?;
1045        self.run(coroutine)
1046    }
1047
1048    /// Sends a message described as JSON through the sendMail action.
1049    pub fn mail_send(
1050        &mut self,
1051        message: &MsgraphMessage,
1052        save_to_sent_items: bool,
1053    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
1054        let coroutine =
1055            MsgraphMailSend::new(&self.auth, &self.user_id, message, save_to_sent_items)?;
1056        self.run(coroutine)
1057    }
1058
1059    /// Sends a message given as raw RFC 5322 MIME bytes through the
1060    /// sendMail action.
1061    pub fn mail_send_mime(
1062        &mut self,
1063        raw: &[u8],
1064    ) -> Result<MsgraphSendOutput<MsgraphNoResponse>, MsgraphClientStdError> {
1065        let coroutine = MsgraphMailSendMime::new(&self.auth, &self.user_id, raw)?;
1066        self.run(coroutine)
1067    }
1068}
1069
1070impl fmt::Debug for MsgraphClientStd {
1071    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1072        f.debug_struct("MsgraphClientStd")
1073            .field("auth", &self.auth)
1074            .field("user_id", &self.user_id)
1075            .finish_non_exhaustive()
1076    }
1077}
1078
1079/// Blocking stream the client runs over, downcastable through `Any`
1080/// (e.g. to recover a concrete TLS stream).
1081pub trait MsgraphStream: Read + Write + Send + Any {
1082    /// The stream as a mutable `Any`, ready for downcasting.
1083    fn as_any_mut(&mut self) -> &mut dyn Any;
1084}
1085
1086impl<T: Read + Write + Send + Any> MsgraphStream for T {
1087    fn as_any_mut(&mut self) -> &mut dyn Any {
1088        self
1089    }
1090}