baml/raw_objects/
http.rs

1//! HTTP types for request/response introspection
2//!
3//! These wrap FFI pointers to HTTP objects managed by the BAML runtime.
4
5use std::{collections::HashMap, ffi::c_void};
6
7use super::{RawObject, RawObjectTrait};
8use crate::{baml_unreachable, error::BamlError, proto::baml_cffi_v1::BamlObjectType};
9
10// =============================================================================
11// HTTPBody
12// =============================================================================
13
14define_raw_object_wrapper! {
15    /// HTTP request or response body
16    HTTPBody => ObjectHttpBody
17}
18
19impl HTTPBody {
20    /// Get body as text (UTF-8 decoded)
21    pub fn text(&self) -> Result<String, BamlError> {
22        self.raw.try_call_method("text", ())
23    }
24
25    /// Get body as JSON value
26    ///
27    /// Parses the body text as JSON. Returns an error if the body is not valid
28    /// JSON.
29    pub fn json(&self) -> Result<serde_json::Value, BamlError> {
30        let text: String = self.raw.try_call_method("text", ())?;
31        serde_json::from_str(&text)
32            .map_err(|e| BamlError::internal(format!("failed to parse JSON: {e}")))
33    }
34}
35
36// =============================================================================
37// HTTPRequest
38// =============================================================================
39
40define_raw_object_wrapper! {
41    /// HTTP request details
42    HTTPRequest => ObjectHttpRequest
43}
44
45impl HTTPRequest {
46    /// Get the request ID
47    pub fn id(&self) -> String {
48        self.raw.call_method("id", ())
49    }
50
51    /// Get the request URL
52    pub fn url(&self) -> String {
53        self.raw.call_method("url", ())
54    }
55
56    /// Get the HTTP method (GET, POST, etc.)
57    pub fn method(&self) -> String {
58        self.raw.call_method("method", ())
59    }
60
61    /// Get request headers
62    pub fn headers(&self) -> HashMap<String, String> {
63        self.raw.call_method("headers", ())
64    }
65
66    /// Get the request body
67    pub fn body(&self) -> HTTPBody {
68        self.raw
69            .call_method_for_object("body", ())
70            .unwrap_or_else(|e| baml_unreachable!("Failed to get body: {e}"))
71    }
72}
73
74// =============================================================================
75// HTTPResponse
76// =============================================================================
77
78define_raw_object_wrapper! {
79    /// HTTP response details
80    HTTPResponse => ObjectHttpResponse
81}
82
83impl HTTPResponse {
84    /// Get the request ID this response corresponds to
85    pub fn id(&self) -> String {
86        self.raw.call_method("id", ())
87    }
88
89    /// Get the HTTP status code
90    pub fn status(&self) -> i64 {
91        self.raw.call_method("status", ())
92    }
93
94    /// Get response headers
95    pub fn headers(&self) -> HashMap<String, String> {
96        self.raw.call_method("headers", ())
97    }
98
99    /// Get the response body
100    pub fn body(&self) -> HTTPBody {
101        self.raw
102            .call_method_for_object("body", ())
103            .unwrap_or_else(|e| baml_unreachable!("Failed to get body: {e}"))
104    }
105}
106
107// =============================================================================
108// SSEResponse
109// =============================================================================
110
111define_raw_object_wrapper! {
112    /// Server-Sent Event response chunk
113    SSEResponse => ObjectSseResponse
114}
115
116impl SSEResponse {
117    /// Get the SSE data as text
118    pub fn text(&self) -> String {
119        self.raw.call_method("text", ())
120    }
121
122    /// Try to parse the SSE data as JSON
123    pub fn json(&self) -> Option<serde_json::Value> {
124        let text: String = self.raw.call_method("text", ());
125        serde_json::from_str(&text).ok()
126    }
127}