use openlark_core::{
api::{ApiRequest, ApiResponseTrait, ResponseFormat},
config::Config,
http::Transport,
SDKResult,
};
use serde::{Deserialize, Serialize};
use crate::common::{api_endpoints::DriveApi, api_utils::*};
#[derive(Debug, Clone, Serialize)]
pub struct MoveFileRequest {
#[serde(skip)]
config: Config,
pub file_token: String,
#[serde(rename = "type")]
pub r#type: String,
pub folder_token: String,
}
impl MoveFileRequest {
pub fn new(
config: Config,
file_token: impl Into<String>,
file_type: impl Into<String>,
folder_token: impl Into<String>,
) -> Self {
Self {
config,
file_token: file_token.into(),
r#type: file_type.into(),
folder_token: folder_token.into(),
}
}
pub async fn execute(self) -> SDKResult<MoveFileResponse> {
self.execute_with_options(openlark_core::req_option::RequestOption::default())
.await
}
pub async fn execute_with_options(
self,
option: openlark_core::req_option::RequestOption,
) -> SDKResult<MoveFileResponse> {
if self.file_token.is_empty() {
return Err(openlark_core::error::validation_error(
"file_token",
"file_token 不能为空",
));
}
if self.folder_token.is_empty() {
return Err(openlark_core::error::validation_error(
"folder_token",
"folder_token 不能为空",
));
}
if self.r#type.is_empty() {
return Err(openlark_core::error::validation_error(
"type",
"type 不能为空",
));
}
match self.r#type.as_str() {
"file" | "docx" | "bitable" | "doc" | "sheet" | "mindnote" | "folder" | "slides" => {}
_ => {
return Err(openlark_core::error::validation_error(
"type",
"type 仅支持 file/docx/bitable/doc/sheet/mindnote/folder/slides",
));
}
}
let api_endpoint = DriveApi::MoveFile(self.file_token.clone());
#[derive(Serialize)]
struct MoveFileBody {
#[serde(rename = "type")]
r#type: String,
folder_token: String,
}
let request =
ApiRequest::<MoveFileResponse>::post(&api_endpoint.to_url()).body(serialize_params(
&MoveFileBody {
r#type: self.r#type,
folder_token: self.folder_token,
},
"移动文件或文件夹",
)?);
let response = Transport::request(request, &self.config, Some(option)).await?;
extract_response_data(response, "移动文件或文件夹")
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MoveFileResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub task_id: Option<String>,
}
impl ApiResponseTrait for MoveFileResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_move_file_request_builder() {
let config = Config::default();
let request = MoveFileRequest::new(config, "file_token", "file", "folder_token");
assert_eq!(request.file_token, "file_token");
assert_eq!(request.r#type, "file");
assert_eq!(request.folder_token, "folder_token");
}
#[test]
fn test_move_file_with_empty_file_token() {
let config = Config::default();
let request = MoveFileRequest::new(config, "", "file", "folder_token");
assert_eq!(request.file_token, "");
}
#[test]
fn test_move_file_with_invalid_type() {
let config = Config::default();
let request = MoveFileRequest::new(config, "file_token", "invalid", "folder_token");
assert_eq!(request.r#type, "invalid");
}
#[test]
fn test_move_file_with_empty_folder_token() {
let config = Config::default();
let request = MoveFileRequest::new(config, "file_token", "file", "");
assert_eq!(request.folder_token, "");
}
#[test]
fn test_move_file_with_all_valid_types() {
let config = Config::default();
let valid_types = [
"file", "docx", "bitable", "doc", "sheet", "mindnote", "folder", "slides",
];
for file_type in valid_types {
let request =
MoveFileRequest::new(config.clone(), "file_token", file_type, "folder_token");
assert_eq!(request.r#type, file_type);
}
}
#[test]
fn test_move_file_response() {
let response = MoveFileResponse {
task_id: Some("task_123".to_string()),
};
assert_eq!(response.task_id, Some("task_123".to_string()));
}
#[test]
fn test_response_trait() {
assert_eq!(MoveFileResponse::data_format(), ResponseFormat::Data);
}
}