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}