diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 3cabe03bba..ea6d9fe947 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -38523,6 +38523,157 @@ components: format: int64 type: integer type: object + FileCoverageLines: + description: Per-file line coverage data including executable, covered, and added lines. + properties: + added_lines: + description: Line numbers that were added in the specified scope (for example, in a PR diff). + example: [11, 12] + items: + format: int64 + type: integer + type: array + covered_lines: + description: Line numbers that were covered by tests. + example: [10, 11, 15] + items: + format: int64 + type: integer + type: array + executable_lines: + description: Line numbers that are executable (can be covered). + example: [10, 11, 12, 15, 20] + items: + format: int64 + type: integer + type: array + type: object + FilesCoverageAttributes: + description: Attributes of the per-file code coverage response. + properties: + base_commit_sha: + description: The SHA of the base commit used for comparison (for example, the merge base for a PR). + example: abc1234567890abcdef1234567890abcdef12345 + type: string + event_timestamp: + description: Unix timestamp (milliseconds) of the coverage event. + example: 1709564000000 + format: int64 + type: integer + files: + additionalProperties: + $ref: "#/components/schemas/FileCoverageLines" + description: Map of file paths to per-file coverage line data. + type: object + head_commit_sha: + description: The SHA of the head commit for which coverage was evaluated. + example: 66adc9350f2cc9b250b69abddab733dd55e1a588 + type: string + report_count: + description: Number of coverage reports evaluated. + example: 3 + format: int64 + type: integer + type: object + FilesCoverageData: + description: Data object for files coverage response. + properties: + attributes: + $ref: "#/components/schemas/FilesCoverageAttributes" + id: + description: Unique identifier for the files coverage response. + example: ZGQxMjM0NV9tYWluXzE3MDk1NjQwMDA= + type: string + type: + $ref: "#/components/schemas/FilesCoverageResponseType" + type: object + FilesCoverageRequest: + description: Request object for getting per-file code coverage data. + properties: + data: + $ref: "#/components/schemas/FilesCoverageRequestData" + required: + - data + type: object + FilesCoverageRequestAttributes: + description: Attributes for requesting per-file code coverage data. Exactly one of `commit_sha`, `branch`, or `pr_number` must be provided. At most one of `service`, `codeowner`, or `flag` may be provided. + properties: + branch: + description: The branch name. + example: main + type: string + changed_only: + description: When true, return coverage data only for files that were changed in the specified scope. + example: true + type: boolean + codeowner: + description: Filter coverage by code owner. At most one of `service`, `codeowner`, or `flag` may be provided. + example: "@my-team" + type: string + commit_sha: + description: The commit SHA (40-character hexadecimal string). + example: 66adc9350f2cc9b250b69abddab733dd55e1a588 + pattern: "^[a-fA-F0-9]{40}$" + type: string + flag: + description: Filter coverage by coverage flag. At most one of `service`, `codeowner`, or `flag` may be provided. + example: unit-tests + type: string + pr_number: + description: The pull request number. Must be a positive integer. + example: 42 + format: int64 + minimum: 1 + type: integer + repository_id: + deprecated: true + description: "Deprecated: use `repository_url` instead. The repository URL." + example: github.com/datadog/shopist + minLength: 1 + type: string + repository_url: + description: The repository URL. Accepts a full URL with or without a scheme (for example, `https://github.com/org/repo` or `github.com/org/repo`). + example: https://github.com/datadog/shopist + minLength: 1 + type: string + service: + description: Filter coverage by service name. At most one of `service`, `codeowner`, or `flag` may be provided. + example: my-service + type: string + type: object + FilesCoverageRequestData: + description: Data object for files coverage request. + properties: + attributes: + $ref: "#/components/schemas/FilesCoverageRequestAttributes" + type: + $ref: "#/components/schemas/FilesCoverageRequestType" + required: + - type + - attributes + type: object + FilesCoverageRequestType: + description: JSON:API type for files coverage request. The value must always be `ci_app_coverage_files_request`. + enum: + - ci_app_coverage_files_request + example: ci_app_coverage_files_request + type: string + x-enum-varnames: + - CI_APP_COVERAGE_FILES_REQUEST + FilesCoverageResponse: + description: Response object containing per-file code coverage data. + properties: + data: + $ref: "#/components/schemas/FilesCoverageData" + type: object + FilesCoverageResponseType: + description: JSON:API type for files coverage response. The value must always be `ci_app_coverage_files`. + enum: + - ci_app_coverage_files + example: ci_app_coverage_files + type: string + x-enum-varnames: + - CI_APP_COVERAGE_FILES FiltersPerProduct: description: Product-specific filters for the dataset. properties: @@ -79919,6 +80070,51 @@ components: type: string x-enum-varnames: - OWNERSHIP_UNTAGGED_FINDINGS + PRCoverageSummaryRequest: + description: Request object for getting code coverage summary for a pull request. + properties: + data: + $ref: "#/components/schemas/PRCoverageSummaryRequestData" + required: + - data + type: object + PRCoverageSummaryRequestAttributes: + description: Attributes for requesting code coverage summary for a pull request. + properties: + pr_number: + description: The pull request number. Must be a positive integer. + example: 42 + format: int64 + minimum: 1 + type: integer + repository_url: + description: The repository URL. Accepts a full URL with or without a scheme (for example, `https://github.com/org/repo` or `github.com/org/repo`). + example: https://github.com/datadog/shopist + minLength: 1 + type: string + required: + - repository_url + - pr_number + type: object + PRCoverageSummaryRequestData: + description: Data object for PR summary request. + properties: + attributes: + $ref: "#/components/schemas/PRCoverageSummaryRequestAttributes" + type: + $ref: "#/components/schemas/PRCoverageSummaryRequestType" + required: + - type + - attributes + type: object + PRCoverageSummaryRequestType: + description: JSON:API type for PR coverage summary request. The value must always be `ci_app_coverage_pr_summary_request`. + enum: + - ci_app_coverage_pr_summary_request + example: ci_app_coverage_pr_summary_request + type: string + x-enum-varnames: + - CI_APP_COVERAGE_PR_SUMMARY_REQUEST PageAnnotationsAttributes: description: Attributes of the annotations on a page. properties: @@ -132319,9 +132515,6 @@ paths: operator: OR permissions: - code_coverage_read - x-unstable: |- - **Note**: This endpoint is in preview and may be subject to change. - If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/code-coverage/commit/summary: post: description: |- @@ -132389,9 +132582,142 @@ paths: operator: OR permissions: - code_coverage_read - x-unstable: |- - **Note**: This endpoint is in preview and may be subject to change. - If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/code-coverage/files: + post: + description: |- + Retrieve per-file code coverage data for a specific commit, branch, or pull request. + Exactly one of `commit_sha`, `branch`, or `pr_number` must be provided. + Optionally filter by `service`, `codeowner`, or `flag` (at most one). + operationId: GetCodeCoverageFiles + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + changed_only: true + commit_sha: 66adc9350f2cc9b250b69abddab733dd55e1a588 + repository_url: https://github.com/datadog/test-service + type: ci_app_coverage_files_request + schema: + $ref: "#/components/schemas/FilesCoverageRequest" + required: true + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + base_commit_sha: abc1234567890abcdef1234567890abcdef12345 + event_timestamp: 1709564000000 + files: + src/main.go: + added_lines: [11, 12] + covered_lines: [10, 11, 15] + executable_lines: [10, 11, 12, 15, 20] + head_commit_sha: 66adc9350f2cc9b250b69abddab733dd55e1a588 + report_count: 3 + id: ZGQxMjM0NV9tYWluXzE3MDk1NjQwMDA= + type: ci_app_coverage_files + schema: + $ref: "#/components/schemas/FilesCoverageResponse" + description: OK + "400": + $ref: "#/components/responses/BadRequestResponse" + "403": + $ref: "#/components/responses/NotAuthorizedResponse" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Internal server error + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - code_coverage_read + summary: Get per-file code coverage data + tags: ["Code Coverage"] + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - code_coverage_read + /api/v2/code-coverage/pr/summary: + post: + description: |- + Retrieve aggregated code coverage statistics for a specific pull request in a repository. + This endpoint provides overall coverage metrics as well as breakdowns by service + and code owner. + operationId: GetCodeCoveragePRSummary + requestBody: + content: + application/json: + examples: + default: + value: + data: + attributes: + pr_number: 42 + repository_url: https://github.com/datadog/test-service + type: ci_app_coverage_pr_summary_request + schema: + $ref: "#/components/schemas/PRCoverageSummaryRequest" + required: true + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + evaluated_flags_count: 3 + evaluated_reports_count: 5 + patch_coverage: 65.2 + total_coverage: 78.6 + id: ZGQxMjM0NV9wcl80Ml8xNzA5NTY0MDAw + type: ci_app_coverage_summary + schema: + $ref: "#/components/schemas/CoverageSummaryResponse" + description: OK + "400": + $ref: "#/components/responses/BadRequestResponse" + "403": + $ref: "#/components/responses/NotAuthorizedResponse" + "404": + $ref: "#/components/responses/NotFoundResponse" + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/APIErrorResponse" + description: Internal server error + security: + - apiKeyAuth: [] + appKeyAuth: [] + - AuthZ: + - code_coverage_read + summary: Get code coverage summary for a pull request + tags: ["Code Coverage"] + x-codegen-request-body-name: body + x-permission: + operator: OR + permissions: + - code_coverage_read /api/v2/compliance_findings/rule_based_view: get: deprecated: true diff --git a/examples/v2_code-coverage_GetCodeCoverageBranchSummary.rs b/examples/v2_code-coverage_GetCodeCoverageBranchSummary.rs index 57dc4d9241..277a603e3a 100644 --- a/examples/v2_code-coverage_GetCodeCoverageBranchSummary.rs +++ b/examples/v2_code-coverage_GetCodeCoverageBranchSummary.rs @@ -14,8 +14,7 @@ async fn main() { .repository_url("https://github.com/datadog/shopist".to_string()), BranchCoverageSummaryRequestType::CI_APP_COVERAGE_BRANCH_SUMMARY_REQUEST, )); - let mut configuration = datadog::Configuration::new(); - configuration.set_unstable_operation_enabled("v2.GetCodeCoverageBranchSummary", true); + let configuration = datadog::Configuration::new(); let api = CodeCoverageAPI::with_config(configuration); let resp = api.get_code_coverage_branch_summary(body).await; if let Ok(value) = resp { diff --git a/examples/v2_code-coverage_GetCodeCoverageCommitSummary.rs b/examples/v2_code-coverage_GetCodeCoverageCommitSummary.rs index 2168106a70..f153e24c72 100644 --- a/examples/v2_code-coverage_GetCodeCoverageCommitSummary.rs +++ b/examples/v2_code-coverage_GetCodeCoverageCommitSummary.rs @@ -16,8 +16,7 @@ async fn main() { .repository_url("https://github.com/datadog/shopist".to_string()), CommitCoverageSummaryRequestType::CI_APP_COVERAGE_COMMIT_SUMMARY_REQUEST, )); - let mut configuration = datadog::Configuration::new(); - configuration.set_unstable_operation_enabled("v2.GetCodeCoverageCommitSummary", true); + let configuration = datadog::Configuration::new(); let api = CodeCoverageAPI::with_config(configuration); let resp = api.get_code_coverage_commit_summary(body).await; if let Ok(value) = resp { diff --git a/examples/v2_code-coverage_GetCodeCoverageFiles.rs b/examples/v2_code-coverage_GetCodeCoverageFiles.rs new file mode 100644 index 0000000000..1c53087150 --- /dev/null +++ b/examples/v2_code-coverage_GetCodeCoverageFiles.rs @@ -0,0 +1,26 @@ +// Get per-file code coverage data returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_code_coverage::CodeCoverageAPI; +use datadog_api_client::datadogV2::model::FilesCoverageRequest; +use datadog_api_client::datadogV2::model::FilesCoverageRequestAttributes; +use datadog_api_client::datadogV2::model::FilesCoverageRequestData; +use datadog_api_client::datadogV2::model::FilesCoverageRequestType; + +#[tokio::main] +async fn main() { + let body = FilesCoverageRequest::new(FilesCoverageRequestData::new( + FilesCoverageRequestAttributes::new() + .changed_only(true) + .commit_sha("66adc9350f2cc9b250b69abddab733dd55e1a588".to_string()) + .repository_url("https://github.com/datadog/shopist".to_string()), + FilesCoverageRequestType::CI_APP_COVERAGE_FILES_REQUEST, + )); + let configuration = datadog::Configuration::new(); + let api = CodeCoverageAPI::with_config(configuration); + let resp = api.get_code_coverage_files(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_code-coverage_GetCodeCoveragePRSummary.rs b/examples/v2_code-coverage_GetCodeCoveragePRSummary.rs new file mode 100644 index 0000000000..8ae2248cf5 --- /dev/null +++ b/examples/v2_code-coverage_GetCodeCoveragePRSummary.rs @@ -0,0 +1,26 @@ +// Get code coverage summary for a pull request returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_code_coverage::CodeCoverageAPI; +use datadog_api_client::datadogV2::model::PRCoverageSummaryRequest; +use datadog_api_client::datadogV2::model::PRCoverageSummaryRequestAttributes; +use datadog_api_client::datadogV2::model::PRCoverageSummaryRequestData; +use datadog_api_client::datadogV2::model::PRCoverageSummaryRequestType; + +#[tokio::main] +async fn main() { + let body = PRCoverageSummaryRequest::new(PRCoverageSummaryRequestData::new( + PRCoverageSummaryRequestAttributes::new( + 42, + "https://github.com/datadog/shopist".to_string(), + ), + PRCoverageSummaryRequestType::CI_APP_COVERAGE_PR_SUMMARY_REQUEST, + )); + let configuration = datadog::Configuration::new(); + let api = CodeCoverageAPI::with_config(configuration); + let resp = api.get_code_coverage_pr_summary(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadog/configuration.rs b/src/datadog/configuration.rs index 63b08e0a39..1cef924da2 100644 --- a/src/datadog/configuration.rs +++ b/src/datadog/configuration.rs @@ -441,8 +441,6 @@ impl Default for Configuration { "v2.validate_security_monitoring_integration_credentials".to_owned(), false, ), - ("v2.get_code_coverage_branch_summary".to_owned(), false), - ("v2.get_code_coverage_commit_summary".to_owned(), false), ("v2.get_rule_based_view".to_owned(), false), ("v2.get_commitments_commitment_list".to_owned(), false), ("v2.get_commitments_coverage_scalar".to_owned(), false), diff --git a/src/datadogV2/api/api_code_coverage.rs b/src/datadogV2/api/api_code_coverage.rs index ac1cd12c1e..c10493b2fe 100644 --- a/src/datadogV2/api/api_code_coverage.rs +++ b/src/datadogV2/api/api_code_coverage.rs @@ -6,7 +6,6 @@ use flate2::{ write::{GzEncoder, ZlibEncoder}, Compression, }; -use log::warn; use reqwest::header::{HeaderMap, HeaderValue}; use serde::{Deserialize, Serialize}; use std::io::Write; @@ -27,6 +26,22 @@ pub enum GetCodeCoverageCommitSummaryError { UnknownValue(serde_json::Value), } +/// GetCodeCoverageFilesError is a struct for typed errors of method [`CodeCoverageAPI::get_code_coverage_files`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetCodeCoverageFilesError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + +/// GetCodeCoveragePRSummaryError is a struct for typed errors of method [`CodeCoverageAPI::get_code_coverage_pr_summary`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetCodeCoveragePRSummaryError { + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// Retrieve and analyze code coverage data from Code Coverage. See the [Code Coverage page]() for more information. #[derive(Debug, Clone)] pub struct CodeCoverageAPI { @@ -140,14 +155,6 @@ impl CodeCoverageAPI { > { let local_configuration = &self.config; let local_operation_id = "v2.get_code_coverage_branch_summary"; - if local_configuration.is_unstable_operation_enabled(local_operation_id) { - warn!("Using unstable operation {local_operation_id}"); - } else { - let local_error = datadog::UnstableOperationDisabledError { - msg: "Operation 'v2.get_code_coverage_branch_summary' is not enabled".to_string(), - }; - return Err(datadog::Error::UnstableOperationDisabledError(local_error)); - } let local_client = &self.client; @@ -314,19 +321,329 @@ impl CodeCoverageAPI { > { let local_configuration = &self.config; let local_operation_id = "v2.get_code_coverage_commit_summary"; - if local_configuration.is_unstable_operation_enabled(local_operation_id) { - warn!("Using unstable operation {local_operation_id}"); + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/code-coverage/commit/summary", + local_configuration.get_operation_host(local_operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + #[cfg(feature = "zstd")] + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; } else { - let local_error = datadog::UnstableOperationDisabledError { - msg: "Operation 'v2.get_code_coverage_commit_summary' is not enabled".to_string(), + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, }; - return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + Err(datadog::Error::ResponseError(local_error)) } + } + + /// Retrieve per-file code coverage data for a specific commit, branch, or pull request. + /// Exactly one of `commit_sha`, `branch`, or `pr_number` must be provided. + /// Optionally filter by `service`, `codeowner`, or `flag` (at most one). + pub async fn get_code_coverage_files( + &self, + body: crate::datadogV2::model::FilesCoverageRequest, + ) -> Result< + crate::datadogV2::model::FilesCoverageResponse, + datadog::Error, + > { + match self.get_code_coverage_files_with_http_info(body).await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Retrieve per-file code coverage data for a specific commit, branch, or pull request. + /// Exactly one of `commit_sha`, `branch`, or `pr_number` must be provided. + /// Optionally filter by `service`, `codeowner`, or `flag` (at most one). + pub async fn get_code_coverage_files_with_http_info( + &self, + body: crate::datadogV2::model::FilesCoverageRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let local_operation_id = "v2.get_code_coverage_files"; let local_client = &self.client; let local_uri_str = format!( - "{}/api/v2/code-coverage/commit/summary", + "{}/api/v2/code-coverage/files", + local_configuration.get_operation_host(local_operation_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::POST, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", HeaderValue::from_static("application/json")); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + // build body parameters + let output = Vec::new(); + let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter); + if body.serialize(&mut ser).is_ok() { + if let Some(content_encoding) = headers.get("Content-Encoding") { + match content_encoding.to_str().unwrap_or_default() { + "gzip" => { + let mut enc = GzEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + "deflate" => { + let mut enc = ZlibEncoder::new(Vec::new(), Compression::default()); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + #[cfg(feature = "zstd")] + "zstd1" => { + let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap(); + let _ = enc.write_all(ser.into_inner().as_slice()); + match enc.finish() { + Ok(buf) => { + local_req_builder = local_req_builder.body(buf); + } + Err(e) => return Err(datadog::Error::Io(e)), + } + } + _ => { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + } else { + local_req_builder = local_req_builder.body(ser.into_inner()); + } + } + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + + /// Retrieve aggregated code coverage statistics for a specific pull request in a repository. + /// This endpoint provides overall coverage metrics as well as breakdowns by service + /// and code owner. + pub async fn get_code_coverage_pr_summary( + &self, + body: crate::datadogV2::model::PRCoverageSummaryRequest, + ) -> Result< + crate::datadogV2::model::CoverageSummaryResponse, + datadog::Error, + > { + match self.get_code_coverage_pr_summary_with_http_info(body).await { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Retrieve aggregated code coverage statistics for a specific pull request in a repository. + /// This endpoint provides overall coverage metrics as well as breakdowns by service + /// and code owner. + pub async fn get_code_coverage_pr_summary_with_http_info( + &self, + body: crate::datadogV2::model::PRCoverageSummaryRequest, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let local_operation_id = "v2.get_code_coverage_pr_summary"; + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/code-coverage/pr/summary", local_configuration.get_operation_host(local_operation_id) ); let mut local_req_builder = @@ -434,7 +751,7 @@ impl CodeCoverageAPI { Err(e) => return Err(datadog::Error::Serde(e)), }; } else { - let local_entity: Option = + let local_entity: Option = serde_json::from_str(&local_content).ok(); let local_error = datadog::ResponseContent { status: local_status, diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index cfe1ded8d7..10c0c2957f 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -2522,6 +2522,32 @@ pub mod model_commit_coverage_summary_request_attributes; pub use self::model_commit_coverage_summary_request_attributes::CommitCoverageSummaryRequestAttributes; pub mod model_commit_coverage_summary_request_type; pub use self::model_commit_coverage_summary_request_type::CommitCoverageSummaryRequestType; +pub mod model_files_coverage_request; +pub use self::model_files_coverage_request::FilesCoverageRequest; +pub mod model_files_coverage_request_data; +pub use self::model_files_coverage_request_data::FilesCoverageRequestData; +pub mod model_files_coverage_request_attributes; +pub use self::model_files_coverage_request_attributes::FilesCoverageRequestAttributes; +pub mod model_files_coverage_request_type; +pub use self::model_files_coverage_request_type::FilesCoverageRequestType; +pub mod model_files_coverage_response; +pub use self::model_files_coverage_response::FilesCoverageResponse; +pub mod model_files_coverage_data; +pub use self::model_files_coverage_data::FilesCoverageData; +pub mod model_files_coverage_attributes; +pub use self::model_files_coverage_attributes::FilesCoverageAttributes; +pub mod model_file_coverage_lines; +pub use self::model_file_coverage_lines::FileCoverageLines; +pub mod model_files_coverage_response_type; +pub use self::model_files_coverage_response_type::FilesCoverageResponseType; +pub mod model_pr_coverage_summary_request; +pub use self::model_pr_coverage_summary_request::PRCoverageSummaryRequest; +pub mod model_pr_coverage_summary_request_data; +pub use self::model_pr_coverage_summary_request_data::PRCoverageSummaryRequestData; +pub mod model_pr_coverage_summary_request_attributes; +pub use self::model_pr_coverage_summary_request_attributes::PRCoverageSummaryRequestAttributes; +pub mod model_pr_coverage_summary_request_type; +pub use self::model_pr_coverage_summary_request_type::PRCoverageSummaryRequestType; pub mod model_rule_based_view_response; pub use self::model_rule_based_view_response::RuleBasedViewResponse; pub mod model_rule_based_view_data; diff --git a/src/datadogV2/model/model_file_coverage_lines.rs b/src/datadogV2/model/model_file_coverage_lines.rs new file mode 100644 index 0000000000..48acd5006f --- /dev/null +++ b/src/datadogV2/model/model_file_coverage_lines.rs @@ -0,0 +1,142 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Per-file line coverage data including executable, covered, and added lines. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FileCoverageLines { + /// Line numbers that were added in the specified scope (for example, in a PR diff). + #[serde(rename = "added_lines")] + pub added_lines: Option>, + /// Line numbers that were covered by tests. + #[serde(rename = "covered_lines")] + pub covered_lines: Option>, + /// Line numbers that are executable (can be covered). + #[serde(rename = "executable_lines")] + pub executable_lines: Option>, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FileCoverageLines { + pub fn new() -> FileCoverageLines { + FileCoverageLines { + added_lines: None, + covered_lines: None, + executable_lines: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn added_lines(mut self, value: Vec) -> Self { + self.added_lines = Some(value); + self + } + + pub fn covered_lines(mut self, value: Vec) -> Self { + self.covered_lines = Some(value); + self + } + + pub fn executable_lines(mut self, value: Vec) -> Self { + self.executable_lines = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FileCoverageLines { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FileCoverageLines { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FileCoverageLinesVisitor; + impl<'a> Visitor<'a> for FileCoverageLinesVisitor { + type Value = FileCoverageLines; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut added_lines: Option> = None; + let mut covered_lines: Option> = None; + let mut executable_lines: Option> = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "added_lines" => { + if v.is_null() { + continue; + } + added_lines = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "covered_lines" => { + if v.is_null() { + continue; + } + covered_lines = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "executable_lines" => { + if v.is_null() { + continue; + } + executable_lines = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FileCoverageLines { + added_lines, + covered_lines, + executable_lines, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FileCoverageLinesVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_attributes.rs b/src/datadogV2/model/model_files_coverage_attributes.rs new file mode 100644 index 0000000000..f00bf06c43 --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_attributes.rs @@ -0,0 +1,183 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of the per-file code coverage response. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FilesCoverageAttributes { + /// The SHA of the base commit used for comparison (for example, the merge base for a PR). + #[serde(rename = "base_commit_sha")] + pub base_commit_sha: Option, + /// Unix timestamp (milliseconds) of the coverage event. + #[serde(rename = "event_timestamp")] + pub event_timestamp: Option, + /// Map of file paths to per-file coverage line data. + #[serde(rename = "files")] + pub files: + Option>, + /// The SHA of the head commit for which coverage was evaluated. + #[serde(rename = "head_commit_sha")] + pub head_commit_sha: Option, + /// Number of coverage reports evaluated. + #[serde(rename = "report_count")] + pub report_count: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FilesCoverageAttributes { + pub fn new() -> FilesCoverageAttributes { + FilesCoverageAttributes { + base_commit_sha: None, + event_timestamp: None, + files: None, + head_commit_sha: None, + report_count: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn base_commit_sha(mut self, value: String) -> Self { + self.base_commit_sha = Some(value); + self + } + + pub fn event_timestamp(mut self, value: i64) -> Self { + self.event_timestamp = Some(value); + self + } + + pub fn files( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.files = Some(value); + self + } + + pub fn head_commit_sha(mut self, value: String) -> Self { + self.head_commit_sha = Some(value); + self + } + + pub fn report_count(mut self, value: i64) -> Self { + self.report_count = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FilesCoverageAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FilesCoverageAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FilesCoverageAttributesVisitor; + impl<'a> Visitor<'a> for FilesCoverageAttributesVisitor { + type Value = FilesCoverageAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut base_commit_sha: Option = None; + let mut event_timestamp: Option = None; + let mut files: Option< + std::collections::BTreeMap, + > = None; + let mut head_commit_sha: Option = None; + let mut report_count: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "base_commit_sha" => { + if v.is_null() { + continue; + } + base_commit_sha = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "event_timestamp" => { + if v.is_null() { + continue; + } + event_timestamp = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "files" => { + if v.is_null() { + continue; + } + files = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "head_commit_sha" => { + if v.is_null() { + continue; + } + head_commit_sha = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "report_count" => { + if v.is_null() { + continue; + } + report_count = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FilesCoverageAttributes { + base_commit_sha, + event_timestamp, + files, + head_commit_sha, + report_count, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FilesCoverageAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_data.rs b/src/datadogV2/model/model_files_coverage_data.rs new file mode 100644 index 0000000000..5a6b98a0ce --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_data.rs @@ -0,0 +1,147 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data object for files coverage response. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FilesCoverageData { + /// Attributes of the per-file code coverage response. + #[serde(rename = "attributes")] + pub attributes: Option, + /// Unique identifier for the files coverage response. + #[serde(rename = "id")] + pub id: Option, + /// JSON:API type for files coverage response. The value must always be `ci_app_coverage_files`. + #[serde(rename = "type")] + pub type_: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FilesCoverageData { + pub fn new() -> FilesCoverageData { + FilesCoverageData { + attributes: None, + id: None, + type_: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn attributes(mut self, value: crate::datadogV2::model::FilesCoverageAttributes) -> Self { + self.attributes = Some(value); + self + } + + pub fn id(mut self, value: String) -> Self { + self.id = Some(value); + self + } + + pub fn type_(mut self, value: crate::datadogV2::model::FilesCoverageResponseType) -> Self { + self.type_ = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FilesCoverageData { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FilesCoverageData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FilesCoverageDataVisitor; + impl<'a> Visitor<'a> for FilesCoverageDataVisitor { + type Value = FilesCoverageData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option = None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + if v.is_null() { + continue; + } + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + if v.is_null() { + continue; + } + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + if v.is_null() { + continue; + } + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::FilesCoverageResponseType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FilesCoverageData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FilesCoverageDataVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_request.rs b/src/datadogV2/model/model_files_coverage_request.rs new file mode 100644 index 0000000000..7891b7f89a --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_request.rs @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request object for getting per-file code coverage data. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FilesCoverageRequest { + /// Data object for files coverage request. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::FilesCoverageRequestData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FilesCoverageRequest { + pub fn new(data: crate::datadogV2::model::FilesCoverageRequestData) -> FilesCoverageRequest { + FilesCoverageRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FilesCoverageRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FilesCoverageRequestVisitor; + impl<'a> Visitor<'a> for FilesCoverageRequestVisitor { + type Value = FilesCoverageRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = FilesCoverageRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FilesCoverageRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_request_attributes.rs b/src/datadogV2/model/model_files_coverage_request_attributes.rs new file mode 100644 index 0000000000..9cd4703842 --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_request_attributes.rs @@ -0,0 +1,256 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes for requesting per-file code coverage data. Exactly one of `commit_sha`, `branch`, or `pr_number` must be provided. At most one of `service`, `codeowner`, or `flag` may be provided. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FilesCoverageRequestAttributes { + /// The branch name. + #[serde(rename = "branch")] + pub branch: Option, + /// When true, return coverage data only for files that were changed in the specified scope. + #[serde(rename = "changed_only")] + pub changed_only: Option, + /// Filter coverage by code owner. At most one of `service`, `codeowner`, or `flag` may be provided. + #[serde(rename = "codeowner")] + pub codeowner: Option, + /// The commit SHA (40-character hexadecimal string). + #[serde(rename = "commit_sha")] + pub commit_sha: Option, + /// Filter coverage by coverage flag. At most one of `service`, `codeowner`, or `flag` may be provided. + #[serde(rename = "flag")] + pub flag: Option, + /// The pull request number. Must be a positive integer. + #[serde(rename = "pr_number")] + pub pr_number: Option, + /// Deprecated: use `repository_url` instead. The repository URL. + #[deprecated] + #[serde(rename = "repository_id")] + pub repository_id: Option, + /// The repository URL. Accepts a full URL with or without a scheme (for example, ` or `github.com/org/repo`). + #[serde(rename = "repository_url")] + pub repository_url: Option, + /// Filter coverage by service name. At most one of `service`, `codeowner`, or `flag` may be provided. + #[serde(rename = "service")] + pub service: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FilesCoverageRequestAttributes { + pub fn new() -> FilesCoverageRequestAttributes { + #[allow(deprecated)] + FilesCoverageRequestAttributes { + branch: None, + changed_only: None, + codeowner: None, + commit_sha: None, + flag: None, + pr_number: None, + repository_id: None, + repository_url: None, + service: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + #[allow(deprecated)] + pub fn branch(mut self, value: String) -> Self { + self.branch = Some(value); + self + } + + #[allow(deprecated)] + pub fn changed_only(mut self, value: bool) -> Self { + self.changed_only = Some(value); + self + } + + #[allow(deprecated)] + pub fn codeowner(mut self, value: String) -> Self { + self.codeowner = Some(value); + self + } + + #[allow(deprecated)] + pub fn commit_sha(mut self, value: String) -> Self { + self.commit_sha = Some(value); + self + } + + #[allow(deprecated)] + pub fn flag(mut self, value: String) -> Self { + self.flag = Some(value); + self + } + + #[allow(deprecated)] + pub fn pr_number(mut self, value: i64) -> Self { + self.pr_number = Some(value); + self + } + + #[allow(deprecated)] + pub fn repository_id(mut self, value: String) -> Self { + self.repository_id = Some(value); + self + } + + #[allow(deprecated)] + pub fn repository_url(mut self, value: String) -> Self { + self.repository_url = Some(value); + self + } + + #[allow(deprecated)] + pub fn service(mut self, value: String) -> Self { + self.service = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FilesCoverageRequestAttributes { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FilesCoverageRequestAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FilesCoverageRequestAttributesVisitor; + impl<'a> Visitor<'a> for FilesCoverageRequestAttributesVisitor { + type Value = FilesCoverageRequestAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut branch: Option = None; + let mut changed_only: Option = None; + let mut codeowner: Option = None; + let mut commit_sha: Option = None; + let mut flag: Option = None; + let mut pr_number: Option = None; + let mut repository_id: Option = None; + let mut repository_url: Option = None; + let mut service: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "branch" => { + if v.is_null() { + continue; + } + branch = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "changed_only" => { + if v.is_null() { + continue; + } + changed_only = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "codeowner" => { + if v.is_null() { + continue; + } + codeowner = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "commit_sha" => { + if v.is_null() { + continue; + } + commit_sha = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "flag" => { + if v.is_null() { + continue; + } + flag = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "pr_number" => { + if v.is_null() { + continue; + } + pr_number = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "repository_id" => { + if v.is_null() { + continue; + } + repository_id = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "repository_url" => { + if v.is_null() { + continue; + } + repository_url = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "service" => { + if v.is_null() { + continue; + } + service = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + #[allow(deprecated)] + let content = FilesCoverageRequestAttributes { + branch, + changed_only, + codeowner, + commit_sha, + flag, + pr_number, + repository_id, + repository_url, + service, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FilesCoverageRequestAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_request_data.rs b/src/datadogV2/model/model_files_coverage_request_data.rs new file mode 100644 index 0000000000..5f820ddedd --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_request_data.rs @@ -0,0 +1,115 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data object for files coverage request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FilesCoverageRequestData { + /// Attributes for requesting per-file code coverage data. Exactly one of `commit_sha`, `branch`, or `pr_number` must be provided. At most one of `service`, `codeowner`, or `flag` may be provided. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::FilesCoverageRequestAttributes, + /// JSON:API type for files coverage request. The value must always be `ci_app_coverage_files_request`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::FilesCoverageRequestType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FilesCoverageRequestData { + pub fn new( + attributes: crate::datadogV2::model::FilesCoverageRequestAttributes, + type_: crate::datadogV2::model::FilesCoverageRequestType, + ) -> FilesCoverageRequestData { + FilesCoverageRequestData { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for FilesCoverageRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FilesCoverageRequestDataVisitor; + impl<'a> Visitor<'a> for FilesCoverageRequestDataVisitor { + type Value = FilesCoverageRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::FilesCoverageRequestAttributes, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::FilesCoverageRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = FilesCoverageRequestData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FilesCoverageRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_request_type.rs b/src/datadogV2/model/model_files_coverage_request_type.rs new file mode 100644 index 0000000000..3993b55747 --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_request_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum FilesCoverageRequestType { + CI_APP_COVERAGE_FILES_REQUEST, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for FilesCoverageRequestType { + fn to_string(&self) -> String { + match self { + Self::CI_APP_COVERAGE_FILES_REQUEST => String::from("ci_app_coverage_files_request"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for FilesCoverageRequestType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for FilesCoverageRequestType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "ci_app_coverage_files_request" => Self::CI_APP_COVERAGE_FILES_REQUEST, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_files_coverage_response.rs b/src/datadogV2/model/model_files_coverage_response.rs new file mode 100644 index 0000000000..c9669c6a6d --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_response.rs @@ -0,0 +1,105 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Response object containing per-file code coverage data. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct FilesCoverageResponse { + /// Data object for files coverage response. + #[serde(rename = "data")] + pub data: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl FilesCoverageResponse { + pub fn new() -> FilesCoverageResponse { + FilesCoverageResponse { + data: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn data(mut self, value: crate::datadogV2::model::FilesCoverageData) -> Self { + self.data = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl Default for FilesCoverageResponse { + fn default() -> Self { + Self::new() + } +} + +impl<'de> Deserialize<'de> for FilesCoverageResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct FilesCoverageResponseVisitor; + impl<'a> Visitor<'a> for FilesCoverageResponseVisitor { + type Value = FilesCoverageResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + if v.is_null() { + continue; + } + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + + let content = FilesCoverageResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(FilesCoverageResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_files_coverage_response_type.rs b/src/datadogV2/model/model_files_coverage_response_type.rs new file mode 100644 index 0000000000..711eabf984 --- /dev/null +++ b/src/datadogV2/model/model_files_coverage_response_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum FilesCoverageResponseType { + CI_APP_COVERAGE_FILES, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for FilesCoverageResponseType { + fn to_string(&self) -> String { + match self { + Self::CI_APP_COVERAGE_FILES => String::from("ci_app_coverage_files"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for FilesCoverageResponseType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for FilesCoverageResponseType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "ci_app_coverage_files" => Self::CI_APP_COVERAGE_FILES, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_pr_coverage_summary_request.rs b/src/datadogV2/model/model_pr_coverage_summary_request.rs new file mode 100644 index 0000000000..e0de0a53ed --- /dev/null +++ b/src/datadogV2/model/model_pr_coverage_summary_request.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Request object for getting code coverage summary for a pull request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct PRCoverageSummaryRequest { + /// Data object for PR summary request. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::PRCoverageSummaryRequestData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl PRCoverageSummaryRequest { + pub fn new( + data: crate::datadogV2::model::PRCoverageSummaryRequestData, + ) -> PRCoverageSummaryRequest { + PRCoverageSummaryRequest { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for PRCoverageSummaryRequest { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PRCoverageSummaryRequestVisitor; + impl<'a> Visitor<'a> for PRCoverageSummaryRequestVisitor { + type Value = PRCoverageSummaryRequest; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = PRCoverageSummaryRequest { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(PRCoverageSummaryRequestVisitor) + } +} diff --git a/src/datadogV2/model/model_pr_coverage_summary_request_attributes.rs b/src/datadogV2/model/model_pr_coverage_summary_request_attributes.rs new file mode 100644 index 0000000000..40712558aa --- /dev/null +++ b/src/datadogV2/model/model_pr_coverage_summary_request_attributes.rs @@ -0,0 +1,104 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes for requesting code coverage summary for a pull request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct PRCoverageSummaryRequestAttributes { + /// The pull request number. Must be a positive integer. + #[serde(rename = "pr_number")] + pub pr_number: i64, + /// The repository URL. Accepts a full URL with or without a scheme (for example, ` or `github.com/org/repo`). + #[serde(rename = "repository_url")] + pub repository_url: String, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl PRCoverageSummaryRequestAttributes { + pub fn new(pr_number: i64, repository_url: String) -> PRCoverageSummaryRequestAttributes { + PRCoverageSummaryRequestAttributes { + pr_number, + repository_url, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for PRCoverageSummaryRequestAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PRCoverageSummaryRequestAttributesVisitor; + impl<'a> Visitor<'a> for PRCoverageSummaryRequestAttributesVisitor { + type Value = PRCoverageSummaryRequestAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut pr_number: Option = None; + let mut repository_url: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "pr_number" => { + pr_number = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "repository_url" => { + repository_url = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let pr_number = pr_number.ok_or_else(|| M::Error::missing_field("pr_number"))?; + let repository_url = + repository_url.ok_or_else(|| M::Error::missing_field("repository_url"))?; + + let content = PRCoverageSummaryRequestAttributes { + pr_number, + repository_url, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(PRCoverageSummaryRequestAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_pr_coverage_summary_request_data.rs b/src/datadogV2/model/model_pr_coverage_summary_request_data.rs new file mode 100644 index 0000000000..17dadee053 --- /dev/null +++ b/src/datadogV2/model/model_pr_coverage_summary_request_data.rs @@ -0,0 +1,115 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data object for PR summary request. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct PRCoverageSummaryRequestData { + /// Attributes for requesting code coverage summary for a pull request. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::PRCoverageSummaryRequestAttributes, + /// JSON:API type for PR coverage summary request. The value must always be `ci_app_coverage_pr_summary_request`. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::PRCoverageSummaryRequestType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl PRCoverageSummaryRequestData { + pub fn new( + attributes: crate::datadogV2::model::PRCoverageSummaryRequestAttributes, + type_: crate::datadogV2::model::PRCoverageSummaryRequestType, + ) -> PRCoverageSummaryRequestData { + PRCoverageSummaryRequestData { + attributes, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for PRCoverageSummaryRequestData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PRCoverageSummaryRequestDataVisitor; + impl<'a> Visitor<'a> for PRCoverageSummaryRequestDataVisitor { + type Value = PRCoverageSummaryRequestData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::PRCoverageSummaryRequestAttributes, + > = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::PRCoverageSummaryRequestType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = PRCoverageSummaryRequestData { + attributes, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(PRCoverageSummaryRequestDataVisitor) + } +} diff --git a/src/datadogV2/model/model_pr_coverage_summary_request_type.rs b/src/datadogV2/model/model_pr_coverage_summary_request_type.rs new file mode 100644 index 0000000000..4afd3f009c --- /dev/null +++ b/src/datadogV2/model/model_pr_coverage_summary_request_type.rs @@ -0,0 +1,50 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum PRCoverageSummaryRequestType { + CI_APP_COVERAGE_PR_SUMMARY_REQUEST, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for PRCoverageSummaryRequestType { + fn to_string(&self) -> String { + match self { + Self::CI_APP_COVERAGE_PR_SUMMARY_REQUEST => { + String::from("ci_app_coverage_pr_summary_request") + } + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for PRCoverageSummaryRequestType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for PRCoverageSummaryRequestType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "ci_app_coverage_pr_summary_request" => Self::CI_APP_COVERAGE_PR_SUMMARY_REQUEST, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/features/v2/code_coverage.feature b/tests/scenarios/features/v2/code_coverage.feature index a103acd210..217c50edf8 100644 --- a/tests/scenarios/features/v2/code_coverage.feature +++ b/tests/scenarios/features/v2/code_coverage.feature @@ -11,24 +11,21 @@ Feature: Code Coverage @generated @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for a branch returns "Bad Request" response - Given operation "GetCodeCoverageBranchSummary" enabled - And new "GetCodeCoverageBranchSummary" request + Given new "GetCodeCoverageBranchSummary" request And body with value {"data": {"attributes": {"branch": "prod", "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_branch_summary_request"}} When the request is sent Then the response status is 400 Bad Request @generated @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for a branch returns "Not Found" response - Given operation "GetCodeCoverageBranchSummary" enabled - And new "GetCodeCoverageBranchSummary" request + Given new "GetCodeCoverageBranchSummary" request And body with value {"data": {"attributes": {"branch": "prod", "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_branch_summary_request"}} When the request is sent Then the response status is 404 Not Found @generated @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for a branch returns "OK" response - Given operation "GetCodeCoverageBranchSummary" enabled - And new "GetCodeCoverageBranchSummary" request + Given new "GetCodeCoverageBranchSummary" request And body with value {"data": {"attributes": {"branch": "prod", "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_branch_summary_request"}} When the request is sent Then the response status is 200 OK @@ -59,24 +56,21 @@ Feature: Code Coverage @generated @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for a commit returns "Bad Request" response - Given operation "GetCodeCoverageCommitSummary" enabled - And new "GetCodeCoverageCommitSummary" request + Given new "GetCodeCoverageCommitSummary" request And body with value {"data": {"attributes": {"commit_sha": "66adc9350f2cc9b250b69abddab733dd55e1a588", "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_commit_summary_request"}} When the request is sent Then the response status is 400 Bad Request @generated @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for a commit returns "Not Found" response - Given operation "GetCodeCoverageCommitSummary" enabled - And new "GetCodeCoverageCommitSummary" request + Given new "GetCodeCoverageCommitSummary" request And body with value {"data": {"attributes": {"commit_sha": "66adc9350f2cc9b250b69abddab733dd55e1a588", "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_commit_summary_request"}} When the request is sent Then the response status is 404 Not Found @generated @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for a commit returns "OK" response - Given operation "GetCodeCoverageCommitSummary" enabled - And new "GetCodeCoverageCommitSummary" request + Given new "GetCodeCoverageCommitSummary" request And body with value {"data": {"attributes": {"commit_sha": "66adc9350f2cc9b250b69abddab733dd55e1a588", "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_commit_summary_request"}} When the request is sent Then the response status is 200 OK @@ -129,6 +123,27 @@ Feature: Code Coverage When the request is sent Then the response status is 404 Not Found + @generated @skip @team:DataDog/ci-app-backend + Scenario: Get code coverage summary for a pull request returns "Bad Request" response + Given new "GetCodeCoveragePRSummary" request + And body with value {"data": {"attributes": {"pr_number": 42, "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_pr_summary_request"}} + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/ci-app-backend + Scenario: Get code coverage summary for a pull request returns "Not Found" response + Given new "GetCodeCoveragePRSummary" request + And body with value {"data": {"attributes": {"pr_number": 42, "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_pr_summary_request"}} + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/ci-app-backend + Scenario: Get code coverage summary for a pull request returns "OK" response + Given new "GetCodeCoveragePRSummary" request + And body with value {"data": {"attributes": {"pr_number": 42, "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_pr_summary_request"}} + When the request is sent + Then the response status is 200 OK + @skip @team:DataDog/ci-app-backend Scenario: Get code coverage summary for an existing branch with valid repository Given operation "GetCodeCoverageBranchSummary" enabled @@ -154,3 +169,24 @@ Feature: Code Coverage And the response "data.attributes" has field "patch_coverage" And the response "data.attributes" has field "evaluated_reports_count" And the response "data.attributes" has field "evaluated_flags_count" + + @generated @skip @team:DataDog/ci-app-backend + Scenario: Get per-file code coverage data returns "Bad Request" response + Given new "GetCodeCoverageFiles" request + And body with value {"data": {"attributes": {"branch": "main", "changed_only": true, "codeowner": "@my-team", "commit_sha": "66adc9350f2cc9b250b69abddab733dd55e1a588", "flag": "unit-tests", "pr_number": 42, "repository_id": "github.com/datadog/shopist", "repository_url": "https://github.com/datadog/shopist", "service": "my-service"}, "type": "ci_app_coverage_files_request"}} + When the request is sent + Then the response status is 400 Bad Request + + @skip @team:DataDog/ci-app-backend + Scenario: Get per-file code coverage data returns "Not Found" response + Given new "GetCodeCoverageFiles" request + And body with value {"data": {"attributes": {"changed_only": true, "commit_sha": "66adc9350f2cc9b250b69abddab733dd55e1a588", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_files_request"}} + When the request is sent + Then the response status is 404 Not Found + + @skip @team:DataDog/ci-app-backend + Scenario: Get per-file code coverage data returns "OK" response + Given new "GetCodeCoverageFiles" request + And body with value {"data": {"attributes": {"changed_only": true, "commit_sha": "66adc9350f2cc9b250b69abddab733dd55e1a588", "repository_url": "https://github.com/datadog/shopist"}, "type": "ci_app_coverage_files_request"}} + When the request is sent + Then the response status is 200 OK diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index df961ee10c..57c7469dac 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -1548,6 +1548,18 @@ "type": "safe" } }, + "GetCodeCoverageFiles": { + "tag": "Code Coverage", + "undo": { + "type": "safe" + } + }, + "GetCodeCoveragePRSummary": { + "tag": "Code Coverage", + "undo": { + "type": "safe" + } + }, "GetRuleBasedView": { "tag": "Compliance", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index 998ffc7460..278c5657b0 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -4178,6 +4178,14 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.GetCodeCoverageCommitSummary".into(), test_v2_get_code_coverage_commit_summary, ); + world.function_mappings.insert( + "v2.GetCodeCoverageFiles".into(), + test_v2_get_code_coverage_files, + ); + world.function_mappings.insert( + "v2.GetCodeCoveragePRSummary".into(), + test_v2_get_code_coverage_pr_summary, + ); world .function_mappings .insert("v2.GetRuleBasedView".into(), test_v2_get_rule_based_view); @@ -31377,6 +31385,59 @@ fn test_v2_get_code_coverage_commit_summary( world.response.code = response.status.as_u16(); } +fn test_v2_get_code_coverage_files(world: &mut DatadogWorld, _parameters: &HashMap) { + let api = world + .api_instances + .v2_api_code_coverage + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.get_code_coverage_files_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_get_code_coverage_pr_summary( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_code_coverage + .as_ref() + .expect("api instance not found"); + let body = serde_json::from_value(_parameters.get("body").unwrap().clone()).unwrap(); + let response = match block_on(api.get_code_coverage_pr_summary_with_http_info(body)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_get_rule_based_view(world: &mut DatadogWorld, _parameters: &HashMap) { let api = world .api_instances