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, Deserialize)]
pub struct CreateFileShortcutResponse {
pub succ_shortcut_node: ShortcutNode,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShortcutNode {
pub token: String,
pub name: String,
#[serde(rename = "type")]
pub r#type: String,
pub parent_token: String,
pub url: String,
pub shortcut_info: CreateShortcutInfo,
pub created_time: String,
pub modified_time: String,
pub owner_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateShortcutInfo {
pub target_type: String,
pub target_token: String,
}
impl ApiResponseTrait for CreateFileShortcutResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[derive(Debug, Clone, Serialize)]
pub struct CreateFileShortcutRequest {
#[serde(skip)]
config: Config,
#[serde(skip)]
pub user_id_type: Option<String>,
pub parent_token: String,
pub refer_entity: ReferEntity,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReferEntity {
pub refer_token: String,
pub refer_type: String,
}
impl CreateFileShortcutRequest {
pub fn new(
config: Config,
parent_token: impl Into<String>,
refer_token: impl Into<String>,
refer_type: impl Into<String>,
) -> Self {
Self {
config,
user_id_type: None,
parent_token: parent_token.into(),
refer_entity: ReferEntity {
refer_token: refer_token.into(),
refer_type: refer_type.into(),
},
}
}
pub fn user_id_type(mut self, user_id_type: impl Into<String>) -> Self {
self.user_id_type = Some(user_id_type.into());
self
}
pub async fn execute(self) -> SDKResult<CreateFileShortcutResponse> {
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<CreateFileShortcutResponse> {
if self.parent_token.is_empty() {
return Err(openlark_core::error::validation_error(
"parent_token",
"parent_token 不能为空",
));
}
if self.refer_entity.refer_token.is_empty() {
return Err(openlark_core::error::validation_error(
"refer_entity.refer_token",
"refer_token 不能为空",
));
}
if self.refer_entity.refer_type.is_empty() {
return Err(openlark_core::error::validation_error(
"refer_entity.refer_type",
"refer_type 不能为空",
));
}
match self.refer_entity.refer_type.as_str() {
"file" | "docx" | "bitable" | "doc" | "sheet" | "mindnote" | "slides" => {}
_ => {
return Err(openlark_core::error::validation_error(
"refer_entity.refer_type",
"refer_type 仅支持 file/docx/bitable/doc/sheet/mindnote/slides",
));
}
}
if let Some(user_id_type) = &self.user_id_type {
match user_id_type.as_str() {
"open_id" | "union_id" | "user_id" => {}
_ => {
return Err(openlark_core::error::validation_error(
"user_id_type",
"user_id_type 仅支持 open_id/union_id/user_id",
));
}
}
}
let api_endpoint = DriveApi::CreateShortcut;
let mut request = ApiRequest::<CreateFileShortcutResponse>::post(&api_endpoint.to_url());
if let Some(user_id_type) = &self.user_id_type {
request = request.query("user_id_type", user_id_type);
}
request = request.body(serialize_params(&self, "创建文件快捷方式")?);
let response = Transport::request(request, &self.config, Some(option)).await?;
extract_response_data(response, "创建文件快捷方式")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_file_shortcut_request() {
let config = Config::default();
let request = CreateFileShortcutRequest::new(config, "fld_xxx", "dox_xxx", "docx")
.user_id_type("open_id");
assert_eq!(request.parent_token, "fld_xxx");
assert_eq!(request.refer_entity.refer_token, "dox_xxx");
assert_eq!(request.refer_entity.refer_type, "docx");
assert_eq!(request.user_id_type, Some("open_id".to_string()));
}
#[test]
fn test_response_trait_implementation() {
assert_eq!(
CreateFileShortcutResponse::data_format(),
ResponseFormat::Data
);
}
}