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}