volcengine_rust_sdk/volcengine/client/
client_info.rs

1/*
2 * @Author: Jerry.Yang
3 * @Date: 2024-10-17 16:16:16
4 * @LastEditors: Jerry.Yang
5 * @LastEditTime: 2025-02-05 14:28:58
6 * @Description: client_info
7 */
8use crate::volcengine::client::config;
9use crate::volcengine::error::error;
10
11#[derive(Debug, Clone)]
12// The `ClientInfo` struct holds metadata about a cloud service, including the service's name,
13// API version, and the signing region required for requests.
14pub struct ClientInfo {
15    pub service_name: config::ClientServiceName, // The name of the service (e.g., IAM, S3)
16    // pub service_id: config::ClientServiceId, // A unique identifier for the service (optional)
17    // pub endpoint: String, // The endpoint URL for the service (optional)
18    pub api_version: String, // The API version used for the service (e.g., "v1", "v2")
19    // pub signing_name: String, // The name used for signing requests (optional)
20    // The region used for signing requests, typically the AWS region
21    // pub json_version: String, // The version of the JSON protocol used (optional)
22    // pub target_prefix: String, // The target prefix for the request (optional)
23    pub signing_region: String,
24}
25
26// The `ClientInfo` struct provides a way to represent metadata required for making authenticated
27// API requests to cloud services. This implementation provides a way to configure and manage information
28// about the service being interacted with, such as its name, API version, and region, which are needed
29// to correctly sign and send requests to a cloud service endpoint.
30//
31// The `impl ClientInfo` block provides an implementation for the methods related to creating and managing
32// `ClientInfo` instances. One key method is `builder()`, which returns a `ClientInfoBuilder` that allows
33// clients to incrementally construct a `ClientInfo` object using the builder pattern. The builder pattern
34// is useful because it allows for flexible construction of the object, providing an easy way to set only
35// the necessary fields while leaving others as optional.
36//
37// The `ClientInfo` struct is designed for use when interacting with a cloud service API and needs
38// metadata for signing requests. The builder pattern ensures that the object can be properly configured
39// before being used to make requests.
40impl ClientInfo {
41    // Provides a method to create a new `ClientInfoBuilder`, which follows the builder pattern
42    // for constructing `ClientInfo` with required fields.
43    pub fn builder() -> ClientInfoBuilder {
44        ClientInfoBuilder {
45            service_name: None, // The service name, which must be set later
46            // service_id: None, // Optional service identifier
47            // endpoint: None, // Optional endpoint URL
48            api_version: None, // The API version, which must be set later
49            // signing_name: None, // Optional signing name
50            // The signing region, which must be set later
51            // json_version: None, // Optional JSON version
52            // target_prefix: None, // Optional target prefix
53            signing_region: None,
54        }
55    }
56}
57
58// The `ClientInfoBuilder` struct implements the builder pattern, allowing clients to incrementally
59// set up fields to construct a valid `ClientInfo` object.
60pub struct ClientInfoBuilder {
61    pub service_name: Option<config::ClientServiceName>, // Option type allows for optional fields
62    // pub service_id: Option<config::ClientServiceId>, // Optional service ID
63    // pub endpoint: Option<String>, // Optional endpoint URL
64    pub api_version: Option<String>, // The API version, if provided
65    // pub signing_name: Option<String>, // Optional signing name
66    // The signing region, if provided
67    // pub json_version: Option<String>, // Optional JSON version
68    // pub target_prefix: Option<String>, // Optional target prefix
69    pub signing_region: Option<String>,
70}
71
72// The `ClientInfoBuilder` struct implements the builder pattern for creating instances of the
73// `ClientInfo` struct. The builder pattern is useful for constructing an object step by step, allowing
74// optional fields to be set and ensuring that the final object is valid before being built.
75//
76// `ClientInfoBuilder` starts with all fields as `None` and provides a set of methods to progressively
77// assign values to the `ClientInfo` struct. Once all required fields are set, the `build` method can be
78// called to generate a fully constructed `ClientInfo` instance. If any required fields are missing,
79// an error will be returned.
80//
81// This pattern is designed to make it easier to create `ClientInfo` objects with varying configurations,
82// especially in cases where some fields are optional or have default values.
83impl ClientInfoBuilder {
84    // Sets the `service_name` field for the builder.
85    // The `service_name` field holds the name of the cloud service (e.g., IAM, S3)
86    // that the client will interact with.
87    //
88    // # Arguments:
89    // - `service_name`: The name of the service as a `ClientServiceName`.
90    //
91    // # Returns:
92    // Returns the builder instance (`Self`) to allow for method chaining.
93    pub fn with_service_name(mut self, service_name: config::ClientServiceName) -> Self {
94        self.service_name = Some(service_name); // Set the `service_name` in the builder.
95        self // Return the builder instance for method chaining.
96    }
97
98    // // Sets the `service_id` field (commented out for now).
99    // pub fn with_service_id(mut self, service_id: config::ClientServiceId) -> Self {
100    //     self.service_id = Some(service_id);
101    //     self
102    // }
103
104    // // Sets the `endpoint` field (commented out for now).
105    // pub fn with_endpoint(mut self, endpoint: &str) -> Self {
106    //     self.endpoint = Some(endpoint.to_string());
107    //     self
108    // }
109
110    // Sets the `api_version` field for the builder.
111    // The `api_version` field holds the version of the API that the client will use.
112    //
113    // # Arguments:
114    // - `api_version`: A string slice (`&str`) representing the version of the API (e.g., "v1", "v2").
115    //
116    // # Returns:
117    // Returns the builder instance (`Self`) to allow for method chaining.
118    pub fn with_api_version(mut self, api_version: &str) -> Self {
119        self.api_version = Some(api_version.to_string()); // Set the `api_version` in the builder.
120        self // Return the builder instance for method chaining.
121    }
122
123    // // Sets the `signing_name` field (commented out for now).
124    // pub fn with_signing_name(mut self, signing_name: &str) -> Self {
125    //     self.signing_name = Some(signing_name.to_string());
126    //     self
127    // }
128
129    // Sets the `signing_region` field for the builder.
130    // The `signing_region` field specifies the region used for signing requests,
131    // typically the AWS region or a similar regional identifier.
132    //
133    // # Arguments:
134    // - `signing_region`: A string slice (`&str`) representing the region used for signing requests.
135    //
136    // # Returns:
137    // Returns the builder instance (`Self`) to allow for method chaining.
138    pub fn with_signing_region(mut self, signing_region: &str) -> Self {
139        self.signing_region = Some(signing_region.to_string()); // Set the `signing_region` in the builder.
140        self // Return the builder instance for method chaining.
141    }
142
143    // // Sets the `json_version` field (commented out for now).
144    // pub fn with_json_version(mut self,json_version : &str) -> Self {
145    //     self.json_version = Some(json_version.to_string());
146    //     self
147    // }
148
149    // // Sets the `target_prefix` field (commented out for now).
150    // pub fn with_target_prefix(mut self,target_prefix : &str) -> Self {
151    //     self.target_prefix = Some(target_prefix.to_string());
152    //     self
153    // }
154
155    // Finalizes the builder and creates a `ClientInfo` object.
156    // Returns an error if any required fields are missing or not set.
157    //
158    // The `build` function validates that all necessary fields are provided before constructing
159    // the `ClientInfo` object. If any required field is missing, an error is returned.
160    //
161    // # Returns:
162    // - `Result<ClientInfo, error::Error>`: On success, returns a `ClientInfo` object. On failure,
163    //   returns an error indicating which required field is missing.
164    pub fn build(self) -> Result<ClientInfo, error::Error> {
165        // Ensure `service_name` is provided, otherwise return an error
166        if self.service_name.is_none() {
167            return Err(error::Error::ErrUtilClientBuildClientInfoNo(
168                "service_name".to_string(),
169            ));
170        }
171
172        // // Ensure `service_id` is provided (if this field is uncommented)
173        // if self.service_id.is_none() {
174        //     return Err(error::Error::ErrUtilClientBuildClientInfoNo(
175        //         "service_id".to_string(),
176        //     ));
177        // }
178
179        // // Ensure `endpoint` is provided (if this field is uncommented)
180        // if self.endpoint.is_none() {
181        //     return Err(error::Error::ErrUtilClientBuildClientInfoNo(
182        //         "endpoint".to_string(),
183        //     ));
184        // }
185
186        // Ensure `api_version` is provided, otherwise return an error
187        if self.api_version.is_none() {
188            return Err(error::Error::ErrUtilClientBuildClientInfoNo(
189                "api_version".to_string(),
190            ));
191        }
192
193        // // Ensure `signing_name` is provided (if this field is uncommented)
194        // if self.signing_name.is_none() {
195        //     return Err(error::Error::ErrUtilClientBuildClientInfoNo(
196        //         "signing_name".to_string(),
197        //     ));
198        // }
199
200        // Ensure `signing_region` is provided, otherwise return an error
201        if self.signing_region.is_none() {
202            return Err(error::Error::ErrUtilClientBuildClientInfoNo(
203                "signing_region".to_string(),
204            ));
205        }
206
207        // Construct and return the `ClientInfo` object, filling in the fields.
208        let client_info = ClientInfo {
209            service_name: self.service_name.unwrap(), // Unwrap to get the value of service_name
210            // service_id: self.service_id.unwrap(), // If service_id is used, uncomment this line
211            // endpoint: self.endpoint.unwrap(), // If endpoint is used, uncomment this line
212            api_version: self.api_version.unwrap(), // Unwrap to get the value of api_version
213            // signing_name: self.signing_name.unwrap(), // If signing_name is used, uncomment this line
214            // Unwrap to get the value of signing_region
215            // json_version: self.json_version.unwrap_or_default(), // If json_version is used, uncomment this line
216            // target_prefix: self.target_prefix.unwrap_or_default(), // If target_prefix is used, uncomment this line
217            signing_region: self.signing_region.unwrap(),
218        };
219
220        // Return the constructed `ClientInfo` object inside a Result.
221        Ok(client_info)
222    }
223}