Trait ResponseExt

Source
pub trait ResponseExt {
    // Required methods
    fn job_status<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Option<GraphResult<Response>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn into_upload_session<'async_trait>(
        self,
        reader: impl 'async_trait + Read + Send,
    ) -> Pin<Box<dyn Future<Output = GraphResult<UploadSession>> + Send + 'async_trait>>
       where Self: 'async_trait;
    fn into_upload_session_async_read<'async_trait>(
        self,
        reader: impl 'async_trait + AsyncReadExt + Send + Unpin,
    ) -> Pin<Box<dyn Future<Output = GraphResult<UploadSession>> + Send + 'async_trait>>
       where Self: 'async_trait;
    fn download<'life0, 'async_trait>(
        self,
        file_config: &'life0 FileConfig,
    ) -> Pin<Box<dyn Future<Output = Result<Response<PathBuf>, AsyncDownloadError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn into_graph_error_message<'async_trait>(
        self,
    ) -> Pin<Box<dyn Future<Output = Result<ErrorMessage, Error>> + Send + 'async_trait>>
       where Self: 'async_trait;
    fn graph_error_type(&self) -> Option<ErrorType>;
}

Required Methods§

Source

fn job_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Option<GraphResult<Response>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn into_upload_session<'async_trait>( self, reader: impl 'async_trait + Read + Send, ) -> Pin<Box<dyn Future<Output = GraphResult<UploadSession>> + Send + 'async_trait>>
where Self: 'async_trait,

§Begin an upload session using any [std::io::Reader].

Converts the current request object into an upload session object for uploading large files to OneDrive or SharePoint.

This method takes a reader object that implements the std::io::Read and Send traits, and returns a GraphResult containing an UploadSession object.

The UploadSession object contains the upload URL for the file, as well as a [RangeIter] iterator that can be used to send the file contents to the server in multiple chunks (or “ranges”). If the upload URL is not found in the response body, this method returns a GraphFailure with an error message indicating that no upload URL was found.

§Requires reqwest::Response body to be valid JSON

The body of the reqwest::Response must be valid JSON with an [uploadUrl] field.

§Example
use graph_rs_sdk::http::{AsyncIterator, ResponseExt};
use graph_rs_sdk::*;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

// Put the path to your file and the file name itself that
// you want to upload to one drive.
static LOCAL_FILE_PATH: &str = "/path/to/file/file.txt";

// Parent folder id of where to store this file.
static DRIVE_PARENT_ID: &str = "PARENT_ID";

// The conflict behavior can be one of: fail, rename, or replace.
static CONFLICT_BEHAVIOR: &str = "rename";
#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let conflict_behavior = CONFLICT_BEHAVIOR.to_string()
    let upload = serde_json::json!({
        "@microsoft.graph.conflictBehavior": Some(conflict_behavior)
    });

    let response = client
        .me()
        .drive()
        .item_by_path(PATH_IN_ONE_DRIVE)
        .create_upload_session(&upload)
        .send()
        .await
        .unwrap();

    let file = std::fs::File::open(PATH_IN_ONE_DRIVE)?;

    let mut iter = response.into_upload_session(file).await?;

    while let Some(result) = iter.next().await {
        let response = result?;
        println!("{response:#?}");
    }

    Ok(())
}
Source

fn into_upload_session_async_read<'async_trait>( self, reader: impl 'async_trait + AsyncReadExt + Send + Unpin, ) -> Pin<Box<dyn Future<Output = GraphResult<UploadSession>> + Send + 'async_trait>>
where Self: 'async_trait,

§Begin an upload session using any tokio::io::AsyncReadExt.

Converts the current request object into an upload session object for uploading large files to OneDrive or SharePoint.

This method takes a reader object that implements the tokio::io::AsyncReadExt, Send, and Unpin traits, and returns a GraphResult containing an UploadSession object.

The UploadSession object contains the upload URL for the file, as well as a [RangeIter] iterator that can be used to send the file contents to the server in multiple chunks (or “ranges”). If the upload URL is not found in the response body, this method returns a GraphFailure with an error message indicating that no upload URL was found.

§Requires reqwest::Response body can be deserialized to valid JSON

The body of the reqwest::Response must be valid JSON with an [uploadUrl] field.

§Example
use graph_rs_sdk::http::{AsyncIterator, ResponseExt};
use graph_rs_sdk::*;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

// Put the path to your file and the file name itself that
// you want to upload to one drive.
static LOCAL_FILE_PATH: &str = "/path/to/file/file.txt";

