use std::fmt::Debug;
use log::error;
use reqwest::Method;
use serde::{Deserialize, Serialize};
use crate::core::{
api_req::ApiRequest,
api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
config::Config,
constants::AccessTokenType,
http::Transport,
req_option::RequestOption,
SDKResult,
};
pub struct ExplorerService {
config: Config,
}
impl ExplorerService {
pub fn new(config: Config) -> Self {
Self { config }
}
pub async fn root_folder_meta(
&self,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<ExplorerRootMeta>> {
let api_req = ApiRequest {
http_method: Method::GET,
api_path: "/open-apis/drive/explorer/v2/root_folder/meta".to_string(),
supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
..Default::default()
};
let api_resp = Transport::request(api_req, &self.config, option).await?;
Ok(api_resp)
}
pub async fn folder_meta(
&self,
folder_token: &str,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<ExplorerFolderMeta>> {
let api_req = ApiRequest {
http_method: Method::GET,
api_path: format!("/open-apis/drive/explorer/v2/folder/{folder_token}/meta"),
supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
..Default::default()
};
let api_resp = Transport::request(api_req, &self.config, option).await?;
Ok(api_resp)
}
pub async fn create_folder(
&self,
create_folder_request: CreateFolderRequest,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<CreateFolderResponse>> {
let mut api_req = create_folder_request.api_req;
api_req.http_method = Method::POST;
api_req.api_path = "/open-apis/drive/v1/files/create_folder".to_string();
api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
let api_resp = Transport::request(api_req, &self.config, option).await?;
Ok(api_resp)
}
pub async fn list_folder(
&self,
list_folder_request: ListFolderRequest,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<ListFolderResponse>> {
let mut api_req = list_folder_request.api_req;
api_req.http_method = Method::GET;
api_req.api_path = "/open-apis/drive/v1/files".to_string();
api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
let api_resp = Transport::request(api_req, &self.config, option).await?;
Ok(api_resp)
}
pub fn list_folder_iter(
&self,
req: ListFolderRequest,
option: Option<RequestOption>,
) -> ListFolderIterator {
ListFolderIterator {
explorer_service: self,
req,
option,
has_more: true,
}
}
}
pub struct ListFolderIterator<'a> {
explorer_service: &'a ExplorerService,
req: ListFolderRequest,
option: Option<RequestOption>,
has_more: bool,
}
impl<'a> ListFolderIterator<'a> {
pub async fn next(&mut self) -> Option<Vec<FileInFolder>> {
if !self.has_more {
return None;
}
match self
.explorer_service
.list_folder(self.req.clone(), self.option.clone())
.await
{
Ok(resp) => match resp.data {
Some(data) => {
self.has_more = data.has_more;
if data.has_more {
self.req
.api_req
.query_params
.insert("page_token".to_string(), data.next_page_token.unwrap());
Some(data.files)
} else if data.files.is_empty() {
None
} else {
Some(data.files)
}
}
None => None,
},
Err(e) => {
error!("Error: {:?}", e);
None
}
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ExplorerRootMeta {
pub token: String,
pub id: String,
pub user_id: String,
}
impl ApiResponseTrait for ExplorerRootMeta {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ExplorerFolderMeta {
pub id: String,
pub name: String,
pub token: String,
#[serde(rename = "createUid")]
pub create_uid: String,
#[serde(rename = "editUid")]
pub edit_uid: String,
#[serde(rename = "parentId")]
pub parent_id: String,
#[serde(rename = "ownUid")]
pub own_uid: String,
}
impl ApiResponseTrait for ExplorerFolderMeta {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[derive(Default, Serialize, Deserialize)]
pub struct CreateFolderRequest {
#[serde(skip)]
api_req: ApiRequest,
name: String,
folder_token: String,
}
impl CreateFolderRequest {
pub fn builder() -> CreateFolderRequestBuilder {
CreateFolderRequestBuilder::default()
}
}
#[derive(Default)]
pub struct CreateFolderRequestBuilder {
request: CreateFolderRequest,
}
impl CreateFolderRequestBuilder {
pub fn name(mut self, name: impl ToString) -> Self {
self.request.name = name.to_string();
self
}
pub fn folder_token(mut self, folder_token: impl ToString) -> Self {
self.request.folder_token = folder_token.to_string();
self
}
pub fn build(mut self) -> CreateFolderRequest {
self.request.api_req.body = serde_json::to_vec(&self.request).unwrap();
self.request
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateFolderResponse {
pub token: String,
pub url: String,
}
impl ApiResponseTrait for CreateFolderResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[derive(Default)]
pub struct ListFolderRequestBuilder {
request: ListFolderRequest,
}
impl ListFolderRequestBuilder {
pub fn page_size(mut self, page_size: i32) -> Self {
self.request
.api_req
.query_params
.insert("page_size".to_string(), page_size.to_string());
self
}
pub fn page_token(mut self, page_token: impl ToString) -> Self {
self.request
.api_req
.query_params
.insert("page_token".to_string(), page_token.to_string());
self
}
pub fn folder_token(mut self, fold_token: impl ToString) -> Self {
self.request
.api_req
.query_params
.insert("folder_token".to_string(), fold_token.to_string());
self
}
pub fn order_by(mut self, order_by: impl ToString) -> Self {
self.request
.api_req
.query_params
.insert("order_by".to_string(), order_by.to_string());
self
}
pub fn direction(mut self, direction: impl ToString) -> Self {
self.request
.api_req
.query_params
.insert("direction".to_string(), direction.to_string());
self
}
pub fn user_id_type(mut self, user_id_type: impl ToString) -> Self {
self.request
.api_req
.query_params
.insert("user_id_type".to_string(), user_id_type.to_string());
self
}
pub fn build(self) -> ListFolderRequest {
self.request
}
}
#[derive(Default, Clone, Serialize, Deserialize)]
pub struct ListFolderRequest {
#[serde(skip)]
api_req: ApiRequest,
}
impl ListFolderRequest {
pub fn builder() -> ListFolderRequestBuilder {
ListFolderRequestBuilder::default()
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ListFolderResponse {
pub files: Vec<FileInFolder>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_page_token: Option<String>,
pub has_more: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct FileInFolder {
pub token: String,
pub name: String,
pub r#type: String,
pub parent_token: String,
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub shortcut_info: Option<ShortcutInfo>,
pub created_time: String,
pub modified_time: String,
pub owner_id: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ShortcutInfo {
pub target_type: String,
pub target_token: String,
}
impl ApiResponseTrait for ListFolderResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}