openlark_core/trait_system/
executable_builder.rs1#![allow(async_fn_in_trait)]
3use crate::req_option::RequestOption;
8use crate::SDKResult;
9
10pub trait ExecutableBuilder<S: Sync, Req, Resp>: Sized {
12 fn build(self) -> Req;
14
15 async fn execute(self, service: &S) -> SDKResult<Resp>;
17
18 async fn execute_with_options(self, service: &S, _option: RequestOption) -> SDKResult<Resp> {
22 self.execute(service).await
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29
30 struct MockService;
32 struct MockRequest {
33 value: String,
34 }
35 struct MockResponse {
36 result: String,
37 }
38
39 struct MockBuilder {
40 value: String,
41 }
42
43 impl ExecutableBuilder<MockService, MockRequest, MockResponse> for MockBuilder {
44 fn build(self) -> MockRequest {
45 MockRequest { value: self.value }
46 }
47
48 async fn execute(self, _service: &MockService) -> SDKResult<MockResponse> {
49 Ok(MockResponse {
50 result: "success".to_string(),
51 })
52 }
53 }
54
55 #[tokio::test]
56 async fn test_executable_builder_build() {
57 let builder = MockBuilder {
58 value: "test".to_string(),
59 };
60 let request = builder.build();
61 assert_eq!(request.value, "test");
62 }
63
64 #[tokio::test]
65 async fn test_executable_builder_execute() {
66 let builder = MockBuilder {
67 value: "test".to_string(),
68 };
69 let service = MockService;
70 let result = builder.execute(&service).await;
71 assert!(result.is_ok());
72 assert_eq!(result.unwrap().result, "success");
73 }
74
75 #[tokio::test]
76 async fn test_executable_builder_execute_with_options() {
77 let builder = MockBuilder {
78 value: "test".to_string(),
79 };
80 let service = MockService;
81 let option = RequestOption::default();
82 let result = builder.execute_with_options(&service, option).await;
83 assert!(result.is_ok());
84 }
85}