openlark_client/
client.rs1#[macro_use]
6mod macros;
7
8mod builder;
9#[cfg(test)]
10#[macro_use]
11mod catalog_contract_support;
12#[cfg(test)]
13mod catalog_contract_foundational;
14#[cfg(test)]
15mod catalog_contract_listing;
16#[cfg(test)]
17mod catalog_contract_remaining;
18mod error_handling;
19#[cfg(test)]
20mod tests;
21
22pub use builder::ClientBuilder;
23pub use error_handling::ClientErrorHandling;
24
25use crate::{
26 DefaultServiceRegistry, Result,
27 error::{with_context, with_operation_context},
28 traits::LarkClient,
29 validation_error,
30};
31use std::sync::Arc;
32
33#[cfg(feature = "auth")]
35#[derive(Debug, Clone)]
36pub struct AuthClient {
37 pub app: openlark_auth::AuthService,
39 pub user: openlark_auth::AuthenService,
41 pub oauth: openlark_auth::OAuthService,
43}
44
45#[cfg(feature = "auth")]
46impl AuthClient {
47 fn new(config: openlark_core::config::Config) -> Self {
48 Self {
49 app: openlark_auth::AuthService::new(config.clone()),
50 user: openlark_auth::AuthenService::new(config.clone()),
51 oauth: openlark_auth::OAuthService::new(config),
52 }
53 }
54}
55
56macro_rules! append_catalog_entries {
61 ($({
62 feature: $c_feature:literal,
63 field: $c_field:ident,
64 ty: $c_ty:ty,
65 doc: $c_doc:literal,
66 init: |$c_core:ident, $c_base:ident| $c_init:block,
67 name: $_name:literal,
69 description: $_description:literal,
70 dependencies: [$( $_dep:literal ),* $(,)?],
71 provides: [$( $_cap:literal ),* $(,)?],
72 priority: $_priority:literal $(,)?
73 }),* $(,)?) => {
74 declare_client! {
75 $(
76 {
77 feature: $c_feature,
78 field: $c_field,
79 ty: $c_ty,
80 doc: $c_doc,
81 init: |$c_core, $c_base| $c_init,
82 },
83 )*
84 }
85 };
86}
87
88crate::capability::for_each_compiled_capability!(append_catalog_entries);
89
90impl Client {
91 pub fn from_env() -> Result<Self> {
111 Self::builder().from_env().build()
112 }
113
114 pub fn builder() -> ClientBuilder {
116 ClientBuilder::new()
117 }
118
119 pub fn config(&self) -> &openlark_core::config::Config {
121 &self.config
122 }
123
124 pub fn registry(&self) -> &DefaultServiceRegistry {
126 &self.registry
127 }
128
129 pub fn core_config(&self) -> &openlark_core::config::Config {
133 &self.config
134 }
135
136 pub fn api_config(&self) -> &openlark_core::config::Config {
142 &self.config
143 }
144
145 pub fn is_configured(&self) -> bool {
147 !self.config.app_id().is_empty() && !self.config.app_secret().is_empty()
148 }
149
150 pub fn with_core_config(config: openlark_core::config::Config) -> Result<Self> {
155 Self::with_checked_core_config(config, "Client::with_core_config")
156 }
157
158 pub(crate) fn with_checked_core_config(
168 base_core_config: openlark_core::config::Config,
169 operation: &str,
170 ) -> Result<Self> {
171 if let Err(err) = base_core_config.validate() {
172 return with_context(Err(err), "operation", operation);
173 }
174 if base_core_config
175 .req_timeout()
176 .is_some_and(|timeout| timeout.is_zero())
177 {
178 return with_context(
179 Err(validation_error("timeout", "timeout必须大于0")),
180 "operation",
181 operation,
182 );
183 }
184
185 let mut registry = DefaultServiceRegistry::new();
186
187 if let Err(err) = crate::registry::bootstrap::register_compiled_services(&mut registry) {
188 return with_operation_context(Err(err), operation, "service_loading");
189 }
190
191 let registry = Arc::new(registry);
192
193 #[cfg(feature = "auth")]
194 let core_config = {
195 use openlark_auth::AuthTokenProvider;
196 let provider = AuthTokenProvider::new(base_core_config.clone());
197 base_core_config.with_token_provider(provider)
198 };
199 #[cfg(not(feature = "auth"))]
200 let core_config = base_core_config.clone();
201
202 Self::from_parts(registry, base_core_config, core_config)
203 }
204
205 pub async fn execute_with_context<F, T>(&self, operation: &str, f: F) -> Result<T>
207 where
208 F: std::future::Future<Output = Result<T>>,
209 {
210 let result = f.await;
211 with_operation_context(result, operation, "Client")
212 }
213}
214
215impl LarkClient for Client {
216 fn config(&self) -> &openlark_core::config::Config {
217 &self.config
218 }
219
220 fn is_configured(&self) -> bool {
221 self.is_configured()
222 }
223}