Skip to main content

bothan_bitfinex/api/
builder.rs

1//! Builder for constructing Bitfinex REST API clients.
2//!
3//! This module provides the [`RestApiBuilder`] for creating configured instances of the Bitfinex REST API client.
4//! It offers a fluent interface for setting configuration options such as the API URL before building the client.
5//!
6//! This module provides:
7//!
8//! - Fluent builder pattern for creating REST API clients
9//! - URL configuration and validation
10//! - HTTP client creation and configuration
11//! - Error handling for invalid configurations
12
13use reqwest::ClientBuilder;
14use url::Url;
15
16use crate::api::error::BuildError;
17use crate::api::rest::{DEFAULT_URL, RestApi};
18
19/// A builder for creating configured Bitfinex REST API clients.
20///
21/// The `RestApiBuilder` provides a fluent interface for setting configuration options
22/// before creating a `RestApi` instance. It handles URL parsing and HTTP client creation.
23///
24/// # Examples
25///
26/// ```rust
27/// use bothan_bitfinex::api::builder::RestApiBuilder;
28///
29/// // Create a builder with default URL
30/// let api = RestApiBuilder::default()
31///     .build()
32///     .expect("Failed to build API client");
33///
34/// // Create a builder with custom URL
35/// let api = RestApiBuilder::new("https://api-pub.bitfinex.com/v2/")
36///     .build()
37///     .expect("Failed to build API client");
38///
39/// // Use the fluent interface
40/// let api = RestApiBuilder::default()
41///     .with_url("https://api-pub.bitfinex.com/v2/")
42///     .build()
43///     .expect("Failed to build API client");
44/// ```
45pub struct RestApiBuilder {
46    /// The URL for the Bitfinex API.
47    url: String,
48}
49
50impl RestApiBuilder {
51    /// Creates a new `RestApiBuilder` with the specified URL.
52    ///
53    /// # Parameters
54    ///
55    /// - `url`: The URL for the Bitfinex API as a string
56    ///
57    /// # Returns
58    ///
59    /// A new `RestApiBuilder` instance with the specified URL.
60    ///
61    /// # Examples
62    ///
63    /// ```rust
64    /// use bothan_bitfinex::api::builder::RestApiBuilder;
65    ///
66    /// let builder = RestApiBuilder::new("https://api-pub.bitfinex.com/v2/");
67    /// ```
68    pub fn new<T: Into<String>>(url: T) -> Self {
69        RestApiBuilder { url: url.into() }
70    }
71
72    /// Sets the URL for the Bitfinex API.
73    ///
74    /// This method allows changing the URL after the builder has been created.
75    /// It returns the builder instance for method chaining.
76    ///
77    /// # Parameters
78    ///
79    /// - `url`: The new URL for the Bitfinex API
80    ///
81    /// # Returns
82    ///
83    /// The builder instance with the updated URL for method chaining.
84    ///
85    /// # Examples
86    ///
87    /// ```rust
88    /// use bothan_bitfinex::api::builder::RestApiBuilder;
89    ///
90    /// let builder = RestApiBuilder::default()
91    ///     .with_url("https://api-pub.bitfinex.com/v2/");
92    /// ```
93    pub fn with_url<T: Into<String>>(mut self, url: T) -> Self {
94        self.url = url.into();
95        self
96    }
97
98    /// Builds a `RestApi` instance with the current configuration.
99    ///
100    /// This method validates the URL, creates an HTTP client, and returns a configured
101    /// `RestApi` instance. If the URL is invalid or the HTTP client cannot be created,
102    /// an error is returned.
103    ///
104    /// # Returns
105    ///
106    /// Returns a `Result` containing a `RestApi` instance on success,
107    /// or a `BuildError` if the configuration is invalid.
108    ///
109    /// # Errors
110    ///
111    /// Returns a `BuildError` if:
112    /// - The URL is invalid and cannot be parsed (`InvalidURL`)
113    /// - The HTTP client cannot be created (`FailedToBuild`)
114    ///
115    /// # Examples
116    ///
117    /// ```rust
118    /// use bothan_bitfinex::api::builder::RestApiBuilder;
119    ///
120    /// match RestApiBuilder::new("https://api-pub.bitfinex.com/v2/").build() {
121    ///     Ok(api) => println!("API client created successfully"),
122    ///     Err(e) => eprintln!("Failed to create API client: {}", e),
123    /// }
124    /// ```
125    pub fn build(self) -> Result<RestApi, BuildError> {
126        let parsed_url = Url::parse(&self.url)?;
127
128        let client = ClientBuilder::new().build()?;
129
130        Ok(RestApi::new(parsed_url, client))
131    }
132}
133
134impl Default for RestApiBuilder {
135    /// Creates a new `RestApiBuilder` with the default Bitfinex API URL.
136    ///
137    /// This method initializes the builder with the default Bitfinex API URL,
138    /// which can then be customized using the builder methods.
139    ///
140    /// # Returns
141    ///
142    /// A new `RestApiBuilder` instance with the default URL.
143    ///
144    /// # Examples
145    ///
146    /// ```rust
147    /// use bothan_bitfinex::api::builder::RestApiBuilder;
148    ///
149    /// let builder = RestApiBuilder::default();
150    /// let api = builder.build().expect("Failed to build API client");
151    /// ```
152    fn default() -> Self {
153        RestApiBuilder {
154            url: DEFAULT_URL.into(),
155        }
156    }
157}