use reqwest::Method;
use serde::{Deserialize, Serialize};
use crate::{
core::{
api_req::ApiRequest,
api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
config::Config,
constants::AccessTokenType,
endpoints::{cloud_docs::*, EndpointBuilder},
http::Transport,
req_option::RequestOption,
SDKResult,
},
impl_executable_builder_owned,
};
#[derive(Debug, Serialize, Default)]
pub struct GetTaskRequest {
#[serde(skip)]
api_request: ApiRequest,
#[serde(skip)]
task_id: String,
}
impl GetTaskRequest {
pub fn builder() -> GetTaskRequestBuilder {
GetTaskRequestBuilder::default()
}
pub fn new(task_id: impl ToString) -> Self {
Self {
task_id: task_id.to_string(),
..Default::default()
}
}
}
#[derive(Default)]
pub struct GetTaskRequestBuilder {
request: GetTaskRequest,
}
impl GetTaskRequestBuilder {
pub fn task_id(mut self, task_id: impl ToString) -> Self {
self.request.task_id = task_id.to_string();
self
}
pub fn build(mut self) -> GetTaskRequest {
self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
self.request
}
}
impl_executable_builder_owned!(
GetTaskRequestBuilder,
crate::service::cloud_docs::wiki::v2::task::TaskService,
GetTaskRequest,
GetTaskResponse,
get
);
#[derive(Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TaskStatus {
Processing,
Success,
Failed,
}
#[derive(Debug, Deserialize)]
pub struct MoveResult {
pub obj_token: String,
pub node_token: String,
pub title: Option<String>,
pub obj_type: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct TaskDetail {
pub task_id: String,
pub status: TaskStatus,
pub space_id: Option<String>,
pub processed_count: Option<i32>,
pub total_count: Option<i32>,
pub move_results: Option<Vec<MoveResult>>,
pub error_message: Option<String>,
pub create_time: Option<String>,
pub finish_time: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct GetTaskResponse {
pub task: TaskDetail,
}
impl ApiResponseTrait for GetTaskResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
pub async fn get_task(
request: GetTaskRequest,
config: &Config,
option: Option<RequestOption>,
) -> SDKResult<BaseResponse<GetTaskResponse>> {
let mut api_req = request.api_request;
api_req.http_method = Method::GET;
api_req.api_path =
EndpointBuilder::replace_param(WIKI_V2_TASK_GET, "task_id", &request.task_id);
api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
let api_resp = Transport::request(api_req, config, option).await?;
Ok(api_resp)
}
impl TaskStatus {
pub fn is_finished(&self) -> bool {
matches!(self, TaskStatus::Success | TaskStatus::Failed)
}
pub fn is_success(&self) -> bool {
matches!(self, TaskStatus::Success)
}
pub fn is_failed(&self) -> bool {
matches!(self, TaskStatus::Failed)
}
pub fn is_processing(&self) -> bool {
matches!(self, TaskStatus::Processing)
}
}
impl TaskDetail {
pub fn progress_percentage(&self) -> Option<f32> {
if let (Some(processed), Some(total)) = (self.processed_count, self.total_count) {
if total > 0 {
return Some((processed as f32 / total as f32) * 100.0);
}
}
None
}
pub fn has_error(&self) -> bool {
self.error_message.is_some()
}
pub fn success_count(&self) -> usize {
self.move_results
.as_ref()
.map_or(0, |results| results.len())
}
}
#[cfg(test)]
#[allow(unused_variables, unused_unsafe)]
mod tests {
use super::*;
#[test]
fn test_get_task_request_builder() {
let request = GetTaskRequest::builder().task_id("taskxxxxxx").build();
assert_eq!(request.task_id, "taskxxxxxx");
}
#[test]
fn test_task_status_methods() {
assert!(TaskStatus::Success.is_finished());
assert!(TaskStatus::Failed.is_finished());
assert!(!TaskStatus::Processing.is_finished());
assert!(TaskStatus::Success.is_success());
assert!(!TaskStatus::Failed.is_success());
assert!(TaskStatus::Failed.is_failed());
assert!(!TaskStatus::Success.is_failed());
assert!(TaskStatus::Processing.is_processing());
assert!(!TaskStatus::Success.is_processing());
}
}