cloud_sdk_testkit/
metadata.rs1use cloud_sdk::rate_limit::RateLimit;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub enum FixtureMetadataError {
8 PaginationZero,
10 PageAfterLast,
12 InvalidLastPage,
14 RemainingExceedsLimit,
16 RateLimitZero,
18 InvalidProgress,
20}
21
22impl_static_error!(FixtureMetadataError,
23 Self::PaginationZero => "fixture pagination value must be nonzero",
24 Self::PageAfterLast => "fixture page exceeds the last page",
25 Self::InvalidLastPage => "fixture last-page metadata is invalid",
26 Self::RemainingExceedsLimit => "fixture remaining requests exceed the rate limit",
27 Self::RateLimitZero => "fixture rate limit must be nonzero",
28 Self::InvalidProgress => "fixture action progress exceeds 100",
29);
30
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub struct PaginationFixture {
34 page: u64,
35 per_page: u64,
36 total_entries: u64,
37 last_page: u64,
38}
39
40impl PaginationFixture {
41 pub const fn new(
43 page: u64,
44 per_page: u64,
45 total_entries: u64,
46 last_page: u64,
47 ) -> Result<Self, FixtureMetadataError> {
48 if page == 0 || per_page == 0 || last_page == 0 {
49 return Err(FixtureMetadataError::PaginationZero);
50 }
51 if page > last_page {
52 return Err(FixtureMetadataError::PageAfterLast);
53 }
54 let mut expected_last = match total_entries.checked_div(per_page) {
55 Some(value) => value,
56 None => return Err(FixtureMetadataError::PaginationZero),
57 };
58 let remainder = match total_entries.checked_rem(per_page) {
59 Some(value) => value,
60 None => return Err(FixtureMetadataError::PaginationZero),
61 };
62 if remainder != 0 {
63 expected_last = match expected_last.checked_add(1) {
64 Some(value) => value,
65 None => return Err(FixtureMetadataError::InvalidLastPage),
66 };
67 }
68 if expected_last == 0 {
69 expected_last = 1;
70 }
71 if last_page != expected_last {
72 return Err(FixtureMetadataError::InvalidLastPage);
73 }
74 Ok(Self {
75 page,
76 per_page,
77 total_entries,
78 last_page,
79 })
80 }
81
82 #[must_use]
84 pub const fn page(self) -> u64 {
85 self.page
86 }
87
88 #[must_use]
90 pub const fn per_page(self) -> u64 {
91 self.per_page
92 }
93
94 #[must_use]
96 pub const fn total_entries(self) -> u64 {
97 self.total_entries
98 }
99
100 #[must_use]
102 pub const fn last_page(self) -> u64 {
103 self.last_page
104 }
105}
106
107#[derive(Clone, Copy, Debug, Eq, PartialEq)]
109pub enum ActionState {
110 Running,
112 Success,
114 Error,
116}
117
118#[derive(Clone, Copy, Debug, Eq, PartialEq)]
120pub struct ActionFixture {
121 state: ActionState,
122 progress: u8,
123}
124
125impl ActionFixture {
126 pub const fn new(state: ActionState, progress: u8) -> Result<Self, FixtureMetadataError> {
128 if progress > 100 {
129 return Err(FixtureMetadataError::InvalidProgress);
130 }
131 Ok(Self { state, progress })
132 }
133
134 #[must_use]
136 pub const fn state(self) -> ActionState {
137 self.state
138 }
139
140 #[must_use]
142 pub const fn progress(self) -> u8 {
143 self.progress
144 }
145}
146
147#[derive(Clone, Copy, Debug, Eq, PartialEq)]
149pub struct RateLimitFixture {
150 limit: u64,
151 remaining: u64,
152 reset_at: u64,
153}
154
155impl RateLimitFixture {
156 pub const fn new(
158 limit: u64,
159 remaining: u64,
160 reset_at: u64,
161 ) -> Result<Self, FixtureMetadataError> {
162 if limit == 0 {
163 return Err(FixtureMetadataError::RateLimitZero);
164 }
165 if remaining > limit {
166 return Err(FixtureMetadataError::RemainingExceedsLimit);
167 }
168 Ok(Self {
169 limit,
170 remaining,
171 reset_at,
172 })
173 }
174
175 #[must_use]
177 pub const fn limit(self) -> u64 {
178 self.limit
179 }
180
181 #[must_use]
183 pub const fn remaining(self) -> u64 {
184 self.remaining
185 }
186
187 #[must_use]
189 pub const fn reset_at(self) -> u64 {
190 self.reset_at
191 }
192
193 pub(crate) const fn into_rate_limit(self) -> Result<RateLimit, FixtureMetadataError> {
194 match RateLimit::new(self.limit, self.remaining, self.reset_at) {
195 Ok(value) => Ok(value),
196 Err(_) => Err(FixtureMetadataError::RemainingExceedsLimit),
197 }
198 }
199}