/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::sync::Arc; use ms_graph_tb::{OperationBody, paths::me::messages}; use nsstring::nsCString; use protocol_shared::{ ServerType, client::DoOperation, safe_xpcom::{ SafeExchangeSimpleOperationListener, SafeListener, SimpleOperationSuccessArgs, UseLegacyFallback, }, }; use thin_vec::ThinVec; use crate::{client::XpComGraphClient, error::XpComGraphError}; struct DoCopyMessage { pub destination_folder_id: String, pub message_ids: Vec, } impl DoOperation, XpComGraphError> for DoCopyMessage { const NAME: &'static str = "copy messages"; type Okay = ThinVec; type Listener = SafeExchangeSimpleOperationListener; async fn do_operation( &mut self, client: &XpComGraphClient, ) -> Result { // Note: the C++ consumer code expects the order of new messages IDs to // match that of the old ones (so that e.g. `new_message_ids[0]` is the // new ID for `self.message_ids[0]`). let requests = self .message_ids .iter() .map(|message_id| { let body = messages::message_id::copy::PostRequestBody::new() .set_destination_id(self.destination_folder_id.clone()); messages::message_id::copy::Post::new( client.base_url().to_string(), message_id.clone(), OperationBody::JSON(body), ) }) .collect(); let responses = client .send_batch_request_json_response(requests, Default::default()) .await?; let new_message_ids = responses .iter() .filter_map(|response| { response .outlook_item() .entity() .id() .ok() .map(ToString::to_string) }) .collect(); Ok(new_message_ids) } fn into_success_arg( self, new_message_ids: Self::Okay, ) -> ::OnSuccessArg { // If we have a length mismatch, that means something went wrong, but // perhaps not the entire request, so we need to tell the client to // requery the server to see what happened to the messages. let fallback = if new_message_ids.len() == self.message_ids.len() { UseLegacyFallback::No } else { UseLegacyFallback::Yes }; let new_message_ids = new_message_ids.iter().map(nsCString::from).collect(); SimpleOperationSuccessArgs { new_ids: new_message_ids, use_legacy_fallback: fallback, } } fn into_failure_arg(self) -> ::OnFailureArg {} } impl XpComGraphClient { /// Moves messages via Graph. /// /// [message move]: https://learn.microsoft.com/en-us/graph/api/message-move pub(crate) async fn copy_messages( self: Arc>, destination_folder_id: String, message_ids: Vec, listener: SafeExchangeSimpleOperationListener, ) { let operation = DoCopyMessage { destination_folder_id, message_ids, }; operation.handle_operation(&self, &listener).await; } }