gout_api/lib.rs
1//! # Gout API
2//!
3//! [Gout](https://github.com/fb0sh/Gout) 的 Rust SDK。
4//!
5//! 包含共享协议类型和两个客户端:
6//!
7//! | 模块 | 用途 | 认证 |
8//! |------|------|------|
9//! | [`client`] | 隧道操作(创建/列出/删除) | 普通 `api-key` |
10//! | [`admin`] | 管理操作(创建/列出/删除 API key) | `admin-api-key` |
11//! | [`data_channel`] | 数据通道握手和 TCP 转发(底层协议) | token 认证 |
12//!
13//! # 快速开始
14//!
15//! ```no_run
16//! # async fn doc() {
17//! use gout_api::client::GoutClient;
18//! use gout_api::admin::GoutAdminClient;
19//! use gout_api::TunnelType;
20//!
21//! let gout = GoutClient::new("server:8080", "sk-xxx");
22//! let tun = gout.create_tunnel(TunnelType::Tcp, 4000).await.unwrap();
23//! gout.delete_tunnel(tun.token).await.unwrap();
24//!
25//! let admin = GoutAdminClient::new("server:8080", "admin-key");
26//! let key = admin.create_key("my laptop").await.unwrap();
27//! # }
28//! ```
29
30use anyhow::Context;
31
32pub mod admin;
33pub mod client;
34pub mod data_channel;
35
36mod proto;
37pub use proto::*;
38
39// ━━━ 内部 HTTP 辅助 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
40
41/// 解析 REST API 响应体,提取 `data` 字段。
42/// 非 2xx 时从 `error` 字段构造错误信息。
43pub(crate) async fn parse_api_response<T>(
44 resp: reqwest::Response,
45) -> anyhow::Result<T>
46where
47 T: serde::de::DeserializeOwned + serde::Serialize,
48{
49 let status = resp.status();
50 if !status.is_success() {
51 let body: ApiResponse<T> = resp
52 .json()
53 .await
54 .unwrap_or(ApiResponse {
55 success: false,
56 data: None,
57 error: Some(status.to_string()),
58 });
59 anyhow::bail!("{}", body.error.unwrap_or_default());
60 }
61 let body: ApiResponse<T> = resp.json().await?;
62 body.data.context("no data in response")
63}