// Parent folder id of where to store this file.
static DRIVE_PARENT_ID: &str = "PARENT_ID";

// The conflict behavior can be one of: fail, rename, or replace.
static CONFLICT_BEHAVIOR: &str = "rename";

#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let conflict_behavior = CONFLICT_BEHAVIOR.to_string()
    let upload = serde_json::json!({
        "@microsoft.graph.conflictBehavior": Some(conflict_behavior)
    });

    let response = client
        .me()
        .drive()
        .item_by_path(PATH_IN_ONE_DRIVE)
        .create_upload_session(&upload)
        .send()
        .await
        .unwrap();

    let file = tokio::fs::File::open(PATH_IN_ONE_DRIVE).await?;

    let mut iter = response.into_upload_session_async_read(file).await?;

    while let Some(result) = iter.next().await {
        let response = result?;
        println!("{response:#?}");
    }

    Ok(())
}
Source

fn download<'life0, 'async_trait>( self, file_config: &'life0 FileConfig, ) -> Pin<Box<dyn Future<Output = Result<Response<PathBuf>, AsyncDownloadError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

§Downloads the content of the HTTP response and saves it to a file.

This method takes a file_config object containing various parameters that control how the file is downloaded and saved. The file_config object includes the file path, file name, whether to create the directory recursively, whether to overwrite existing files, and the desired file extension.

If create_dir_all is set to true (default is true), this method will recursively create the directory at the path specified if it doesn’t exist yet. If it is set to false and the target directory doesn’t exist, this method will return an AsyncDownloadError with an error message indicating that the target directory does not exist.

The FileConfig::file_name parameter can be used to specify a custom file name for the downloaded file. If it is not provided, the method will attempt to parse the Content-Disposition header to extract the file name. If no file name can be obtained from the header, this method will return an AsyncDownloadError::NoFileName with an error message indicating that no file name was found.

If the FileConfig::extension parameter is set to a non-empty string, this method will set the file extension of the downloaded file to the specified value.

If the target file already exists and [overwrite_existing_file] is set to false, this method will return an AsyncDownloadError::FileExists with an error message indicating that the file already exists and cannot be overwritten.

If the file is downloaded and saved successfully, this method returns a http::Response<PathBuf> object containing the path to the downloaded file.

§Example
use graph_rs_sdk::http::{BodyRead, FileConfig};
use graph_rs_sdk::*;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

static ITEM_ID: &str = "ITEM_ID";

static FORMAT: &str = "pdf";

static DOWNLOAD_DIRECTORY: &str = "./examples";

#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let response = client
        .me()
        .drive()
        .item(ITEM_ID)
        .get_items_content()
        .format(FORMAT)
        .send()
        .await?;

    println!("{response:#?}");

    let response2 = response.download(&FileConfig::new(DOWNLOAD_DIRECTORY))
        .send()
        .await?;

    let path_buf = response2.body();
    println!("{:#?}", path_buf.metadata());

    Ok(())
}



§Example format and rename
use graph_rs_sdk::http::{BodyRead, FileConfig};
use graph_rs_sdk::*;
use std::ffi::OsStr;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

static ITEM_ID: &str = "ITEM_ID";

static FORMAT: &str = "pdf";

static DOWNLOAD_DIRECTORY: &str = "./examples";

static FILE_NAME: &str = "new_file_name.pdf";

#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let response = client
        .me()
        .drive()
        .item(ITEM_ID)
        .get_items_content()
        .format(FORMAT)
        .send()
        .await?;

    println!("{response:#?}");

    let file_config = FileConfig::new(DOWNLOAD_DIRECTORY)
        .file_name(OsStr::new(FILE_NAME));

    let response2 = response.download(file_config)
        .send()
        .await?;

    let path_buf = response2.body();
    println!("{:#?}", path_buf.metadata());

    Ok(())
}
Source

fn into_graph_error_message<'async_trait>( self, ) -> Pin<Box<dyn Future<Output = Result<ErrorMessage, Error>> + Send + 'async_trait>>
where Self: 'async_trait,

If the response is a server error then Microsoft Graph will return an error in the response body. The ErrorMessage type maps to these errors and this method deserializes to this type.

Microsoft Graph does not return this error message in all situations so it make sure to handle cases where the body could not be deserialized properly.

let status = response.status();

if status.is_server_error() || status.is_client_error() {
    let error_message = response.into_error_message().await.unwrap();
    println!("{error_message:#?}");

    // This is the same thing as doing
    let error_message: ErrorMessage = response.json().await.unwrap();
}
Source

