Skip to main content

openai_core/
response_meta.rs

1//! 响应元数据定义。
2
3use std::ops::{Deref, DerefMut};
4
5use bytes::Bytes;
6use http::{HeaderMap, StatusCode};
7
8use crate::providers::ProviderKind;
9
10/// 表示一次响应携带的元信息。
11#[derive(Debug, Clone)]
12pub struct ResponseMeta {
13    /// HTTP 状态码。
14    pub status: StatusCode,
15    /// 响应头。
16    pub headers: HeaderMap,
17    /// 请求 ID。
18    pub request_id: Option<String>,
19    /// Provider 类型。
20    pub provider: ProviderKind,
21    /// 实际尝试次数。
22    pub attempts: usize,
23    /// 最终命中的 URL。
24    pub url: String,
25}
26
27/// 表示带有元信息的响应对象。
28#[derive(Debug, Clone)]
29pub struct ApiResponse<T> {
30    /// 反序列化后的数据对象。
31    pub data: T,
32    /// 附带的响应元数据。
33    pub meta: ResponseMeta,
34}
35
36impl<T> ApiResponse<T> {
37    /// 创建新的带元信息响应。
38    pub fn new(data: T, meta: ResponseMeta) -> Self {
39        Self { data, meta }
40    }
41
42    /// 把响应拆分成数据与元信息。
43    pub fn into_parts(self) -> (T, ResponseMeta) {
44        (self.data, self.meta)
45    }
46}
47
48impl<T> Deref for ApiResponse<T> {
49    type Target = T;
50
51    fn deref(&self) -> &Self::Target {
52        &self.data
53    }
54}
55
56impl<T> DerefMut for ApiResponse<T> {
57    fn deref_mut(&mut self) -> &mut Self::Target {
58        &mut self.data
59    }
60}
61
62/// 把字节响应转换为标准的 `http::Response<Bytes>`。
63pub fn into_http_response(meta: &ResponseMeta, body: Bytes) -> http::Response<Bytes> {
64    let mut response = http::Response::builder().status(meta.status);
65
66    if let Some(headers) = response.headers_mut() {
67        headers.extend(meta.headers.clone());
68    }
69
70    response
71        .body(body)
72        .unwrap_or_else(|_| http::Response::new(Bytes::new()))
73}