Skip to main content

wecomx_runtime/
client.rs

1//! [`WecomClient`]:面向第三方应用的门面客户端。
2//!
3//! 组合 [`wecomx::Client`](动态服务发现 + schema 驱动调用 + 长任务轮询)
4//! 与带鉴权的 [`Transport`](wecomx_transport::Transport),第三方应用无需
5//! 关心端点目录、网关协议与 token 注入细节。
6
7use wecomx_transport::Transport;
8
9/// WeCom 客户端:认证、服务发现与方法调用的统一入口。
10///
11/// 经 [`WecomClientBuilder`](crate::WecomClientBuilder) 构建后即可直接使用:
12///
13/// ```ignore
14/// let client = WecomClientBuilder::new()
15///     .token_provider(Arc::new(provider))
16///     .build()
17///     .await?;
18///
19/// // 程序化调用(服务/方法名由 discovery 下发)
20/// let svc = client.service("hr").await?;
21/// let result = svc.method(&["users", "list"])?.invoke(json!({})).await?;
22/// ```
23pub struct WecomClient {
24    inner: wecomx::Client,
25}
26
27impl WecomClient {
28    /// 用已构建的 transport 组装客户端(自动挂网关协议端点目录)。
29    ///
30    /// 适合需要完全自定义 transport 的调用方;常规路径请用
31    /// [`WecomClientBuilder`](crate::WecomClientBuilder)。
32    ///
33    /// # Errors
34    ///
35    /// [`wecomx::Client`] 构建失败时返回 [`wecomx::Error`]。
36    pub fn from_transport(transport: Transport) -> Result<Self, wecomx::Error> {
37        Ok(Self {
38            inner: wecomx::Client::builder()
39                .transport(transport)
40                .endpoint_catalog(crate::endpoint_catalog())
41                .build()?,
42        })
43    }
44
45    /// 包裹一个已配置好的 [`wecomx::Client`](不改动其任何配置)。
46    #[must_use]
47    pub fn from_client(inner: wecomx::Client) -> Self {
48        Self { inner }
49    }
50
51    /// 底层 [`wecomx::Client`](需要沙箱 FS、helper、扩展命令等高级配置时使用)。
52    #[must_use]
53    pub fn inner(&self) -> &wecomx::Client {
54        &self.inner
55    }
56
57    /// 消耗自身,返回底层 [`wecomx::Client`]。
58    #[must_use]
59    pub fn into_inner(self) -> wecomx::Client {
60        self.inner
61    }
62
63    /// 带鉴权的 transport(可注入默认 header、extension 等)。
64    #[must_use]
65    pub fn transport(&self) -> &Transport {
66        self.inner.transport()
67    }
68
69    /// 列出 discovery 下发的服务目录。
70    ///
71    /// # Errors
72    ///
73    /// 服务发现失败时返回 [`wecomx::Error`]。
74    pub async fn list_services(&self) -> Result<Vec<wecomx::ServiceInfo>, wecomx::Error> {
75        self.inner.list_services().await
76    }
77
78    /// 获取指定服务的句柄(服务名由 discovery 下发)。
79    ///
80    /// # Errors
81    ///
82    /// 服务不存在或发现失败时返回 [`wecomx::Error`]。
83    pub async fn service(&self, name: &str) -> Result<wecomx::ServiceHandle<'_>, wecomx::Error> {
84        self.inner.service(name).await
85    }
86
87    /// 按路径(服务名 + 资源段 + 方法名)直接获取方法句柄。
88    ///
89    /// # Errors
90    ///
91    /// 方法不存在或发现失败时返回 [`wecomx::Error`]。
92    pub async fn method(&self, path: &[&str]) -> Result<wecomx::MethodHandle<'_>, wecomx::Error> {
93        self.inner.method(path).await
94    }
95
96    /// CLI 风格的 argv 调度入口(与 `wecom-cli` 同一套命令模型)。
97    ///
98    /// 返回 [`wecomx::CliRun`](`IntoFuture`),`.await` 即执行:
99    ///
100    /// ```ignore
101    /// client.run(vec!["wecom".into(), "hr".into(), "users".into(), "list".into()])
102    ///     .await?;
103    /// ```
104    #[must_use]
105    pub fn run(&self, argv: Vec<String>) -> wecomx::CliRun<'_> {
106        self.inner.run(argv)
107    }
108}