fn graph_error_type(&self) -> Option<ErrorType>

Microsoft Graph specific status code errors mapped from the response [StatusCode]. Not all status codes map to a Microsoft Graph error.

Use ErrorType::as_str to get a short description of the Microsoft Graph specific error.

let error_type = response.graph_error_type().unwrap();
println!("{:#?}", error_type.as_str());

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl ResponseExt for Response

Source§

fn into_upload_session<'async_trait>( self, reader: impl 'async_trait + Read + Send, ) -> Pin<Box<dyn Future<Output = GraphResult<UploadSession>> + Send + 'async_trait>>
where Self: 'async_trait,

§Begin an upload session using any [std::io::Reader].

Converts the current request object into an upload session object for uploading large files to OneDrive or SharePoint.

This method takes a reader object that implements the std::io::Read and Send traits, and returns a GraphResult containing an UploadSession object.

The UploadSession object contains the upload URL for the file, as well as a [RangeIter] iterator that can be used to send the file contents to the server in multiple chunks (or “ranges”). If the upload URL is not found in the response body, this method returns a GraphFailure with an error message indicating that no upload URL was found.

§Requires reqwest::Response body to be valid JSON

The body of the reqwest::Response must be valid JSON with an [uploadUrl] field.

§Example
use graph_rs_sdk::http::{AsyncIterator, ResponseExt};
use graph_rs_sdk::*;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

// Put the path to your file and the file name itself that
// you want to upload to one drive.
static LOCAL_FILE_PATH: &str = "/path/to/file/file.txt";

// Parent folder id of where to store this file.
static DRIVE_PARENT_ID: &str = "PARENT_ID";

// The conflict behavior can be one of: fail, rename, or replace.
static CONFLICT_BEHAVIOR: &str = "rename";
#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let conflict_behavior = CONFLICT_BEHAVIOR.to_string();
    let upload = serde_json::json!({
        "@microsoft.graph.conflictBehavior": Some(conflict_behavior)
    });

    let response = client
        .me()
        .drive()
        .item_by_path(PATH_IN_ONE_DRIVE)
        .create_upload_session(&upload)
        .send()
        .await
        .unwrap();

    let file = std::fs::File::open(PATH_IN_ONE_DRIVE)?;

    let mut iter = response.into_upload_session(file).await?;

    while let Some(result) = iter.next().await {
        let response = result?;
        println!("{response:#?}");
    }

    Ok(())
}
Source§

fn into_upload_session_async_read<'async_trait>( self, reader: impl 'async_trait + AsyncReadExt + Send + Unpin, ) -> Pin<Box<dyn Future<Output = GraphResult<UploadSession>> + Send + 'async_trait>>
where Self: 'async_trait,

§Begin an upload session using any tokio::io::AsyncReadExt.

Converts the current request object into an upload session object for uploading large files to OneDrive or SharePoint.

This method takes a reader object that implements the tokio::io::AsyncReadExt, Send, and Unpin traits, and returns a GraphResult containing an UploadSession object.

The UploadSession object contains the upload URL for the file, as well as a [RangeIter] iterator that can be used to send the file contents to the server in multiple chunks (or “ranges”). If the upload URL is not found in the response body, this method returns a GraphFailure with an error message indicating that no upload URL was found.

§Requires reqwest::Response body can be deserialized to valid JSON

The body of the reqwest::Response must be valid JSON with an [uploadUrl] field.

§Example
use graph_rs_sdk::http::{AsyncIterator, ResponseExt};
use graph_rs_sdk::*;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

// Put the path to your file and the file name itself that
// you want to upload to one drive.
static LOCAL_FILE_PATH: &str = "/path/to/file/file.txt";

// Parent folder id of where to store this file.
static DRIVE_PARENT_ID: &str = "PARENT_ID";

// The conflict behavior can be one of: fail, rename, or replace.
static CONFLICT_BEHAVIOR: &str = "rename";

#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let conflict_behavior = CONFLICT_BEHAVIOR.to_string();
    let upload = serde_json::json!({
        "@microsoft.graph.conflictBehavior": Some(conflict_behavior)
    });

    let response = client
        .me()
        .drive()
        .item_by_path(PATH_IN_ONE_DRIVE)
        .create_upload_session(&upload)
        .send()
        .await
        .unwrap();

    let file = tokio::fs::File::open(PATH_IN_ONE_DRIVE).await?;

    let mut iter = response.into_upload_session_async_read(file).await?;

    while let Some(result) = iter.next().await {
        let response = result?;
        println!("{response:#?}");
    }

    Ok(())
}
Source§

