ossify/ops/service/resource_pool/
list_resource_pools.rs1use std::future::Future;
6
7use http::Method;
8use serde::{Deserialize, Serialize};
9use serde_with::skip_serializing_none;
10
11use crate::body::NoneBody;
12use crate::error::Result;
13use crate::ops::common::ResourcePool;
14use crate::response::BodyResponseProcessor;
15use crate::ser::OnlyKeyField;
16use crate::{Client, Ops, Prepared, Request};
17
18#[skip_serializing_none]
19#[derive(Debug, Clone, Default, Serialize)]
20#[serde(rename_all = "kebab-case")]
21pub struct ListResourcePoolsParams {
22 #[serde(rename = "resourcePool")]
23 resource_pool: OnlyKeyField,
24
25 pub continuation_token: Option<String>,
26 pub max_keys: Option<u32>,
27}
28
29impl ListResourcePoolsParams {
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 pub fn continuation_token(mut self, token: impl Into<String>) -> Self {
35 self.continuation_token = Some(token.into());
36 self
37 }
38
39 pub fn max_keys(mut self, max_keys: u32) -> Self {
40 self.max_keys = Some(max_keys);
41 self
42 }
43}
44
45#[derive(Debug, Clone, Default, Deserialize)]
46#[serde(rename_all = "PascalCase")]
47pub struct ListResourcePoolsResult {
48 pub region: Option<String>,
49 pub owner: Option<String>,
50 pub continuation_token: Option<String>,
51 pub next_continuation_token: Option<String>,
52 #[serde(default)]
53 pub is_truncated: bool,
54 #[serde(default, rename = "ResourcePool")]
55 pub resource_pools: Vec<ResourcePool>,
56}
57
58pub struct ListResourcePools {
59 pub params: ListResourcePoolsParams,
60}
61
62impl Ops for ListResourcePools {
63 type Response = BodyResponseProcessor<ListResourcePoolsResult>;
64 type Body = NoneBody;
65 type Query = ListResourcePoolsParams;
66
67 const USE_BUCKET: bool = false;
68
69 fn prepare(self) -> Result<Prepared<ListResourcePoolsParams>> {
70 Ok(Prepared {
71 method: Method::GET,
72 query: Some(self.params),
73 ..Default::default()
74 })
75 }
76}
77
78pub trait ListResourcePoolsOps {
79 fn list_resource_pools(
83 &self,
84 params: Option<ListResourcePoolsParams>,
85 ) -> impl Future<Output = Result<ListResourcePoolsResult>>;
86}
87
88impl ListResourcePoolsOps for Client {
89 async fn list_resource_pools(
90 &self,
91 params: Option<ListResourcePoolsParams>,
92 ) -> Result<ListResourcePoolsResult> {
93 self.request(ListResourcePools {
94 params: params.unwrap_or_default(),
95 })
96 .await
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn params_serialize_defaults() {
106 assert_eq!(crate::ser::to_string(&ListResourcePoolsParams::new()).unwrap(), "resourcePool");
107 }
108
109 #[test]
110 fn params_serialize_with_pagination() {
111 let q = crate::ser::to_string(
112 &ListResourcePoolsParams::new()
113 .continuation_token("abc")
114 .max_keys(5),
115 )
116 .unwrap();
117 assert_eq!(q, "continuation-token=abc&max-keys=5&resourcePool");
118 }
119
120 #[test]
121 fn use_bucket_is_false() {
122 const _: () = assert!(!<ListResourcePools as Ops>::USE_BUCKET);
123 }
124
125 #[test]
126 fn parse_response() {
127 let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
128<ListResourcePoolsResult>
129 <Region>oss-cn-hangzhou</Region>
130 <Owner>103xxxx</Owner>
131 <IsTruncated>false</IsTruncated>
132 <ResourcePool>
133 <Name>rp-for-ai</Name>
134 <CreateTime>2024-11-29T08:42:32.000Z</CreateTime>
135 </ResourcePool>
136 <ResourcePool>
137 <Name>rp-for-etl</Name>
138 <CreateTime>2024-12-01T10:00:00.000Z</CreateTime>
139 </ResourcePool>
140</ListResourcePoolsResult>"#;
141 let parsed: ListResourcePoolsResult = quick_xml::de::from_str(xml).unwrap();
142 assert_eq!(parsed.region.as_deref(), Some("oss-cn-hangzhou"));
143 assert_eq!(parsed.resource_pools.len(), 2);
144 assert_eq!(parsed.resource_pools[0].name, "rp-for-ai");
145 }
146}