use crate::core::{api_resp::BaseResponse, error::LarkAPIError, SDKResult};
pub trait StandardResponse<T> {
fn into_result(self) -> SDKResult<T>;
fn data_or_default(self) -> T
where
T: Default;
}
impl<T> StandardResponse<T> for BaseResponse<T> {
fn into_result(self) -> SDKResult<T> {
if self.success() {
match self.data {
Some(data) => Ok(data),
None => Err(LarkAPIError::DataError(
"Response succeeded but contains no data".to_string(),
)),
}
} else {
Err(LarkAPIError::APIError {
code: self.code(),
msg: self.msg().to_string(),
error: self.err().map(|e| format!("{e:?}")),
})
}
}
fn data_or_default(self) -> T
where
T: Default,
{
if self.success() {
self.data.unwrap_or_default()
} else {
T::default()
}
}
}
impl<T> StandardResponse<T> for SDKResult<BaseResponse<T>> {
fn into_result(self) -> SDKResult<T> {
match self {
Ok(response) => response.into_result(),
Err(error) => Err(error),
}
}
fn data_or_default(self) -> T
where
T: Default,
{
match self {
Ok(response) => response.data_or_default(),
Err(_) => T::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::api_resp::{BaseResponse, RawResponse};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
struct TestData {
value: String,
}
#[test]
fn test_successful_response_with_data() {
let response = BaseResponse {
raw_response: RawResponse {
code: 0,
msg: "success".to_string(),
err: None,
},
data: Some(TestData {
value: "test".to_string(),
}),
};
let result = response.into_result();
assert!(result.is_ok());
assert_eq!(result.unwrap().value, "test");
}
#[test]
fn test_successful_response_without_data() {
let response: BaseResponse<TestData> = BaseResponse {
raw_response: RawResponse {
code: 0,
msg: "success".to_string(),
err: None,
},
data: None,
};
let result = response.into_result();
assert!(result.is_err());
if let Err(LarkAPIError::DataError(msg)) = result {
assert!(msg.contains("no data"));
} else {
panic!("Expected DataError");
}
}
#[test]
fn test_failed_response() {
let response: BaseResponse<TestData> = BaseResponse {
raw_response: RawResponse {
code: -1,
msg: "error".to_string(),
err: None,
},
data: None,
};
let result = response.into_result();
assert!(result.is_err());
}
#[test]
fn test_data_or_default_success() {
let response = BaseResponse {
raw_response: RawResponse {
code: 0,
msg: "success".to_string(),
err: None,
},
data: Some(TestData {
value: "test".to_string(),
}),
};
let data = response.data_or_default();
assert_eq!(data.value, "test");
}
#[test]
fn test_data_or_default_no_data() {
let response: BaseResponse<TestData> = BaseResponse {
raw_response: RawResponse {
code: 0,
msg: "success".to_string(),
err: None,
},
data: None,
};
let data = response.data_or_default();
assert_eq!(data, TestData::default());
}
#[test]
fn test_data_or_default_failure() {
let response: BaseResponse<TestData> = BaseResponse {
raw_response: RawResponse {
code: -1,
msg: "error".to_string(),
err: None,
},
data: None,
};
let data = response.data_or_default();
assert_eq!(data, TestData::default());
}
}