fn download<'life0, 'async_trait>( self, file_config: &'life0 FileConfig, ) -> Pin<Box<dyn Future<Output = Result<Response<PathBuf>, AsyncDownloadError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

§Downloads the content of the HTTP response and saves it to a file.

This method takes a file_config object containing various parameters that control how the file is downloaded and saved. The file_config object includes the file path, file name, whether to create the directory recursively, whether to overwrite existing files, and the desired file extension.

If create_dir_all is set to true, this method will create the directory at the specified path if it doesn’t exist yet. If it is set to false and the target directory doesn’t exist, this method will return an AsyncDownloadError with an error message indicating that the target directory does not exist.

The FileConfig::file_name parameter can be used to specify a custom file name for the downloaded file. If it is not provided, the method will attempt to parse the Content-Disposition header to extract the file name. If no file name can be obtained from the header, this method will return an AsyncDownloadError::NoFileName with an error message indicating that no file name was found.

If the FileConfig::extension parameter is set to a non-empty string, this method will set the file extension of the downloaded file to the specified value.

If the target file already exists and [overwrite_existing_file] is set to false, this method will return an AsyncDownloadError::FileExists with an error message indicating that the file already exists and cannot be overwritten.

If the file is downloaded and saved successfully, this method returns a http::Response<PathBuf> object containing the path to the downloaded file.

§Example
use graph_rs_sdk::http::{BodyRead, FileConfig};
use graph_rs_sdk::*;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

static ITEM_ID: &str = "ITEM_ID";

static FORMAT: &str = "pdf";

static DOWNLOAD_DIRECTORY: &str = "./examples";

#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let response = client
        .me()
        .drive()
        .item(ITEM_ID)
        .get_items_content()
        .format(FORMAT)
        .send()
        .await?;

    println!("{response:#?}");

    let response2 = response.download(&FileConfig::new(DOWNLOAD_DIRECTORY))
        .send()
        .await?;

    let path_buf = response2.body();
    println!("{:#?}", path_buf.metadata());

    Ok(())
}



§Example format and rename
use graph_rs_sdk::http::{BodyRead, FileConfig};
use graph_rs_sdk::*;
use std::ffi::OsStr;

static ACCESS_TOKEN: &str = "ACCESS_TOKEN";

static ITEM_ID: &str = "ITEM_ID";

static FORMAT: &str = "pdf";

static DOWNLOAD_DIRECTORY: &str = "./examples";

static FILE_NAME: &str = "new_file_name.pdf";

#[tokio::main]
async fn main() -> GraphResult<()> {
    let client = Graph::new(ACCESS_TOKEN);

    let response = client
        .me()
        .drive()
        .item(ITEM_ID)
        .get_items_content()
        .format(FORMAT)
        .send()
        .await?;

    println!("{response:#?}");

    let file_config = FileConfig::new(DOWNLOAD_DIRECTORY)
        .file_name(OsStr::new(FILE_NAME));

    let response2 = response.download(file_config)
        .send()
        .await?;

    let path_buf = response2.body();
    println!("{:#?}", path_buf.metadata());

    Ok(())
}
Source§

fn into_graph_error_message<'async_trait>( self, ) -> Pin<Box<dyn Future<Output = Result<ErrorMessage, Error>> + Send + 'async_trait>>
where Self: 'async_trait,

If the response is a server error then Microsoft Graph will return an error in the response body. The ErrorMessage type maps to these errors and this method deserializes to this type.

Microsoft Graph does not return this error message in all situations so it make sure to handle cases where the body could not be deserialized properly.

let status = response.status();

if status.is_server_error() || status.is_client_error() {
    let error_message = response.into_error_message().await.unwrap();
    println!("{error_message:#?}");

    // This is the same thing as doing
    let error_message: ErrorMessage = response.json().await.unwrap();
}
Source§

fn graph_error_type(&self) -> Option<ErrorType>

Microsoft Graph specific status code errors mapped from the response [StatusCode]. Not all status codes map to a Microsoft Graph error.

Use ErrorType::as_str to get a short description of the Microsoft Graph specific error.

let error_type = response.graph_error_type().unwrap();
println!("{:#?}", error_type.as_str());
Source§

fn job_status<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Option<GraphResult<Response>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Implementors§