Skip to content

Commit 7de821d

Browse files
committed
feat(redis-cloud): expand additional response types with list fields
Continue ergonomics improvements from #373 by exposing list fields in wrapper types instead of hiding them in 'extra'. Changes: - CloudAccount: Added console_username, console_password, access_secret_key - CloudAccounts: Added cloud_accounts list field - AccountSubscriptions: Added subscriptions list field - AccountACLUsers: Added users list field - AccountACLRedisRules: Added redis_rules list field - AccountACLRoles: Added roles list field This eliminates more boilerplate for common list operations and provides direct type-safe access to nested collections.
1 parent baf74f9 commit 7de821d

File tree

4 files changed

+77
-16
lines changed

4 files changed

+77
-16
lines changed

crates/redis-cloud/src/acl.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,33 +115,47 @@ pub struct AclUserUpdateRequest {
115115
}
116116

117117
/// Redis list of ACL users in current account
118+
///
119+
/// Response from GET /acl/users
118120
#[derive(Debug, Clone, Serialize, Deserialize)]
119121
#[serde(rename_all = "camelCase")]
120122
pub struct AccountACLUsers {
123+
/// Account ID
121124
#[serde(skip_serializing_if = "Option::is_none")]
122125
pub account_id: Option<i32>,
123126

124-
/// HATEOAS links
127+
/// List of ACL users (typically in extra as 'users' array)
128+
#[serde(skip_serializing_if = "Option::is_none")]
129+
pub users: Option<Vec<ACLUser>>,
130+
131+
/// HATEOAS links for API navigation
125132
#[serde(skip_serializing_if = "Option::is_none")]
126133
pub links: Option<Vec<HashMap<String, Value>>>,
127134

128-
/// Additional fields from the API
135+
/// Only for truly unknown/future API fields
129136
#[serde(flatten)]
130137
pub extra: Value,
131138
}
132139

133140
/// Redis list of ACL redis rules in current account
141+
///
142+
/// Response from GET /acl/redisRules
134143
#[derive(Debug, Clone, Serialize, Deserialize)]
135144
#[serde(rename_all = "camelCase")]
136145
pub struct AccountACLRedisRules {
146+
/// Account ID
137147
#[serde(skip_serializing_if = "Option::is_none")]
138148
pub account_id: Option<i32>,
139149

140-
/// HATEOAS links
150+
/// List of Redis ACL rules (typically in extra as 'redisRules' array)
151+
#[serde(skip_serializing_if = "Option::is_none")]
152+
pub redis_rules: Option<Vec<Value>>,
153+
154+
/// HATEOAS links for API navigation
141155
#[serde(skip_serializing_if = "Option::is_none")]
142156
pub links: Option<Vec<HashMap<String, Value>>>,
143157

144-
/// Additional fields from the API
158+
/// Only for truly unknown/future API fields
145159
#[serde(flatten)]
146160
pub extra: Value,
147161
}
@@ -165,17 +179,24 @@ pub struct AclRedisRuleCreateRequest {
165179
}
166180

167181
/// Redis list of ACL roles in current account
182+
///
183+
/// Response from GET /acl/roles
168184
#[derive(Debug, Clone, Serialize, Deserialize)]
169185
#[serde(rename_all = "camelCase")]
170186
pub struct AccountACLRoles {
187+
/// Account ID
171188
#[serde(skip_serializing_if = "Option::is_none")]
172189
pub account_id: Option<i32>,
173190

174-
/// HATEOAS links
191+
/// List of ACL roles (typically in extra as 'roles' array)
192+
#[serde(skip_serializing_if = "Option::is_none")]
193+
pub roles: Option<Vec<Value>>,
194+
195+
/// HATEOAS links for API navigation
175196
#[serde(skip_serializing_if = "Option::is_none")]
176197
pub links: Option<Vec<HashMap<String, Value>>>,
177198

178-
/// Additional fields from the API
199+
/// Only for truly unknown/future API fields
179200
#[serde(flatten)]
180201
pub extra: Value,
181202
}

