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