timber_rust/service/aws/config.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
3
4#![cfg(feature = "aws")]
5#![cfg_attr(docsrs, doc(cfg(feature = "aws")))]
6
7use std::time::SystemTime;
8
9/// Configuration for the AWS CloudWatch service.
10///
11/// This struct holds all necessary credentials and identifiers to authenticate
12/// and send logs to a specific CloudWatch Log Group.
13///
14/// # Note
15/// While this configuration is explicit, the underlying SDK can often
16/// fall back to environment variables if certain fields are left as default.
17#[derive(Clone)]
18pub struct Config {
19 /// AWS Access Key ID used for authentication.
20 pub(crate) access_key_id: String,
21 /// AWS Secret Access Key. This field is sensitive and hidden in Debug logs.
22 pub(crate) access_key_secret: String,
23 /// Optional session token for temporary credentials (STS).
24 pub(crate) session_token: Option<String>,
25 /// Optional expiration timestamp for the credentials in seconds.
26 pub(crate) expires_in: Option<SystemTime>,
27 /// The name of the CloudWatch Log Group where logs will be sent.
28 pub(crate) log_group: String,
29 /// The AWS Region (e.g., "us-east-1").
30 pub(crate) region: String,
31 /// Identifier for the provider or application generating the logs.
32 pub(crate) provider: &'static str,
33}
34
35impl Config {
36 /// Creates a new `Config` instance with required parameters.
37 ///
38 /// # Arguments
39 /// * `access_key_id` - The AWS Access Key.
40 /// * `access_key_secret` - The AWS Secret Key.
41 /// * `log_group` - The target CloudWatch Log Group name.
42 /// * `region` - The AWS region string.
43 ///
44 /// # Defaults:
45 /// provider: "timber-rust"
46 ///
47 /// # Example
48 /// ```rust
49 /// # use timber_rust::service::aws::Config;
50 /// let config = Config::new("AKIA...", "secret", "my-logs", "us-east-1");
51 /// ```
52 pub fn new<S1, S2, S3, S4>(
53 access_key_id: S1,
54 access_key_secret: S2,
55 log_group: S3,
56 region: S4,
57 ) -> Self
58 where
59 S1: Into<String>,
60 S2: Into<String>,
61 S3: Into<String>,
62 S4: Into<String>,
63 {
64 Config {
65 access_key_id: access_key_id.into(),
66 access_key_secret: access_key_secret.into(),
67 session_token: None,
68 expires_in: None,
69 log_group: log_group.into(),
70 region: region.into(),
71 provider: "timber-rust",
72 }
73 }
74
75 /// Returns the AWS Access Key ID.
76 pub fn get_access_key_id(&self) -> &str {
77 &self.access_key_id
78 }
79
80 /// Returns the AWS Secret Access Key.
81 pub fn get_access_key_secret(&self) -> &str {
82 &self.access_key_secret
83 }
84
85 /// Returns the AWS Session Token, if any.
86 pub fn get_session_token(&self) -> Option<&str> {
87 self.session_token.as_deref()
88 }
89
90 /// Returns the expiration time of the credentials in seconds.
91 pub fn get_expires_in(&self) -> Option<SystemTime> {
92 self.expires_in
93 }
94
95 /// Returns the target CloudWatch Log Group name.
96 pub fn get_log_group(&self) -> &str {
97 &self.log_group
98 }
99
100 /// Returns the AWS Region string.
101 pub fn get_region(&self) -> &str {
102 &self.region
103 }
104
105 /// Returns the provider name string.
106 pub fn get_provider(&self) -> &'static str {
107 &self.provider
108 }
109
110 // --- Builder Pattern Methods ---
111
112 /// Sets the AWS Access Key ID.
113 pub fn access_key_id(mut self, v: impl Into<String>) -> Self {
114 self.access_key_id = v.into();
115 self
116 }
117
118 /// Sets the AWS Secret Access Key.
119 pub fn access_key_secret(mut self, v: impl Into<String>) -> Self {
120 self.access_key_secret = v.into();
121 self
122 }
123
124 /// Sets an optional AWS Session Token.
125 pub fn session_token(mut self, v: Option<impl Into<String>>) -> Self {
126 self.session_token = v.map(|v| v.into());
127 self
128 }
129
130 /// Sets the credential expiration time (in seconds).
131 pub fn expires_in(mut self, v: Option<SystemTime>) -> Self {
132 self.expires_in = v;
133 self
134 }
135
136 /// Sets the target CloudWatch Log Group.
137 pub fn log_group(mut self, v: impl Into<String>) -> Self {
138 self.log_group = v.into();
139 self
140 }
141
142 /// Sets the AWS Region.
143 pub fn region(mut self, v: impl Into<String>) -> Self {
144 self.region = v.into();
145 self
146 }
147
148 /// Sets the provider name for this configuration.
149 pub fn provider(mut self, v: &'static str) -> Self {
150 self.provider = v;
151 self
152 }
153}
154
155impl std::fmt::Debug for Config {
156 /// Formats the configuration for debugging purposes.
157 /// Note that `access_key_secret` is masked for security.
158 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159 let mut d = f.debug_struct("Config");
160
161 d.field("access_key_id", &self.access_key_id)
162 .field("access_key_secret", &"***")
163 .field("log_group", &self.log_group)
164 .field("region", &self.region)
165 .field("provider", &self.provider);
166
167 #[cfg(debug_assertions)]
168 {
169 d.field("access_key_secret", &self.access_key_secret);
170 }
171 #[cfg(not(debug_assertions))]
172 {
173 d.field("access_key_secret", &"***");
174 }
175
176 d.finish()
177 }
178}