1use crate::datadog;
5use async_stream::try_stream;
6use flate2::{
7 write::{GzEncoder, ZlibEncoder},
8 Compression,
9};
10use futures_core::stream::Stream;
11use reqwest::header::{HeaderMap, HeaderValue};
12use serde::{Deserialize, Serialize};
13use std::io::Write;
14
15#[non_exhaustive]
17#[derive(Clone, Default, Debug)]
18pub struct ListCIAppTestEventsOptionalParams {
19 pub filter_query: Option<String>,
21 pub filter_from: Option<chrono::DateTime<chrono::Utc>>,
23 pub filter_to: Option<chrono::DateTime<chrono::Utc>>,
25 pub sort: Option<crate::datadogV2::model::CIAppSort>,
27 pub page_cursor: Option<String>,
29 pub page_limit: Option<i32>,
31}
32
33impl ListCIAppTestEventsOptionalParams {
34 pub fn filter_query(mut self, value: String) -> Self {
36 self.filter_query = Some(value);
37 self
38 }
39 pub fn filter_from(mut self, value: chrono::DateTime<chrono::Utc>) -> Self {
41 self.filter_from = Some(value);
42 self
43 }
44 pub fn filter_to(mut self, value: chrono::DateTime<chrono::Utc>) -> Self {
46 self.filter_to = Some(value);
47 self
48 }
49 pub fn sort(mut self, value: crate::datadogV2::model::CIAppSort) -> Self {
51 self.sort = Some(value);
52 self
53 }
54 pub fn page_cursor(mut self, value: String) -> Self {
56 self.page_cursor = Some(value);
57 self
58 }
59 pub fn page_limit(mut self, value: i32) -> Self {
61 self.page_limit = Some(value);
62 self
63 }
64}
65
66#[non_exhaustive]
68#[derive(Clone, Default, Debug)]
69pub struct SearchCIAppTestEventsOptionalParams {
70 pub body: Option<crate::datadogV2::model::CIAppTestEventsRequest>,
71}
72
73impl SearchCIAppTestEventsOptionalParams {
74 pub fn body(mut self, value: crate::datadogV2::model::CIAppTestEventsRequest) -> Self {
75 self.body = Some(value);
76 self
77 }
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize)]
82#[serde(untagged)]
83pub enum AggregateCIAppTestEventsError {
84 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
85 UnknownValue(serde_json::Value),
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90#[serde(untagged)]
91pub enum ListCIAppTestEventsError {
92 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
93 UnknownValue(serde_json::Value),
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
98#[serde(untagged)]
99pub enum SearchCIAppTestEventsError {
100 APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
101 UnknownValue(serde_json::Value),
102}
103
104#[derive(Debug, Clone)]
106pub struct CIVisibilityTestsAPI {
107 config: datadog::Configuration,
108 client: reqwest_middleware::ClientWithMiddleware,
109}
110
111impl Default for CIVisibilityTestsAPI {
112 fn default() -> Self {
113 Self::with_config(datadog::Configuration::default())
114 }
115}
116
117impl CIVisibilityTestsAPI {
118 pub fn new() -> Self {
119 Self::default()
120 }
121 pub fn with_config(config: datadog::Configuration) -> Self {
122 let mut reqwest_client_builder = reqwest::Client::builder();
123
124 if let Some(proxy_url) = &config.proxy_url {
125 let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
126 reqwest_client_builder = reqwest_client_builder.proxy(proxy);
127 }
128
129 let mut middleware_client_builder =
130 reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
131
132 if config.enable_retry {
133 struct RetryableStatus;
134 impl reqwest_retry::RetryableStrategy for RetryableStatus {
135 fn handle(
136 &self,
137 res: &Result<reqwest::Response, reqwest_middleware::Error>,
138 ) -> Option<reqwest_retry::Retryable> {
139 match res {
140 Ok(success) => reqwest_retry::default_on_request_success(success),
141 Err(_) => None,
142 }
143 }
144 }
145 let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
146 .build_with_max_retries(config.max_retries);
147
148 let retry_middleware =
149 reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
150 backoff_policy,
151 RetryableStatus,
152 );
153
154 middleware_client_builder = middleware_client_builder.with(retry_middleware);
155 }
156
157 let client = middleware_client_builder.build();
158
159 Self { config, client }
160 }
161
162 pub fn with_client_and_config(
163 config: datadog::Configuration,
164 client: reqwest_middleware::ClientWithMiddleware,
165 ) -> Self {
166 Self { config, client }
167 }
168
169 pub async fn aggregate_ci_app_test_events(
171 &self,
172 body: crate::datadogV2::model::CIAppTestsAggregateRequest,
173 ) -> Result<
174 crate::datadogV2::model::CIAppTestsAnalyticsAggregateResponse,
175 datadog::Error<AggregateCIAppTestEventsError>,
176 > {
177 match self.aggregate_ci_app_test_events_with_http_info(body).await {
178 Ok(response_content) => {
179 if let Some(e) = response_content.entity {
180 Ok(e)
181 } else {
182 Err(datadog::Error::Serde(serde::de::Error::custom(
183 "response content was None",
184 )))
185 }
186 }
187 Err(err) => Err(err),
188 }
189 }
190
191 pub async fn aggregate_ci_app_test_events_with_http_info(
193 &self,
194 body: crate::datadogV2::model::CIAppTestsAggregateRequest,
195 ) -> Result<
196 datadog::ResponseContent<crate::datadogV2::model::CIAppTestsAnalyticsAggregateResponse>,
197 datadog::Error<AggregateCIAppTestEventsError>,
198 > {
199 let local_configuration = &self.config;
200 let operation_id = "v2.aggregate_ci_app_test_events";
201
202 let local_client = &self.client;
203
204 let local_uri_str = format!(
205 "{}/api/v2/ci/tests/analytics/aggregate",
206 local_configuration.get_operation_host(operation_id)
207 );
208 let mut local_req_builder =
209 local_client.request(reqwest::Method::POST, local_uri_str.as_str());
210
211 let mut headers = HeaderMap::new();
213 headers.insert("Content-Type", HeaderValue::from_static("application/json"));
214 headers.insert("Accept", HeaderValue::from_static("application/json"));
215
216 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
218 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
219 Err(e) => {
220 log::warn!("Failed to parse user agent header: {e}, falling back to default");
221 headers.insert(
222 reqwest::header::USER_AGENT,
223 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
224 )
225 }
226 };
227
228 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
230 headers.insert(
231 "DD-API-KEY",
232 HeaderValue::from_str(local_key.key.as_str())
233 .expect("failed to parse DD-API-KEY header"),
234 );
235 };
236 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
237 headers.insert(
238 "DD-APPLICATION-KEY",
239 HeaderValue::from_str(local_key.key.as_str())
240 .expect("failed to parse DD-APPLICATION-KEY header"),
241 );
242 };
243
244 let output = Vec::new();
246 let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
247 if body.serialize(&mut ser).is_ok() {
248 if let Some(content_encoding) = headers.get("Content-Encoding") {
249 match content_encoding.to_str().unwrap_or_default() {
250 "gzip" => {
251 let mut enc = GzEncoder::new(Vec::new(), Compression::default());
252 let _ = enc.write_all(ser.into_inner().as_slice());
253 match enc.finish() {
254 Ok(buf) => {
255 local_req_builder = local_req_builder.body(buf);
256 }
257 Err(e) => return Err(datadog::Error::Io(e)),
258 }
259 }
260 "deflate" => {
261 let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
262 let _ = enc.write_all(ser.into_inner().as_slice());
263 match enc.finish() {
264 Ok(buf) => {
265 local_req_builder = local_req_builder.body(buf);
266 }
267 Err(e) => return Err(datadog::Error::Io(e)),
268 }
269 }
270 "zstd1" => {
271 let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
272 let _ = enc.write_all(ser.into_inner().as_slice());
273 match enc.finish() {
274 Ok(buf) => {
275 local_req_builder = local_req_builder.body(buf);
276 }
277 Err(e) => return Err(datadog::Error::Io(e)),
278 }
279 }
280 _ => {
281 local_req_builder = local_req_builder.body(ser.into_inner());
282 }
283 }
284 } else {
285 local_req_builder = local_req_builder.body(ser.into_inner());
286 }
287 }
288
289 local_req_builder = local_req_builder.headers(headers);
290 let local_req = local_req_builder.build()?;
291 log::debug!("request content: {:?}", local_req.body());
292 let local_resp = local_client.execute(local_req).await?;
293
294 let local_status = local_resp.status();
295 let local_content = local_resp.text().await?;
296 log::debug!("response content: {}", local_content);
297
298 if !local_status.is_client_error() && !local_status.is_server_error() {
299 match serde_json::from_str::<
300 crate::datadogV2::model::CIAppTestsAnalyticsAggregateResponse,
301 >(&local_content)
302 {
303 Ok(e) => {
304 return Ok(datadog::ResponseContent {
305 status: local_status,
306 content: local_content,
307 entity: Some(e),
308 })
309 }
310 Err(e) => return Err(datadog::Error::Serde(e)),
311 };
312 } else {
313 let local_entity: Option<AggregateCIAppTestEventsError> =
314 serde_json::from_str(&local_content).ok();
315 let local_error = datadog::ResponseContent {
316 status: local_status,
317 content: local_content,
318 entity: local_entity,
319 };
320 Err(datadog::Error::ResponseError(local_error))
321 }
322 }
323
324 pub async fn list_ci_app_test_events(
329 &self,
330 params: ListCIAppTestEventsOptionalParams,
331 ) -> Result<
332 crate::datadogV2::model::CIAppTestEventsResponse,
333 datadog::Error<ListCIAppTestEventsError>,
334 > {
335 match self.list_ci_app_test_events_with_http_info(params).await {
336 Ok(response_content) => {
337 if let Some(e) = response_content.entity {
338 Ok(e)
339 } else {
340 Err(datadog::Error::Serde(serde::de::Error::custom(
341 "response content was None",
342 )))
343 }
344 }
345 Err(err) => Err(err),
346 }
347 }
348
349 pub fn list_ci_app_test_events_with_pagination(
350 &self,
351 mut params: ListCIAppTestEventsOptionalParams,
352 ) -> impl Stream<
353 Item = Result<
354 crate::datadogV2::model::CIAppTestEvent,
355 datadog::Error<ListCIAppTestEventsError>,
356 >,
357 > + '_ {
358 try_stream! {
359 let mut page_size: i32 = 10;
360 if params.page_limit.is_none() {
361 params.page_limit = Some(page_size);
362 } else {
363 page_size = params.page_limit.unwrap().clone();
364 }
365 loop {
366 let resp = self.list_ci_app_test_events(params.clone()).await?;
367 let Some(data) = resp.data else { break };
368
369 let r = data;
370 let count = r.len();
371 for team in r {
372 yield team;
373 }
374
375 if count < page_size as usize {
376 break;
377 }
378 let Some(meta) = resp.meta else { break };
379 let Some(page) = meta.page else { break };
380 let Some(after) = page.after else { break };
381
382 params.page_cursor = Some(after);
383 }
384 }
385 }
386
387 pub async fn list_ci_app_test_events_with_http_info(
392 &self,
393 params: ListCIAppTestEventsOptionalParams,
394 ) -> Result<
395 datadog::ResponseContent<crate::datadogV2::model::CIAppTestEventsResponse>,
396 datadog::Error<ListCIAppTestEventsError>,
397 > {
398 let local_configuration = &self.config;
399 let operation_id = "v2.list_ci_app_test_events";
400
401 let filter_query = params.filter_query;
403 let filter_from = params.filter_from;
404 let filter_to = params.filter_to;
405 let sort = params.sort;
406 let page_cursor = params.page_cursor;
407 let page_limit = params.page_limit;
408
409 let local_client = &self.client;
410
411 let local_uri_str = format!(
412 "{}/api/v2/ci/tests/events",
413 local_configuration.get_operation_host(operation_id)
414 );
415 let mut local_req_builder =
416 local_client.request(reqwest::Method::GET, local_uri_str.as_str());
417
418 if let Some(ref local_query_param) = filter_query {
419 local_req_builder =
420 local_req_builder.query(&[("filter[query]", &local_query_param.to_string())]);
421 };
422 if let Some(ref local_query_param) = filter_from {
423 local_req_builder = local_req_builder.query(&[(
424 "filter[from]",
425 &local_query_param.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
426 )]);
427 };
428 if let Some(ref local_query_param) = filter_to {
429 local_req_builder = local_req_builder.query(&[(
430 "filter[to]",
431 &local_query_param.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
432 )]);
433 };
434 if let Some(ref local_query_param) = sort {
435 local_req_builder =
436 local_req_builder.query(&[("sort", &local_query_param.to_string())]);
437 };
438 if let Some(ref local_query_param) = page_cursor {
439 local_req_builder =
440 local_req_builder.query(&[("page[cursor]", &local_query_param.to_string())]);
441 };
442 if let Some(ref local_query_param) = page_limit {
443 local_req_builder =
444 local_req_builder.query(&[("page[limit]", &local_query_param.to_string())]);
445 };
446
447 let mut headers = HeaderMap::new();
449 headers.insert("Accept", HeaderValue::from_static("application/json"));
450
451 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
453 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
454 Err(e) => {
455 log::warn!("Failed to parse user agent header: {e}, falling back to default");
456 headers.insert(
457 reqwest::header::USER_AGENT,
458 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
459 )
460 }
461 };
462
463 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
465 headers.insert(
466 "DD-API-KEY",
467 HeaderValue::from_str(local_key.key.as_str())
468 .expect("failed to parse DD-API-KEY header"),
469 );
470 };
471 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
472 headers.insert(
473 "DD-APPLICATION-KEY",
474 HeaderValue::from_str(local_key.key.as_str())
475 .expect("failed to parse DD-APPLICATION-KEY header"),
476 );
477 };
478
479 local_req_builder = local_req_builder.headers(headers);
480 let local_req = local_req_builder.build()?;
481 log::debug!("request content: {:?}", local_req.body());
482 let local_resp = local_client.execute(local_req).await?;
483
484 let local_status = local_resp.status();
485 let local_content = local_resp.text().await?;
486 log::debug!("response content: {}", local_content);
487
488 if !local_status.is_client_error() && !local_status.is_server_error() {
489 match serde_json::from_str::<crate::datadogV2::model::CIAppTestEventsResponse>(
490 &local_content,
491 ) {
492 Ok(e) => {
493 return Ok(datadog::ResponseContent {
494 status: local_status,
495 content: local_content,
496 entity: Some(e),
497 })
498 }
499 Err(e) => return Err(datadog::Error::Serde(e)),
500 };
501 } else {
502 let local_entity: Option<ListCIAppTestEventsError> =
503 serde_json::from_str(&local_content).ok();
504 let local_error = datadog::ResponseContent {
505 status: local_status,
506 content: local_content,
507 entity: local_entity,
508 };
509 Err(datadog::Error::ResponseError(local_error))
510 }
511 }
512
513 pub async fn search_ci_app_test_events(
518 &self,
519 params: SearchCIAppTestEventsOptionalParams,
520 ) -> Result<
521 crate::datadogV2::model::CIAppTestEventsResponse,
522 datadog::Error<SearchCIAppTestEventsError>,
523 > {
524 match self.search_ci_app_test_events_with_http_info(params).await {
525 Ok(response_content) => {
526 if let Some(e) = response_content.entity {
527 Ok(e)
528 } else {
529 Err(datadog::Error::Serde(serde::de::Error::custom(
530 "response content was None",
531 )))
532 }
533 }
534 Err(err) => Err(err),
535 }
536 }
537
538 pub fn search_ci_app_test_events_with_pagination(
539 &self,
540 mut params: SearchCIAppTestEventsOptionalParams,
541 ) -> impl Stream<
542 Item = Result<
543 crate::datadogV2::model::CIAppTestEvent,
544 datadog::Error<SearchCIAppTestEventsError>,
545 >,
546 > + '_ {
547 try_stream! {
548 let mut page_size: i32 = 10;
549 if params.body.is_none() {
550 params.body = Some(crate::datadogV2::model::CIAppTestEventsRequest::new());
551 }
552 if params.body.as_ref().unwrap().page.is_none() {
553 params.body.as_mut().unwrap().page = Some(crate::datadogV2::model::CIAppQueryPageOptions::new());
554 }
555 if params.body.as_ref().unwrap().page.as_ref().unwrap().limit.is_none() {
556 params.body.as_mut().unwrap().page.as_mut().unwrap().limit = Some(page_size);
557 } else {
558 page_size = params.body.as_ref().unwrap().page.as_ref().unwrap().limit.unwrap().clone();
559 }
560 loop {
561 let resp = self.search_ci_app_test_events(params.clone()).await?;
562 let Some(data) = resp.data else { break };
563
564 let r = data;
565 let count = r.len();
566 for team in r {
567 yield team;
568 }
569
570 if count < page_size as usize {
571 break;
572 }
573 let Some(meta) = resp.meta else { break };
574 let Some(page) = meta.page else { break };
575 let Some(after) = page.after else { break };
576
577 params.body.as_mut().unwrap().page.as_mut().unwrap().cursor = Some(after);
578 }
579 }
580 }
581
582 pub async fn search_ci_app_test_events_with_http_info(
587 &self,
588 params: SearchCIAppTestEventsOptionalParams,
589 ) -> Result<
590 datadog::ResponseContent<crate::datadogV2::model::CIAppTestEventsResponse>,
591 datadog::Error<SearchCIAppTestEventsError>,
592 > {
593 let local_configuration = &self.config;
594 let operation_id = "v2.search_ci_app_test_events";
595
596 let body = params.body;
598
599 let local_client = &self.client;
600
601 let local_uri_str = format!(
602 "{}/api/v2/ci/tests/events/search",
603 local_configuration.get_operation_host(operation_id)
604 );
605 let mut local_req_builder =
606 local_client.request(reqwest::Method::POST, local_uri_str.as_str());
607
608 let mut headers = HeaderMap::new();
610 headers.insert("Content-Type", HeaderValue::from_static("application/json"));
611 headers.insert("Accept", HeaderValue::from_static("application/json"));
612
613 match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
615 Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
616 Err(e) => {
617 log::warn!("Failed to parse user agent header: {e}, falling back to default");
618 headers.insert(
619 reqwest::header::USER_AGENT,
620 HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
621 )
622 }
623 };
624
625 if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
627 headers.insert(
628 "DD-API-KEY",
629 HeaderValue::from_str(local_key.key.as_str())
630 .expect("failed to parse DD-API-KEY header"),
631 );
632 };
633 if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
634 headers.insert(
635 "DD-APPLICATION-KEY",
636 HeaderValue::from_str(local_key.key.as_str())
637 .expect("failed to parse DD-APPLICATION-KEY header"),
638 );
639 };
640
641 let output = Vec::new();
643 let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
644 if body.serialize(&mut ser).is_ok() {
645 if let Some(content_encoding) = headers.get("Content-Encoding") {
646 match content_encoding.to_str().unwrap_or_default() {
647 "gzip" => {
648 let mut enc = GzEncoder::new(Vec::new(), Compression::default());
649 let _ = enc.write_all(ser.into_inner().as_slice());
650 match enc.finish() {
651 Ok(buf) => {
652 local_req_builder = local_req_builder.body(buf);
653 }
654 Err(e) => return Err(datadog::Error::Io(e)),
655 }
656 }
657 "deflate" => {
658 let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
659 let _ = enc.write_all(ser.into_inner().as_slice());
660 match enc.finish() {
661 Ok(buf) => {
662 local_req_builder = local_req_builder.body(buf);
663 }
664 Err(e) => return Err(datadog::Error::Io(e)),
665 }
666 }
667 "zstd1" => {
668 let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
669 let _ = enc.write_all(ser.into_inner().as_slice());
670 match enc.finish() {
671 Ok(buf) => {
672 local_req_builder = local_req_builder.body(buf);
673 }
674 Err(e) => return Err(datadog::Error::Io(e)),
675 }
676 }
677 _ => {
678 local_req_builder = local_req_builder.body(ser.into_inner());
679 }
680 }
681 } else {
682 local_req_builder = local_req_builder.body(ser.into_inner());
683 }
684 }
685
686 local_req_builder = local_req_builder.headers(headers);
687 let local_req = local_req_builder.build()?;
688 log::debug!("request content: {:?}", local_req.body());
689 let local_resp = local_client.execute(local_req).await?;
690
691 let local_status = local_resp.status();
692 let local_content = local_resp.text().await?;
693 log::debug!("response content: {}", local_content);
694
695 if !local_status.is_client_error() && !local_status.is_server_error() {
696 match serde_json::from_str::<crate::datadogV2::model::CIAppTestEventsResponse>(
697 &local_content,
698 ) {
699 Ok(e) => {
700 return Ok(datadog::ResponseContent {
701 status: local_status,
702 content: local_content,
703 entity: Some(e),
704 })
705 }
706 Err(e) => return Err(datadog::Error::Serde(e)),
707 };
708 } else {
709 let local_entity: Option<SearchCIAppTestEventsError> =
710 serde_json::from_str(&local_content).ok();
711 let local_error = datadog::ResponseContent {
712 status: local_status,
713 content: local_content,
714 entity: local_entity,
715 };
716 Err(datadog::Error::ResponseError(local_error))
717 }
718 }
719}