volcengine_rust_sdk/volcengine/session/session.rs
1/*
2 * @Author: Jerry.Yang
3 * @Date: 2024-10-17 16:05:11
4 * @LastEditors: Jerry.Yang
5 * @LastEditTime: 2025-02-05 11:38:41
6 * @Description: Session management for Volcengine clients.
7 */
8use crate::volcengine::client::config as client_config; // Importing client configuration
9use crate::volcengine::config; // Importing the main configuration
10use crate::volcengine::endpoint::endpoint; // Importing endpoint handling
11use crate::volcengine::error::error; // Importing custom error types
12use crate::volcengine::request::handles; // Importing request handling
13use crate::volcengine::util::url; // Importing URL utilities
14
15/// Represents a session for interacting with Volcengine services.
16///
17/// A `Session` contains the configuration and request handles required to communicate
18/// with Volcengine services.
19#[derive(Debug, Clone)]
20pub struct Session {
21 config: config::Config, // Configuration for the session
22 handles: handles::Handles, // Handles for managing requests
23}
24
25/// Represents a session for managing the state and context of an ongoing process or interaction.
26///
27/// The `Session` struct is typically used to manage data, configurations, or resources that are
28/// required to maintain continuity across multiple interactions or requests within a specific context.
29/// A session might track user states, configurations, or other critical parameters that need to
30/// persist during the interaction period. This struct will hold all necessary information relevant
31/// to the session's lifecycle and its associated operations.
32impl Session {
33 /// Creates a new `SessionBuilder` for constructing `Session` instances.
34 ///
35 /// # Returns
36 /// A `SessionBuilder` instance initialized with empty configuration and handles.
37 pub fn builder() -> SessionBuilder {
38 SessionBuilder {
39 config: None,
40 handles: None,
41 } // Initialize builder with None values
42 }
43
44 /// Creates a new `client_config::Config` for the specified service name.
45 ///
46 /// This method configures a new client by cloning the session's base configuration and
47 /// setting specific endpoint and signing details for the given service name.
48 ///
49 /// # Arguments
50 /// - `client_service_name`: The name of the client service.
51 ///
52 /// # Returns
53 /// A `client_config::Config` instance ready to be used for API requests.
54 pub fn new_client_config(
55 &self,
56 client_service_name: client_config::ClientServiceName, // The name of the client service
57 ) -> client_config::Config {
58 // Initialize client_config::Config explicitly without using Default
59 let mut client_config = client_config::Config {
60 config: self.config.clone(), // Clone the session's config
61 endpoint: String::new(), // Initialize endpoint as an empty string
62 signing_region: String::new(), // Initialize signing region as empty
63 signing_name: String::new(), // Initialize signing name as empty
64 signing_name_derived: false, // Initialize derived signing name flag
65 handles: self.handles.clone(), // Clone the session's handles
66 };
67
68 // Set endpoint if not provided
69 if client_config.config.endpoint.is_empty() {
70 // Generate endpoint URL based on service name and region
71 let endpoint_url = url::Url {
72 service_name: client_service_name, // Service name
73 region: self.config.region.clone(), // Region from session config
74 }
75 .get_endpoint();
76 client_config.config.endpoint = endpoint_url.to_string(); // Assign generated endpoint
77 }
78
79 // Resolve the endpoint and signing information
80 let resolved_endpoint = self.resolve_endpoint(&client_config.config.endpoint);
81 client_config.endpoint = resolved_endpoint.url; // Set the resolved URL
82 client_config.signing_region = resolved_endpoint.signing_region; // Set signing region
83 client_config.signing_name = resolved_endpoint.signing_name; // Set signing name
84 client_config.signing_name_derived = resolved_endpoint.signing_name_derived; // Set derived signing name flag
85
86 // Return the configured client
87 client_config
88 }
89
90 /// Resolves the endpoint URL and signing details for the given endpoint.
91 ///
92 /// This method ensures that the endpoint URL is properly formatted and includes the correct
93 /// signing details required for secure API interactions.
94 ///
95 /// # Arguments
96 /// - `endpoint`: The endpoint URL to be resolved.
97 ///
98 /// # Returns
99 /// A `ResolvedEndpoint` containing the fully resolved URL, signing region, and signing name.
100 fn resolve_endpoint(&self, endpoint: &str) -> endpoint::ResolvedEndpoint {
101 // Initialize a new ResolvedEndpoint with empty values
102 let mut resolved_endpoint = endpoint::ResolvedEndpoint {
103 url: String::new(), // URL placeholder
104 signing_region: String::new(), // Signing region placeholder
105 signing_name: String::new(), // Signing name placeholder
106 signing_name_derived: false, // Derived signing name flag placeholder
107 };
108
109 // If the endpoint is not empty, resolve it
110 if !endpoint.is_empty() {
111 let endpoint_url = endpoint::add_scheme(endpoint, self.config.disable_ssl); // Add scheme to URL
112 resolved_endpoint.url = endpoint_url; // Set resolved URL
113 resolved_endpoint.signing_region = self.config.region.clone(); // Set signing region from session config
114 }
115
116 // Return the resolved endpoint
117 resolved_endpoint
118 }
119}
120
121/// Builder struct for creating a Session instance step-by-step.
122///
123/// The `SessionBuilder` allows you to configure and create a `Session` by
124/// specifying the necessary configuration and request handles.
125pub struct SessionBuilder {
126 config: Option<config::Config>, // Optional configuration for the session
127 handles: Option<handles::Handles>, // Optional handles for requests
128}
129
130/// Builder for constructing a `Session` instance.
131///
132/// The `SessionBuilder` is used to incrementally construct a `Session` object, allowing for the
133/// configuration of various parameters before finalizing the session. It provides a flexible way
134/// to build and configure a `Session` by setting different attributes such as configuration,
135/// user-specific data, or other relevant parameters required for session management.
136///
137/// The builder pattern allows for creating a `Session` with multiple optional components in a
138/// controlled manner, without forcing users to provide all attributes at once.
139///
140/// # Example:
141/// ```rust
142/// let session = SessionBuilder::new()
143/// .with_config(config)
144/// .with_user_info(user_info)
145/// .build();
146/// ```
147impl SessionBuilder {
148 /// Sets the configuration for the session builder.
149 ///
150 /// This method allows you to provide the configuration that will be used
151 /// for the session.
152 ///
153 /// # Arguments
154 /// - `config`: The configuration to be used for the session.
155 ///
156 /// # Returns
157 /// The modified `SessionBuilder` instance with the specified configuration.
158 pub fn with_config(mut self, config: config::Config) -> Self {
159 self.config = Some(config); // Store the provided config
160 self
161 }
162
163 /// Sets the handles for the session builder.
164 ///
165 /// This method allows you to provide custom request handles that will be
166 /// used for managing requests in the session.
167 ///
168 /// # Arguments
169 /// - `handles`: The handles to be used for managing requests.
170 ///
171 /// # Returns
172 /// The modified `SessionBuilder` instance with the specified handles.
173 pub fn with_handles(mut self, handles: handles::Handles) -> Self {
174 self.handles = Some(handles); // Store the provided handles
175 self
176 }
177
178 /// Builds the final `Session` object.
179 ///
180 /// This method checks if all required fields have been provided and creates
181 /// the `Session` instance. If any required fields are missing, an error is returned.
182 ///
183 /// # Returns
184 /// - `Ok(Session)`: The successfully built `Session`.
185 /// - `Err(error::Error)`: An error if required fields are missing.
186 pub fn build(self) -> Result<Session, error::Error> {
187 // Check if config is provided; return an error if not
188 if self.config.is_none() {
189 return Err(error::Error::ErrUtilSessionBuildSessionNoConfig); // Error for missing config
190 }
191
192 // Create and return a Session instance, using default handles if not provided
193 Ok(Session {
194 config: self.config.unwrap(), // Unwrap config (guaranteed to be Some)
195 handles: handles::Handles {}, // Use default handles if None
196 })
197 }
198}