openrouter_rs/
utils.rs

1use crate::{api::errors::ApiErrorResponse, error::OpenRouterError};
2use surf::Response;
3
4/// A macro for generating builder-style setter methods.
5///
6/// This macro provides two variants:
7/// 1. Direct assignment: `setter!(field_name, FieldType)`
8/// 2. Automatic Into conversion: `setter!(field_name, into TargetType)`
9///
10/// # Examples
11///
12/// ```rust
13/// struct Builder {
14///     name: Option<String>,
15///     count: Option<u32>,
16/// }
17///
18/// impl Builder {
19///     setter!(name, into String);  // Accepts any type that implements Into<String>
20///     setter!(count, u32);         // Only accepts u32
21///
22///     pub fn build(self) -> Self {
23///         self
24///     }
25/// }
26///
27/// let builder = Builder {
28///     name: None,
29///     count: None,
30/// }
31/// .name("test")    // &str automatically converted to String
32/// .count(42);      // Direct u32 assignment
33/// ```
34#[macro_export]
35macro_rules! setter {
36    // Direct value assignment
37    ($name:ident, $type:ty) => {
38        #[doc = concat!("Sets the `", stringify!($name), "` field directly.")]
39        pub fn $name(mut self, value: $type) -> Self {
40            self.$name = Some(value);
41            self
42        }
43    };
44
45    // Automatic Into conversion
46    ($name:ident, into $type:ty) => {
47        #[doc = concat!("Sets the `", stringify!($name), "` field with automatic conversion using `Into<", stringify!($type), ">`.")]
48        pub fn $name(mut self, value: impl Into<$type>) -> Self {
49            self.$name = Some(value.into());
50            self
51        }
52    };
53}
54
55pub async fn handle_error(mut response: Response) -> Result<(), OpenRouterError> {
56    let status = response.status();
57    let text = response
58        .body_string()
59        .await
60        .unwrap_or_else(|_| "Failed to read response text".to_string());
61    let api_error_response: Result<ApiErrorResponse, _> = serde_json::from_str(&text);
62
63    if let Ok(api_error_response) = api_error_response {
64        Err(OpenRouterError::from(api_error_response))
65    } else {
66        Err(OpenRouterError::ApiError {
67            code: status,
68            message: text,
69        })
70    }
71}