crates/redis-cloud/src/cloud_accounts.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,30 +93,51 @@ pub struct CloudAccountUpdateRequest {
9393
/// RedisLabs Cloud Account information
9494
#[derive(Debug, Clone, Serialize, Deserialize)]
9595
#[serde(rename_all = "camelCase")]
96+
/// Cloud Account
97+
///
98+
/// Represents a cloud provider account integration with all known API fields
9699
pub struct CloudAccount {
100+
/// Cloud account ID
97101
#[serde(skip_serializing_if = "Option::is_none")]
98102
pub id: Option<i32>,
99103

104+
/// Cloud account display name
100105
#[serde(skip_serializing_if = "Option::is_none")]
101106
pub name: Option<String>,
102107

108+
/// Account status (e.g., "active", "error")
103109
#[serde(skip_serializing_if = "Option::is_none")]
104110
pub status: Option<String>,
105111

112+
/// Cloud provider (e.g., "AWS", "GCP", "Azure")
113+
#[serde(skip_serializing_if = "Option::is_none")]
114+
pub provider: Option<String>,
115+
116+
/// Cloud provider access key ID
106117
#[serde(skip_serializing_if = "Option::is_none")]
107118
pub access_key_id: Option<String>,
108119

120+
/// Cloud provider secret key (typically masked in responses)
109121
#[serde(skip_serializing_if = "Option::is_none")]
110-
pub sign_in_login_url: Option<String>,
122+
pub access_secret_key: Option<String>,
111123

124+
/// Cloud provider management console username
112125
#[serde(skip_serializing_if = "Option::is_none")]
113-
pub provider: Option<String>,
126+
pub console_username: Option<String>,
114127

115-
/// HATEOAS links
128+
/// Cloud provider management console password (typically masked)
129+
#[serde(skip_serializing_if = "Option::is_none")]
130+
pub console_password: Option<String>,
131+
132+
/// Cloud provider management console login URL
133+
#[serde(skip_serializing_if = "Option::is_none")]
134+
pub sign_in_login_url: Option<String>,
135+
136+
/// HATEOAS links for API navigation
116137
#[serde(skip_serializing_if = "Option::is_none")]
117138
pub links: Option<Vec<HashMap<String, Value>>>,
118139

119-
/// Additional fields from the API
140+
/// Only for truly unknown/future API fields
120141
#[serde(flatten)]
121142
pub extra: Value,
122143
}
@@ -156,17 +177,24 @@ pub struct CloudAccountCreateRequest {
156177
}
157178

158179
/// RedisLabs Cloud Accounts information
180+
///
181+
/// Response from GET /cloud-accounts containing list of cloud provider integrations
159182
#[derive(Debug, Clone, Serialize, Deserialize)]
160183
#[serde(rename_all = "camelCase")]
161184
pub struct CloudAccounts {
185+
/// Account ID
162186
#[serde(skip_serializing_if = "Option::is_none")]
163187
pub account_id: Option<i32>,
164188

165-
/// HATEOAS links
189+
/// List of cloud provider accounts (typically in extra as 'cloudAccounts' array)
190+
#[serde(skip_serializing_if = "Option::is_none")]
191+
pub cloud_accounts: Option<Vec<CloudAccount>>,
192+
193+
/// HATEOAS links for API navigation
166194
#[serde(skip_serializing_if = "Option::is_none")]
167195
pub links: Option<Vec<HashMap<String, Value>>>,
168196

169-
/// Additional fields from the API
197+
/// Only for truly unknown/future API fields
170198
#[serde(flatten)]
171199
pub extra: Value,
172200
}

crates/redis-cloud/src/flexible/subscriptions.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,17 +677,24 @@ pub struct MaintenanceWindowSpec {
677677
}
678678

679679
/// RedisLabs list of subscriptions in current account
680+
///
681+
/// Response from GET /subscriptions
680682
#[derive(Debug, Clone, Serialize, Deserialize)]
681683
#[serde(rename_all = "camelCase")]
682684
pub struct AccountSubscriptions {
685+
/// Account ID
683686
#[serde(skip_serializing_if = "Option::is_none")]
684687
pub account_id: Option<i32>,
685688

686-
/// HATEOAS links
689+
/// List of subscriptions (typically in extra as 'subscriptions' array)
690+
#[serde(skip_serializing_if = "Option::is_none")]
691+
pub subscriptions: Option<Vec<Subscription>>,
692+
693+
/// HATEOAS links for API navigation
687694
#[serde(skip_serializing_if = "Option::is_none")]
688695
pub links: Option<Vec<HashMap<String, Value>>>,
689696

690-
/// Additional fields from the API
697+
/// Only for truly unknown/future API fields
691698
#[serde(flatten)]
692699
pub extra: Value,
693700
}

crates/redis-cloud/tests/subscriptions_tests.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,13 @@ async fn test_get_all_subscriptions() {
3636
let result = handler.get_all_subscriptions().await.unwrap();
3737

3838
assert_eq!(result.account_id, Some(456));
39-
// The subscriptions are in the extra field
40-
assert!(result.extra.get("subscriptions").is_some());
39+
// The subscriptions are now first-class field
40+
assert!(result.subscriptions.is_some());
41+
let subs = result.subscriptions.unwrap();
42+
assert_eq!(subs.len(), 1);
43+
assert_eq!(subs[0].id, Some(123));
44+
assert_eq!(subs[0].name, Some("Production".to_string()));
45+
assert_eq!(subs[0].status, Some("active".to_string()));
4146
}
4247

4348
#[tokio::test]

0 commit comments

Comments
 (0)