From abc66206231f0ccd0f74cfb16713c6d01b725f3d Mon Sep 17 00:00:00 2001 From: Alexander Lyon Date: Thu, 6 Nov 2025 10:28:54 +0000 Subject: [PATCH 1/4] fix deprecated Command::cargo_bin New changes to cargo means in recent rust (1.91) means that this does not always find the bin properly. A deprecation notice recommends a compile-time macro instead which does find it. --- cargo-progenitor/tests/test_cmd.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cargo-progenitor/tests/test_cmd.rs b/cargo-progenitor/tests/test_cmd.rs index 101bbae0..655a257f 100644 --- a/cargo-progenitor/tests/test_cmd.rs +++ b/cargo-progenitor/tests/test_cmd.rs @@ -1,11 +1,10 @@ // Copyright 2025 Oxide Computer Company -use assert_cmd::Command; +use assert_cmd::cargo::cargo_bin_cmd; #[test] fn test_help() { - Command::cargo_bin("cargo-progenitor") - .unwrap() + cargo_bin_cmd!("cargo-progenitor") .arg("progenitor") .arg("--help") .assert() From 09aa6f3b8884e8351a72d2cb76615977aa5b671a Mon Sep 17 00:00:00 2001 From: Alexander Lyon Date: Thu, 6 Nov 2025 11:28:09 +0000 Subject: [PATCH 2/4] add missing and generated operation id strategies --- progenitor-impl/src/cli.rs | 14 +- progenitor-impl/src/httpmock.rs | 14 +- progenitor-impl/src/lib.rs | 259 +++++++++++++++++++++++++++++--- progenitor-impl/src/method.rs | 25 ++- progenitor/src/lib.rs | 1 + 5 files changed, 283 insertions(+), 30 deletions(-) diff --git a/progenitor-impl/src/cli.rs b/progenitor-impl/src/cli.rs index ed32ff95..e64880b7 100644 --- a/progenitor-impl/src/cli.rs +++ b/progenitor-impl/src/cli.rs @@ -24,7 +24,7 @@ struct CliOperation { impl Generator { /// Generate a `clap`-based CLI. pub fn cli(&mut self, spec: &OpenAPI, crate_name: &str) -> Result { - validate_openapi(spec)?; + validate_openapi(spec, self.settings.operation_id_strategy)?; // Convert our components dictionary to schemars let schemas = spec.components.iter().flat_map(|components| { @@ -46,8 +46,16 @@ impl Generator { (path.as_str(), method, operation, &item.parameters) }) }) - .map(|(path, method, operation, path_parameters)| { - self.process_operation(operation, &spec.components, path, method, path_parameters) + .filter_map(|(path, method, operation, path_parameters)| { + self.process_operation( + operation, + &spec.components, + path, + method, + path_parameters, + self.settings.operation_id_strategy, + ) + .transpose() }) .collect::>>()?; diff --git a/progenitor-impl/src/httpmock.rs b/progenitor-impl/src/httpmock.rs index 1e7f9745..cdb090ef 100644 --- a/progenitor-impl/src/httpmock.rs +++ b/progenitor-impl/src/httpmock.rs @@ -30,7 +30,7 @@ impl Generator { /// the SDK. This can include `::` and instances of `-` in the crate name /// should be converted to `_`. pub fn httpmock(&mut self, spec: &OpenAPI, crate_path: &str) -> Result { - validate_openapi(spec)?; + validate_openapi(spec, self.settings.operation_id_strategy)?; // Convert our components dictionary to schemars let schemas = spec.components.iter().flat_map(|components| { @@ -52,8 +52,16 @@ impl Generator { (path.as_str(), method, operation, &item.parameters) }) }) - .map(|(path, method, operation, path_parameters)| { - self.process_operation(operation, &spec.components, path, method, path_parameters) + .filter_map(|(path, method, operation, path_parameters)| { + self.process_operation( + operation, + &spec.components, + path, + method, + path_parameters, + self.settings.operation_id_strategy, + ) + .transpose() }) .collect::>>()?; diff --git a/progenitor-impl/src/lib.rs b/progenitor-impl/src/lib.rs index 68454ece..212b9229 100644 --- a/progenitor-impl/src/lib.rs +++ b/progenitor-impl/src/lib.rs @@ -6,6 +6,7 @@ use std::collections::{BTreeMap, HashMap, HashSet}; +use heck::ToSnakeCase; use openapiv3::OpenAPI; use proc_macro2::TokenStream; use quote::quote; @@ -68,6 +69,8 @@ pub struct GenerationSettings { extra_derives: Vec, extra_cli_bounds: Vec, + operation_id_strategy: OperationIdStrategy, + map_type: Option, unknown_crates: UnknownPolicy, crates: BTreeMap, @@ -114,6 +117,26 @@ impl Default for TagStyle { } } +/// Style for handing operations that do not have an operation ID. +#[derive(Copy, Clone)] +pub enum OperationIdStrategy { + /// The default behaviour. Reject when any operation on the resulting + /// client does not have an operation ID. + RejectMissing, + /// Omit any operation on the resulting client that does not have an + /// operation ID. + OmitMissing, + /// Generate plausible names for operations on the resulting client that + /// do not have an operation ID. + GenerateMissing, +} + +impl Default for OperationIdStrategy { + fn default() -> Self { + Self::RejectMissing + } +} + impl GenerationSettings { /// Create new generator settings with default values. pub fn new() -> Self { @@ -255,6 +278,16 @@ impl GenerationSettings { self.timeout = Some(timeout); self } + + /// Set the strategy to be used when encountering operations that do not + /// have an operation ID. + pub fn with_operation_id_strategy( + &mut self, + operation_id_strategy: OperationIdStrategy, + ) -> &mut Self { + self.operation_id_strategy = operation_id_strategy; + self + } } impl Default for Generator { @@ -320,7 +353,7 @@ impl Generator { /// Emit a [TokenStream] containing the generated client code. pub fn generate_tokens(&mut self, spec: &OpenAPI) -> Result { - validate_openapi(spec)?; + validate_openapi(spec, self.settings.operation_id_strategy)?; // Convert our components dictionary to schemars let schemas = spec.components.iter().flat_map(|components| { @@ -342,8 +375,16 @@ impl Generator { (path.as_str(), method, operation, &item.parameters) }) }) - .map(|(path, method, operation, path_parameters)| { - self.process_operation(operation, &spec.components, path, method, path_parameters) + .filter_map(|(path, method, operation, path_parameters)| { + self.process_operation( + operation, + &spec.components, + path, + method, + path_parameters, + self.settings.operation_id_strategy, + ) + .transpose() }) .collect::>>()?; @@ -690,7 +731,7 @@ fn validate_openapi_spec_version(spec_version: &str) -> Result<()> { } /// Do some very basic checks of the OpenAPI documents. -pub fn validate_openapi(spec: &OpenAPI) -> Result<()> { +pub fn validate_openapi(spec: &OpenAPI, operation_id_strategy: OperationIdStrategy) -> Result<()> { validate_openapi_spec_version(spec.openapi.as_str())?; let mut opids = HashSet::new(); @@ -700,21 +741,31 @@ pub fn validate_openapi(spec: &OpenAPI) -> Result<()> { format!("path {} uses reference, unsupported", p.0,), )), openapiv3::ReferenceOr::Item(item) => { - // Make sure every operation has an operation ID, and that each - // operation ID is only used once in the document. - item.iter().try_for_each(|(_, o)| { - if let Some(oid) = o.operation_id.as_ref() { - if !opids.insert(oid.to_string()) { + // Make sure every operation has an operation ID, or that the operation id + // strategy allows ignoring / generating one, and that each operation ID is + // only used once in the document. + item.iter().try_for_each(|(method, o)| { + match resolve_operation_id_with_strategy( + p.0, + method, + o.operation_id.as_deref(), + operation_id_strategy, + ) { + Ok(Some(oid)) => { + if !opids.insert(oid.to_string()) { + return Err(Error::UnexpectedFormat(format!( + "duplicate operation ID: {}", + oid, + ))); + } + } + Ok(None) => {} + Err(Rejected) => { return Err(Error::UnexpectedFormat(format!( - "duplicate operation ID: {}", - oid, + "path {} is missing operation ID", + p.0, ))); } - } else { - return Err(Error::UnexpectedFormat(format!( - "path {} is missing operation ID", - p.0, - ))); } Ok(()) }) @@ -725,11 +776,52 @@ pub fn validate_openapi(spec: &OpenAPI) -> Result<()> { Ok(()) } +/// Rejected operation ID +// Clippy doesn't like () being used as the error type, +// and double option is confusing. +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct Rejected; + +/// Resolve the operation ID for the given operation, using the given +/// operation ID strategy. +/// +/// Ok(None) means none was found but that is OK +/// Ok(Some(String)) means the operation ID was found +/// Err(()) means the operation ID was not found and the +/// chosen strategy rejects the operation +pub fn resolve_operation_id_with_strategy( + path: &str, + method: &str, + id: Option<&str>, + strategy: OperationIdStrategy, +) -> std::result::Result, Rejected> { + if let Some(oid) = id { + return Ok(Some(oid.to_string())); + } + match strategy { + OperationIdStrategy::RejectMissing => Err(Rejected), + OperationIdStrategy::OmitMissing => Ok(None), + OperationIdStrategy::GenerateMissing => { + let path = path.to_snake_case(); + let method = method.to_snake_case(); + let oid = if path.is_empty() { + method + } else { + format!("{}_{}", method, path) + }; + Ok(Some(oid)) + } + } +} + #[cfg(test)] mod tests { use serde_json::json; - use crate::{validate_openapi_spec_version, Error}; + use crate::{ + resolve_operation_id_with_strategy, validate_openapi_spec_version, Error, + OperationIdStrategy, + }; #[test] fn test_bad_value() { @@ -776,4 +868,137 @@ mod tests { "unexpected or unhandled format in the OpenAPI document invalid version: 3.1.0" ); } + + #[test] + fn test_resolve_operation_id_with_existing_id() { + // When operation ID exists, all strategies should return it + let strategies = [ + OperationIdStrategy::RejectMissing, + OperationIdStrategy::OmitMissing, + OperationIdStrategy::GenerateMissing, + ]; + + for strategy in strategies { + let result = resolve_operation_id_with_strategy( + "/api/users", + "GET", + Some("getUserList"), + strategy, + ); + assert_eq!(result, Ok(Some("getUserList".to_string()))); + } + } + + #[test] + fn test_resolve_operation_id_reject_missing_strategy() { + // RejectMissing should return Err when no operation ID + let result = resolve_operation_id_with_strategy( + "/api/users", + "GET", + None, + OperationIdStrategy::RejectMissing, + ); + assert_eq!(result, Err(())); + } + + #[test] + fn test_resolve_operation_id_omit_missing_strategy() { + // OmitMissing should return Ok(None) when no operation ID + let result = resolve_operation_id_with_strategy( + "/api/users", + "GET", + None, + OperationIdStrategy::OmitMissing, + ); + assert_eq!(result, Ok(None)); + } + + #[test] + fn test_resolve_operation_id_generate_missing_strategy() { + // GenerateMissing should generate operation IDs from method and path + let result = resolve_operation_id_with_strategy( + "/api/users", + "GET", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!(result, Ok(Some("get_api_users".to_string()))); + } + + #[test] + fn test_resolve_operation_id_generate_with_path_params() { + // Test with path parameters + let result = resolve_operation_id_with_strategy( + "/api/users/{id}", + "GET", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!(result, Ok(Some("get_api_users_id".to_string()))); + } + + #[test] + fn test_resolve_operation_id_generate_with_camel_case() { + // Test that camelCase paths are converted to snake_case + let result = resolve_operation_id_with_strategy( + "/api/userProfiles", + "POST", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!(result, Ok(Some("post_api_user_profiles".to_string()))); + } + + #[test] + fn test_resolve_operation_id_generate_with_empty_path() { + // Test with empty path (root) + let result = resolve_operation_id_with_strategy( + "", + "GET", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!(result, Ok(Some("get".to_string()))); + } + + #[test] + fn test_resolve_operation_id_generate_with_uppercase_method() { + // Test that uppercase methods are converted to lowercase + let result = resolve_operation_id_with_strategy( + "/api/users", + "DELETE", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!(result, Ok(Some("delete_api_users".to_string()))); + } + + #[test] + fn test_resolve_operation_id_generate_with_complex_path() { + // Test with complex path containing multiple segments + let result = resolve_operation_id_with_strategy( + "/api/v1/organizations/{orgId}/users/{userId}/profile", + "PATCH", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!( + result, + Ok(Some( + "patch_api_v1_organizations_org_id_users_user_id_profile".to_string() + )) + ); + } + + #[test] + fn test_resolve_operation_id_generate_with_hyphens() { + // Test that hyphens in paths are handled correctly + let result = resolve_operation_id_with_strategy( + "/api/user-profiles", + "GET", + None, + OperationIdStrategy::GenerateMissing, + ); + assert_eq!(result, Ok(Some("get_api_user_profiles".to_string()))); + } } diff --git a/progenitor-impl/src/method.rs b/progenitor-impl/src/method.rs index 8bf1d0fe..3cc0c539 100644 --- a/progenitor-impl/src/method.rs +++ b/progenitor-impl/src/method.rs @@ -12,9 +12,10 @@ use quote::{format_ident, quote, ToTokens}; use typify::{TypeId, TypeSpace}; use crate::{ + resolve_operation_id_with_strategy, template::PathTemplate, util::{items, parameter_map, sanitize, unique_ident_from, Case}, - Error, Generator, Result, TagStyle, + Error, Generator, OperationIdStrategy, Result, TagStyle, }; use crate::{to_schema::ToSchema, util::ReferenceOrExt}; @@ -290,8 +291,18 @@ impl Generator { path: &str, method: &str, path_parameters: &[ReferenceOr], - ) -> Result { - let operation_id = operation.operation_id.as_ref().unwrap(); + operation_id_strategy: OperationIdStrategy, + ) -> Result> { + let Some(operation_id) = resolve_operation_id_with_strategy( + path, + method, + operation.operation_id.as_deref(), + operation_id_strategy, + ) + .map_err(|_| Error::UnexpectedFormat(format!("path {} is missing operation ID", path)))? + else { + return Ok(None); + }; let mut combined_path_parameters = parameter_map(path_parameters, components)?; for operation_param in items(&operation.parameters, components) { @@ -534,8 +545,8 @@ impl Generator { ))); } - Ok(OperationMethod { - operation_id: sanitize(operation_id, Case::Snake), + Ok(Some(OperationMethod { + operation_id: sanitize(&operation_id, Case::Snake), tags: operation.tags.clone(), method: HttpMethod::from_str(method)?, path: tmp, @@ -545,7 +556,7 @@ impl Generator { responses, dropshot_paginated, dropshot_websocket, - }) + })) } pub(crate) fn positional_method( @@ -1399,7 +1410,7 @@ impl Generator { /// param_1, /// param_2, /// } = self; - /// + /// /// let param_1 = param_1.map_err(Error::InvalidRequest)?; /// let param_2 = param_1.map_err(Error::InvalidRequest)?; /// diff --git a/progenitor/src/lib.rs b/progenitor/src/lib.rs index 52cd7b3b..b3789680 100644 --- a/progenitor/src/lib.rs +++ b/progenitor/src/lib.rs @@ -19,6 +19,7 @@ pub use progenitor_impl::Error; pub use progenitor_impl::GenerationSettings; pub use progenitor_impl::Generator; pub use progenitor_impl::InterfaceStyle; +pub use progenitor_impl::OperationIdStrategy; pub use progenitor_impl::TagStyle; pub use progenitor_impl::TypeImpl; pub use progenitor_impl::TypePatch; From 090b80b307fb0756d20f528f33c65659c131f8ec Mon Sep 17 00:00:00 2001 From: Alexander Lyon Date: Thu, 6 Nov 2025 11:22:55 +0000 Subject: [PATCH 3/4] add tests --- .../output/src/buildomat_builder_tagged.rs | 85 +- .../output/src/cli_gen_builder_tagged.rs | 4 +- .../src/generated_operation_id_builder.rs | 219 +++++ .../generated_operation_id_builder_tagged.rs | 221 +++++ .../output/src/generated_operation_id_cli.rs | 118 +++ .../src/generated_operation_id_httpmock.rs | 104 +++ .../src/generated_operation_id_positional.rs | 159 ++++ .../tests/output/src/keeper_builder_tagged.rs | 70 +- .../tests/output/src/keeper_cli.rs | 20 - .../src/missing_operation_id_builder.rs | 168 ++++ .../missing_operation_id_builder_tagged.rs | 170 ++++ .../output/src/missing_operation_id_cli.rs | 87 ++ .../src/missing_operation_id_httpmock.rs | 59 ++ .../src/missing_operation_id_positional.rs | 134 +++ .../tests/output/src/nexus_builder_tagged.rs | 767 ++++++++++++++---- .../src/propolis_server_builder_tagged.rs | 87 +- progenitor-impl/tests/test_output.rs | 33 +- sample_openapi/generated-operation-id.json | 31 + sample_openapi/missing-operation-id.json | 31 + 19 files changed, 2309 insertions(+), 258 deletions(-) create mode 100644 progenitor-impl/tests/output/src/generated_operation_id_builder.rs create mode 100644 progenitor-impl/tests/output/src/generated_operation_id_builder_tagged.rs create mode 100644 progenitor-impl/tests/output/src/generated_operation_id_cli.rs create mode 100644 progenitor-impl/tests/output/src/generated_operation_id_httpmock.rs create mode 100644 progenitor-impl/tests/output/src/generated_operation_id_positional.rs create mode 100644 progenitor-impl/tests/output/src/missing_operation_id_builder.rs create mode 100644 progenitor-impl/tests/output/src/missing_operation_id_builder_tagged.rs create mode 100644 progenitor-impl/tests/output/src/missing_operation_id_cli.rs create mode 100644 progenitor-impl/tests/output/src/missing_operation_id_httpmock.rs create mode 100644 progenitor-impl/tests/output/src/missing_operation_id_positional.rs create mode 100644 sample_openapi/generated-operation-id.json create mode 100644 sample_openapi/missing-operation-id.json diff --git a/progenitor-impl/tests/output/src/buildomat_builder_tagged.rs b/progenitor-impl/tests/output/src/buildomat_builder_tagged.rs index e2dc6a80..e4952e82 100644 --- a/progenitor-impl/tests/output/src/buildomat_builder_tagged.rs +++ b/progenitor-impl/tests/output/src/buildomat_builder_tagged.rs @@ -55,7 +55,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(untagged)] pub enum GetThingOrThingsId { String(::std::string::String), @@ -100,6 +102,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum HeaderArgAcceptLanguage { #[serde(rename = "de")] @@ -218,7 +221,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ObjWithOptionArray { #[serde(rename = "stranger-things")] pub stranger_things: ::std::vec::Vec<::std::option::Option>, @@ -274,7 +279,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Task { pub id: ::std::string::String, pub name: ::std::string::String, @@ -328,7 +335,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct TaskEvent { pub payload: ::std::string::String, pub seq: u32, @@ -376,7 +385,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct TaskOutput { pub id: ::std::string::String, pub path: ::std::string::String, @@ -427,7 +438,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct TaskSubmit { pub default: bool, pub name: ::std::string::String, @@ -466,7 +479,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct TaskSubmitResult { pub id: ::std::string::String, } @@ -501,7 +516,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UploadedChunk { pub id: ::std::string::String, } @@ -536,7 +553,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UserCreate { pub name: ::std::string::String, } @@ -579,7 +598,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UserCreateResult { pub id: ::std::string::String, pub name: ::std::string::String, @@ -620,7 +641,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WhoamiResult { pub id: ::std::string::String, pub name: ::std::string::String, @@ -678,7 +701,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Worker { pub deleted: bool, pub id: ::std::string::String, @@ -732,7 +757,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerAddOutput { pub chunks: ::std::vec::Vec<::std::string::String>, pub path: ::std::string::String, @@ -778,7 +805,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerAppendTask { pub payload: ::std::string::String, pub stream: ::std::string::String, @@ -819,7 +848,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerBootstrap { pub bootstrap: ::std::string::String, pub token: ::std::string::String, @@ -855,7 +886,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerBootstrapResult { pub id: ::std::string::String, } @@ -890,7 +923,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerCompleteTask { pub failed: bool, } @@ -928,7 +963,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerPingResult { pub poweroff: bool, #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] @@ -976,7 +1013,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerPingTask { pub id: ::std::string::String, pub output_rules: ::std::vec::Vec<::std::string::String>, @@ -1021,7 +1060,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkerTask { pub id: ::std::string::String, pub name: ::std::string::String, @@ -1061,7 +1102,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct WorkersResult { pub workers: ::std::vec::Vec, } diff --git a/progenitor-impl/tests/output/src/cli_gen_builder_tagged.rs b/progenitor-impl/tests/output/src/cli_gen_builder_tagged.rs index 7dc52582..1d93d4fd 100644 --- a/progenitor-impl/tests/output/src/cli_gen_builder_tagged.rs +++ b/progenitor-impl/tests/output/src/cli_gen_builder_tagged.rs @@ -53,7 +53,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UnoBody { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub gateway: ::std::option::Option<::std::string::String>, diff --git a/progenitor-impl/tests/output/src/generated_operation_id_builder.rs b/progenitor-impl/tests/output/src/generated_operation_id_builder.rs new file mode 100644 index 00000000..71aca8f8 --- /dev/null +++ b/progenitor-impl/tests/output/src/generated_operation_id_builder.rs @@ -0,0 +1,219 @@ +#[allow(unused_imports)] +use progenitor_client::{encode_path, ClientHooks, OperationInfo, RequestBuilderExt}; +#[allow(unused_imports)] +pub use progenitor_client::{ByteStream, ClientInfo, Error, ResponseValue}; +/// Types used as operation parameters and responses. +#[allow(clippy::all)] +pub mod types { + /// Error types. + pub mod error { + /// Error from a `TryFrom` or `FromStr` implementation. + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } + } +} + +#[derive(Clone, Debug)] +///Client for Missing operation ids test +/// +///Minimal API for testing missing operation id strategies +/// +///Version: v1 +pub struct Client { + pub(crate) baseurl: String, + pub(crate) client: reqwest::Client, +} + +impl Client { + /// Create a new client. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new(baseurl: &str) -> Self { + #[cfg(not(target_arch = "wasm32"))] + let client = { + let dur = ::std::time::Duration::from_secs(15u64); + reqwest::ClientBuilder::new() + .connect_timeout(dur) + .timeout(dur) + }; + #[cfg(target_arch = "wasm32")] + let client = reqwest::ClientBuilder::new(); + Self::new_with_client(baseurl, client.build().unwrap()) + } + + /// Construct a new client with an existing `reqwest::Client`, + /// allowing more control over its configuration. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { + Self { + baseurl: baseurl.to_string(), + client, + } + } +} + +impl ClientInfo<()> for Client { + fn api_version() -> &'static str { + "v1" + } + + fn baseurl(&self) -> &str { + self.baseurl.as_str() + } + + fn client(&self) -> &reqwest::Client { + &self.client + } + + fn inner(&self) -> &() { + &() + } +} + +impl ClientHooks<()> for &Client {} +impl Client { + ///Ping + /// + ///Sends a `GET` request to `/` + /// + ///```ignore + /// let response = client.get() + /// .send() + /// .await; + /// ``` + pub fn get(&self) -> builder::Get<'_> { + builder::Get::new(self) + } + + ///Ping + /// + ///Sends a `POST` request to `/` + /// + ///```ignore + /// let response = client.do_ping() + /// .send() + /// .await; + /// ``` + pub fn do_ping(&self) -> builder::DoPing<'_> { + builder::DoPing::new(self) + } +} + +/// Types for composing operation parameters. +#[allow(clippy::all)] +pub mod builder { + use super::types; + #[allow(unused_imports)] + use super::{ + encode_path, ByteStream, ClientHooks, ClientInfo, Error, OperationInfo, RequestBuilderExt, + ResponseValue, + }; + ///Builder for [`Client::get`] + /// + ///[`Client::get`]: super::Client::get + #[derive(Debug, Clone)] + pub struct Get<'a> { + client: &'a super::Client, + } + + impl<'a> Get<'a> { + pub fn new(client: &'a super::Client) -> Self { + Self { client: client } + } + + ///Sends a `GET` request to `/` + pub async fn send(self) -> Result, Error<()>> { + let Self { client } = self; + let url = format!("{}/", client.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(super::Client::api_version()), + ); + #[allow(unused_mut)] + let mut request = client.client.get(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "get", + }; + client.pre(&mut request, &info).await?; + let result = client.exec(request, &info).await; + client.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + } + + ///Builder for [`Client::do_ping`] + /// + ///[`Client::do_ping`]: super::Client::do_ping + #[derive(Debug, Clone)] + pub struct DoPing<'a> { + client: &'a super::Client, + } + + impl<'a> DoPing<'a> { + pub fn new(client: &'a super::Client) -> Self { + Self { client: client } + } + + ///Sends a `POST` request to `/` + pub async fn send(self) -> Result, Error<()>> { + let Self { client } = self; + let url = format!("{}/", client.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(super::Client::api_version()), + ); + #[allow(unused_mut)] + let mut request = client.client.post(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "do_ping", + }; + client.pre(&mut request, &info).await?; + let result = client.exec(request, &info).await; + client.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + } +} + +/// Items consumers will typically use such as the Client. +pub mod prelude { + pub use self::super::Client; +} diff --git a/progenitor-impl/tests/output/src/generated_operation_id_builder_tagged.rs b/progenitor-impl/tests/output/src/generated_operation_id_builder_tagged.rs new file mode 100644 index 00000000..a2a91bc6 --- /dev/null +++ b/progenitor-impl/tests/output/src/generated_operation_id_builder_tagged.rs @@ -0,0 +1,221 @@ +#[allow(unused_imports)] +use progenitor_client::{encode_path, ClientHooks, OperationInfo, RequestBuilderExt}; +#[allow(unused_imports)] +pub use progenitor_client::{ByteStream, ClientInfo, Error, ResponseValue}; +/// Types used as operation parameters and responses. +#[allow(clippy::all)] +pub mod types { + /// Error types. + pub mod error { + /// Error from a `TryFrom` or `FromStr` implementation. + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } + } +} + +#[derive(Clone, Debug)] +///Client for Missing operation ids test +/// +///Minimal API for testing missing operation id strategies +/// +///Version: v1 +pub struct Client { + pub(crate) baseurl: String, + pub(crate) client: reqwest::Client, +} + +impl Client { + /// Create a new client. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new(baseurl: &str) -> Self { + #[cfg(not(target_arch = "wasm32"))] + let client = { + let dur = ::std::time::Duration::from_secs(15u64); + reqwest::ClientBuilder::new() + .connect_timeout(dur) + .timeout(dur) + }; + #[cfg(target_arch = "wasm32")] + let client = reqwest::ClientBuilder::new(); + Self::new_with_client(baseurl, client.build().unwrap()) + } + + /// Construct a new client with an existing `reqwest::Client`, + /// allowing more control over its configuration. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { + Self { + baseurl: baseurl.to_string(), + client, + } + } +} + +impl ClientInfo<()> for Client { + fn api_version() -> &'static str { + "v1" + } + + fn baseurl(&self) -> &str { + self.baseurl.as_str() + } + + fn client(&self) -> &reqwest::Client { + &self.client + } + + fn inner(&self) -> &() { + &() + } +} + +impl ClientHooks<()> for &Client {} +impl Client { + ///Ping + /// + ///Sends a `GET` request to `/` + /// + ///```ignore + /// let response = client.get() + /// .send() + /// .await; + /// ``` + pub fn get(&self) -> builder::Get<'_> { + builder::Get::new(self) + } + + ///Ping + /// + ///Sends a `POST` request to `/` + /// + ///```ignore + /// let response = client.do_ping() + /// .send() + /// .await; + /// ``` + pub fn do_ping(&self) -> builder::DoPing<'_> { + builder::DoPing::new(self) + } +} + +/// Types for composing operation parameters. +#[allow(clippy::all)] +pub mod builder { + use super::types; + #[allow(unused_imports)] + use super::{ + encode_path, ByteStream, ClientHooks, ClientInfo, Error, OperationInfo, RequestBuilderExt, + ResponseValue, + }; + ///Builder for [`Client::get`] + /// + ///[`Client::get`]: super::Client::get + #[derive(Debug, Clone)] + pub struct Get<'a> { + client: &'a super::Client, + } + + impl<'a> Get<'a> { + pub fn new(client: &'a super::Client) -> Self { + Self { client: client } + } + + ///Sends a `GET` request to `/` + pub async fn send(self) -> Result, Error<()>> { + let Self { client } = self; + let url = format!("{}/", client.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(super::Client::api_version()), + ); + #[allow(unused_mut)] + let mut request = client.client.get(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "get", + }; + client.pre(&mut request, &info).await?; + let result = client.exec(request, &info).await; + client.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + } + + ///Builder for [`Client::do_ping`] + /// + ///[`Client::do_ping`]: super::Client::do_ping + #[derive(Debug, Clone)] + pub struct DoPing<'a> { + client: &'a super::Client, + } + + impl<'a> DoPing<'a> { + pub fn new(client: &'a super::Client) -> Self { + Self { client: client } + } + + ///Sends a `POST` request to `/` + pub async fn send(self) -> Result, Error<()>> { + let Self { client } = self; + let url = format!("{}/", client.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(super::Client::api_version()), + ); + #[allow(unused_mut)] + let mut request = client.client.post(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "do_ping", + }; + client.pre(&mut request, &info).await?; + let result = client.exec(request, &info).await; + client.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + } +} + +/// Items consumers will typically use such as the Client and +/// extension traits. +pub mod prelude { + #[allow(unused_imports)] + pub use super::Client; +} diff --git a/progenitor-impl/tests/output/src/generated_operation_id_cli.rs b/progenitor-impl/tests/output/src/generated_operation_id_cli.rs new file mode 100644 index 00000000..4ac9546b --- /dev/null +++ b/progenitor-impl/tests/output/src/generated_operation_id_cli.rs @@ -0,0 +1,118 @@ +use crate::generated_operation_id_builder::*; +pub struct Cli { + client: Client, + config: T, +} + +impl Cli { + pub fn new(client: Client, config: T) -> Self { + Self { client, config } + } + + pub fn get_command(cmd: CliCommand) -> ::clap::Command { + match cmd { + CliCommand::Get => Self::cli_get(), + CliCommand::DoPing => Self::cli_do_ping(), + } + } + + pub fn cli_get() -> ::clap::Command { + ::clap::Command::new("").long_about("Ping") + } + + pub fn cli_do_ping() -> ::clap::Command { + ::clap::Command::new("").long_about("Ping") + } + + pub async fn execute( + &self, + cmd: CliCommand, + matches: &::clap::ArgMatches, + ) -> anyhow::Result<()> { + match cmd { + CliCommand::Get => self.execute_get(matches).await, + CliCommand::DoPing => self.execute_do_ping(matches).await, + } + } + + pub async fn execute_get(&self, matches: &::clap::ArgMatches) -> anyhow::Result<()> { + let mut request = self.client.get(); + self.config.execute_get(matches, &mut request)?; + let result = request.send().await; + match result { + Ok(r) => { + self.config.success_no_item(&r); + Ok(()) + } + Err(r) => { + self.config.error(&r); + Err(anyhow::Error::new(r)) + } + } + } + + pub async fn execute_do_ping(&self, matches: &::clap::ArgMatches) -> anyhow::Result<()> { + let mut request = self.client.do_ping(); + self.config.execute_do_ping(matches, &mut request)?; + let result = request.send().await; + match result { + Ok(r) => { + self.config.success_no_item(&r); + Ok(()) + } + Err(r) => { + self.config.error(&r); + Err(anyhow::Error::new(r)) + } + } + } +} + +pub trait CliConfig { + fn success_item(&self, value: &ResponseValue) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn success_no_item(&self, value: &ResponseValue<()>); + fn error(&self, value: &Error) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_start(&self) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_item(&self, value: &T) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_end_success(&self) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_end_error(&self, value: &Error) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn execute_get( + &self, + matches: &::clap::ArgMatches, + request: &mut builder::Get, + ) -> anyhow::Result<()> { + Ok(()) + } + + fn execute_do_ping( + &self, + matches: &::clap::ArgMatches, + request: &mut builder::DoPing, + ) -> anyhow::Result<()> { + Ok(()) + } +} + +#[derive(Copy, Clone, Debug)] +pub enum CliCommand { + Get, + DoPing, +} + +impl CliCommand { + pub fn iter() -> impl Iterator { + vec![CliCommand::Get, CliCommand::DoPing].into_iter() + } +} diff --git a/progenitor-impl/tests/output/src/generated_operation_id_httpmock.rs b/progenitor-impl/tests/output/src/generated_operation_id_httpmock.rs new file mode 100644 index 00000000..c1ea29d2 --- /dev/null +++ b/progenitor-impl/tests/output/src/generated_operation_id_httpmock.rs @@ -0,0 +1,104 @@ +pub mod operations { + #![doc = r" [`When`](::httpmock::When) and [`Then`](::httpmock::Then)"] + #![doc = r" wrappers for each operation. Each can be converted to"] + #![doc = r" its inner type with a call to `into_inner()`. This can"] + #![doc = r" be used to explicitly deviate from permitted values."] + use crate::generated_operation_id_builder::*; + pub struct GetWhen(::httpmock::When); + impl GetWhen { + pub fn new(inner: ::httpmock::When) -> Self { + Self( + inner + .method(::httpmock::Method::GET) + .path_matches(regex::Regex::new("^/$").unwrap()), + ) + } + + pub fn into_inner(self) -> ::httpmock::When { + self.0 + } + } + + pub struct GetThen(::httpmock::Then); + impl GetThen { + pub fn new(inner: ::httpmock::Then) -> Self { + Self(inner) + } + + pub fn into_inner(self) -> ::httpmock::Then { + self.0 + } + + pub fn ok(self) -> Self { + Self(self.0.status(200u16)) + } + } + + pub struct DoPingWhen(::httpmock::When); + impl DoPingWhen { + pub fn new(inner: ::httpmock::When) -> Self { + Self( + inner + .method(::httpmock::Method::POST) + .path_matches(regex::Regex::new("^/$").unwrap()), + ) + } + + pub fn into_inner(self) -> ::httpmock::When { + self.0 + } + } + + pub struct DoPingThen(::httpmock::Then); + impl DoPingThen { + pub fn new(inner: ::httpmock::Then) -> Self { + Self(inner) + } + + pub fn into_inner(self) -> ::httpmock::Then { + self.0 + } + + pub fn ok(self) -> Self { + Self(self.0.status(200u16)) + } + } +} + +#[doc = r" An extension trait for [`MockServer`](::httpmock::MockServer) that"] +#[doc = r" adds a method for each operation. These are the equivalent of"] +#[doc = r" type-checked [`mock()`](::httpmock::MockServer::mock) calls."] +pub trait MockServerExt { + fn get(&self, config_fn: F) -> ::httpmock::Mock<'_> + where + F: FnOnce(operations::GetWhen, operations::GetThen); + fn do_ping(&self, config_fn: F) -> ::httpmock::Mock<'_> + where + F: FnOnce(operations::DoPingWhen, operations::DoPingThen); +} + +impl MockServerExt for ::httpmock::MockServer { + fn get(&self, config_fn: F) -> ::httpmock::Mock<'_> + where + F: FnOnce(operations::GetWhen, operations::GetThen), + { + self.mock(|when, then| { + config_fn( + operations::GetWhen::new(when), + operations::GetThen::new(then), + ) + }) + } + + fn do_ping(&self, config_fn: F) -> ::httpmock::Mock<'_> + where + F: FnOnce(operations::DoPingWhen, operations::DoPingThen), + { + self.mock(|when, then| { + config_fn( + operations::DoPingWhen::new(when), + operations::DoPingThen::new(then), + ) + }) + } +} diff --git a/progenitor-impl/tests/output/src/generated_operation_id_positional.rs b/progenitor-impl/tests/output/src/generated_operation_id_positional.rs new file mode 100644 index 00000000..ce413a39 --- /dev/null +++ b/progenitor-impl/tests/output/src/generated_operation_id_positional.rs @@ -0,0 +1,159 @@ +#[allow(unused_imports)] +use progenitor_client::{encode_path, ClientHooks, OperationInfo, RequestBuilderExt}; +#[allow(unused_imports)] +pub use progenitor_client::{ByteStream, ClientInfo, Error, ResponseValue}; +/// Types used as operation parameters and responses. +#[allow(clippy::all)] +pub mod types { + /// Error types. + pub mod error { + /// Error from a `TryFrom` or `FromStr` implementation. + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } + } +} + +#[derive(Clone, Debug)] +///Client for Missing operation ids test +/// +///Minimal API for testing missing operation id strategies +/// +///Version: v1 +pub struct Client { + pub(crate) baseurl: String, + pub(crate) client: reqwest::Client, +} + +impl Client { + /// Create a new client. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new(baseurl: &str) -> Self { + #[cfg(not(target_arch = "wasm32"))] + let client = { + let dur = ::std::time::Duration::from_secs(15u64); + reqwest::ClientBuilder::new() + .connect_timeout(dur) + .timeout(dur) + }; + #[cfg(target_arch = "wasm32")] + let client = reqwest::ClientBuilder::new(); + Self::new_with_client(baseurl, client.build().unwrap()) + } + + /// Construct a new client with an existing `reqwest::Client`, + /// allowing more control over its configuration. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { + Self { + baseurl: baseurl.to_string(), + client, + } + } +} + +impl ClientInfo<()> for Client { + fn api_version() -> &'static str { + "v1" + } + + fn baseurl(&self) -> &str { + self.baseurl.as_str() + } + + fn client(&self) -> &reqwest::Client { + &self.client + } + + fn inner(&self) -> &() { + &() + } +} + +impl ClientHooks<()> for &Client {} +#[allow(clippy::all)] +impl Client { + ///Ping + /// + ///Sends a `GET` request to `/` + pub async fn get<'a>(&'a self) -> Result, Error<()>> { + let url = format!("{}/", self.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(Self::api_version()), + ); + #[allow(unused_mut)] + let mut request = self.client.get(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "get", + }; + self.pre(&mut request, &info).await?; + let result = self.exec(request, &info).await; + self.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + + ///Ping + /// + ///Sends a `POST` request to `/` + pub async fn do_ping<'a>(&'a self) -> Result, Error<()>> { + let url = format!("{}/", self.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(Self::api_version()), + ); + #[allow(unused_mut)] + let mut request = self.client.post(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "do_ping", + }; + self.pre(&mut request, &info).await?; + let result = self.exec(request, &info).await; + self.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } +} + +/// Items consumers will typically use such as the Client. +pub mod prelude { + #[allow(unused_imports)] + pub use super::Client; +} diff --git a/progenitor-impl/tests/output/src/keeper_builder_tagged.rs b/progenitor-impl/tests/output/src/keeper_builder_tagged.rs index bcf15357..3b114e3e 100644 --- a/progenitor-impl/tests/output/src/keeper_builder_tagged.rs +++ b/progenitor-impl/tests/output/src/keeper_builder_tagged.rs @@ -58,7 +58,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct EnrolBody { pub host: ::std::string::String, pub key: ::std::string::String, @@ -98,7 +100,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct GlobalJobsResult { pub summary: ::std::vec::Vec, } @@ -142,7 +146,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct OutputRecord { pub msg: ::std::string::String, pub stream: ::std::string::String, @@ -184,7 +190,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct PingResult { pub host: ::std::string::String, pub ok: bool, @@ -236,11 +244,13 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ReportFinishBody { - pub duration_millis: i32, + pub duration_millis: usize, pub end_time: ::chrono::DateTime<::chrono::offset::Utc>, - pub exit_status: i32, + pub exit_status: usize, pub id: ReportId, } @@ -293,7 +303,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ReportId { pub host: ::std::string::String, pub job: ::std::string::String, @@ -337,7 +349,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ReportOutputBody { pub id: ReportId, pub record: OutputRecord, @@ -374,7 +388,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ReportResult { pub existed_already: bool, } @@ -419,7 +435,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ReportStartBody { pub id: ReportId, pub script: ::std::string::String, @@ -480,13 +498,15 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ReportSummary { - pub age_seconds: i32, - pub duration_seconds: i32, + pub age_seconds: usize, + pub duration_seconds: usize, pub host: ::std::string::String, pub job: ::std::string::String, - pub status: i32, + pub status: usize, pub when: ::chrono::DateTime<::chrono::offset::Utc>, } @@ -746,12 +766,12 @@ pub mod types { #[derive(Clone, Debug)] pub struct ReportFinishBody { - duration_millis: ::std::result::Result, + duration_millis: ::std::result::Result, end_time: ::std::result::Result< ::chrono::DateTime<::chrono::offset::Utc>, ::std::string::String, >, - exit_status: ::std::result::Result, + exit_status: ::std::result::Result, id: ::std::result::Result, } @@ -769,7 +789,7 @@ pub mod types { impl ReportFinishBody { pub fn duration_millis(mut self, value: T) -> Self where - T: ::std::convert::TryInto, + T: ::std::convert::TryInto, T::Error: ::std::fmt::Display, { self.duration_millis = value.try_into().map_err(|e| { @@ -789,7 +809,7 @@ pub mod types { } pub fn exit_status(mut self, value: T) -> Self where - T: ::std::convert::TryInto, + T: ::std::convert::TryInto, T::Error: ::std::fmt::Display, { self.exit_status = value @@ -1120,11 +1140,11 @@ pub mod types { #[derive(Clone, Debug)] pub struct ReportSummary { - age_seconds: ::std::result::Result, - duration_seconds: ::std::result::Result, + age_seconds: ::std::result::Result, + duration_seconds: ::std::result::Result, host: ::std::result::Result<::std::string::String, ::std::string::String>, job: ::std::result::Result<::std::string::String, ::std::string::String>, - status: ::std::result::Result, + status: ::std::result::Result, when: ::std::result::Result< ::chrono::DateTime<::chrono::offset::Utc>, ::std::string::String, @@ -1147,7 +1167,7 @@ pub mod types { impl ReportSummary { pub fn age_seconds(mut self, value: T) -> Self where - T: ::std::convert::TryInto, + T: ::std::convert::TryInto, T::Error: ::std::fmt::Display, { self.age_seconds = value @@ -1157,7 +1177,7 @@ pub mod types { } pub fn duration_seconds(mut self, value: T) -> Self where - T: ::std::convert::TryInto, + T: ::std::convert::TryInto, T::Error: ::std::fmt::Display, { self.duration_seconds = value.try_into().map_err(|e| { @@ -1190,7 +1210,7 @@ pub mod types { } pub fn status(mut self, value: T) -> Self where - T: ::std::convert::TryInto, + T: ::std::convert::TryInto, T::Error: ::std::fmt::Display, { self.status = value diff --git a/progenitor-impl/tests/output/src/keeper_cli.rs b/progenitor-impl/tests/output/src/keeper_cli.rs index ba309f20..76793e6a 100644 --- a/progenitor-impl/tests/output/src/keeper_cli.rs +++ b/progenitor-impl/tests/output/src/keeper_cli.rs @@ -86,12 +86,6 @@ impl Cli { .required(true) .help("Authorization header (bearer token)"), ) - .arg( - ::clap::Arg::new("duration-millis") - .long("duration-millis") - .value_parser(::clap::value_parser!(i32)) - .required_unless_present("json-body"), - ) .arg( ::clap::Arg::new("end-time") .long("end-time") @@ -100,12 +94,6 @@ impl Cli { )) .required_unless_present("json-body"), ) - .arg( - ::clap::Arg::new("exit-status") - .long("exit-status") - .value_parser(::clap::value_parser!(i32)) - .required_unless_present("json-body"), - ) .arg( ::clap::Arg::new("json-body") .long("json-body") @@ -281,20 +269,12 @@ impl Cli { request = request.authorization(value.clone()); } - if let Some(value) = matches.get_one::("duration-millis") { - request = request.body_map(|body| body.duration_millis(value.clone())) - } - if let Some(value) = matches.get_one::<::chrono::DateTime<::chrono::offset::Utc>>("end-time") { request = request.body_map(|body| body.end_time(value.clone())) } - if let Some(value) = matches.get_one::("exit-status") { - request = request.body_map(|body| body.exit_status(value.clone())) - } - if let Some(value) = matches.get_one::("json-body") { let body_txt = std::fs::read_to_string(value).unwrap(); let body_value = serde_json::from_str::(&body_txt).unwrap(); diff --git a/progenitor-impl/tests/output/src/missing_operation_id_builder.rs b/progenitor-impl/tests/output/src/missing_operation_id_builder.rs new file mode 100644 index 00000000..64e63e97 --- /dev/null +++ b/progenitor-impl/tests/output/src/missing_operation_id_builder.rs @@ -0,0 +1,168 @@ +#[allow(unused_imports)] +use progenitor_client::{encode_path, ClientHooks, OperationInfo, RequestBuilderExt}; +#[allow(unused_imports)] +pub use progenitor_client::{ByteStream, ClientInfo, Error, ResponseValue}; +/// Types used as operation parameters and responses. +#[allow(clippy::all)] +pub mod types { + /// Error types. + pub mod error { + /// Error from a `TryFrom` or `FromStr` implementation. + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } + } +} + +#[derive(Clone, Debug)] +///Client for Missing operation ids test +/// +///Minimal API for testing missing operation id strategies +/// +///Version: v1 +pub struct Client { + pub(crate) baseurl: String, + pub(crate) client: reqwest::Client, +} + +impl Client { + /// Create a new client. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new(baseurl: &str) -> Self { + #[cfg(not(target_arch = "wasm32"))] + let client = { + let dur = ::std::time::Duration::from_secs(15u64); + reqwest::ClientBuilder::new() + .connect_timeout(dur) + .timeout(dur) + }; + #[cfg(target_arch = "wasm32")] + let client = reqwest::ClientBuilder::new(); + Self::new_with_client(baseurl, client.build().unwrap()) + } + + /// Construct a new client with an existing `reqwest::Client`, + /// allowing more control over its configuration. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { + Self { + baseurl: baseurl.to_string(), + client, + } + } +} + +impl ClientInfo<()> for Client { + fn api_version() -> &'static str { + "v1" + } + + fn baseurl(&self) -> &str { + self.baseurl.as_str() + } + + fn client(&self) -> &reqwest::Client { + &self.client + } + + fn inner(&self) -> &() { + &() + } +} + +impl ClientHooks<()> for &Client {} +impl Client { + ///Ping + /// + ///Sends a `POST` request to `/` + /// + ///```ignore + /// let response = client.do_ping() + /// .send() + /// .await; + /// ``` + pub fn do_ping(&self) -> builder::DoPing<'_> { + builder::DoPing::new(self) + } +} + +/// Types for composing operation parameters. +#[allow(clippy::all)] +pub mod builder { + use super::types; + #[allow(unused_imports)] + use super::{ + encode_path, ByteStream, ClientHooks, ClientInfo, Error, OperationInfo, RequestBuilderExt, + ResponseValue, + }; + ///Builder for [`Client::do_ping`] + /// + ///[`Client::do_ping`]: super::Client::do_ping + #[derive(Debug, Clone)] + pub struct DoPing<'a> { + client: &'a super::Client, + } + + impl<'a> DoPing<'a> { + pub fn new(client: &'a super::Client) -> Self { + Self { client: client } + } + + ///Sends a `POST` request to `/` + pub async fn send(self) -> Result, Error<()>> { + let Self { client } = self; + let url = format!("{}/", client.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(super::Client::api_version()), + ); + #[allow(unused_mut)] + let mut request = client.client.post(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "do_ping", + }; + client.pre(&mut request, &info).await?; + let result = client.exec(request, &info).await; + client.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + } +} + +/// Items consumers will typically use such as the Client. +pub mod prelude { + pub use self::super::Client; +} diff --git a/progenitor-impl/tests/output/src/missing_operation_id_builder_tagged.rs b/progenitor-impl/tests/output/src/missing_operation_id_builder_tagged.rs new file mode 100644 index 00000000..e58f3710 --- /dev/null +++ b/progenitor-impl/tests/output/src/missing_operation_id_builder_tagged.rs @@ -0,0 +1,170 @@ +#[allow(unused_imports)] +use progenitor_client::{encode_path, ClientHooks, OperationInfo, RequestBuilderExt}; +#[allow(unused_imports)] +pub use progenitor_client::{ByteStream, ClientInfo, Error, ResponseValue}; +/// Types used as operation parameters and responses. +#[allow(clippy::all)] +pub mod types { + /// Error types. + pub mod error { + /// Error from a `TryFrom` or `FromStr` implementation. + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } + } +} + +#[derive(Clone, Debug)] +///Client for Missing operation ids test +/// +///Minimal API for testing missing operation id strategies +/// +///Version: v1 +pub struct Client { + pub(crate) baseurl: String, + pub(crate) client: reqwest::Client, +} + +impl Client { + /// Create a new client. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new(baseurl: &str) -> Self { + #[cfg(not(target_arch = "wasm32"))] + let client = { + let dur = ::std::time::Duration::from_secs(15u64); + reqwest::ClientBuilder::new() + .connect_timeout(dur) + .timeout(dur) + }; + #[cfg(target_arch = "wasm32")] + let client = reqwest::ClientBuilder::new(); + Self::new_with_client(baseurl, client.build().unwrap()) + } + + /// Construct a new client with an existing `reqwest::Client`, + /// allowing more control over its configuration. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { + Self { + baseurl: baseurl.to_string(), + client, + } + } +} + +impl ClientInfo<()> for Client { + fn api_version() -> &'static str { + "v1" + } + + fn baseurl(&self) -> &str { + self.baseurl.as_str() + } + + fn client(&self) -> &reqwest::Client { + &self.client + } + + fn inner(&self) -> &() { + &() + } +} + +impl ClientHooks<()> for &Client {} +impl Client { + ///Ping + /// + ///Sends a `POST` request to `/` + /// + ///```ignore + /// let response = client.do_ping() + /// .send() + /// .await; + /// ``` + pub fn do_ping(&self) -> builder::DoPing<'_> { + builder::DoPing::new(self) + } +} + +/// Types for composing operation parameters. +#[allow(clippy::all)] +pub mod builder { + use super::types; + #[allow(unused_imports)] + use super::{ + encode_path, ByteStream, ClientHooks, ClientInfo, Error, OperationInfo, RequestBuilderExt, + ResponseValue, + }; + ///Builder for [`Client::do_ping`] + /// + ///[`Client::do_ping`]: super::Client::do_ping + #[derive(Debug, Clone)] + pub struct DoPing<'a> { + client: &'a super::Client, + } + + impl<'a> DoPing<'a> { + pub fn new(client: &'a super::Client) -> Self { + Self { client: client } + } + + ///Sends a `POST` request to `/` + pub async fn send(self) -> Result, Error<()>> { + let Self { client } = self; + let url = format!("{}/", client.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(super::Client::api_version()), + ); + #[allow(unused_mut)] + let mut request = client.client.post(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "do_ping", + }; + client.pre(&mut request, &info).await?; + let result = client.exec(request, &info).await; + client.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } + } +} + +/// Items consumers will typically use such as the Client and +/// extension traits. +pub mod prelude { + #[allow(unused_imports)] + pub use super::Client; +} diff --git a/progenitor-impl/tests/output/src/missing_operation_id_cli.rs b/progenitor-impl/tests/output/src/missing_operation_id_cli.rs new file mode 100644 index 00000000..e0cb95ae --- /dev/null +++ b/progenitor-impl/tests/output/src/missing_operation_id_cli.rs @@ -0,0 +1,87 @@ +use crate::missing_operation_id_builder::*; +pub struct Cli { + client: Client, + config: T, +} + +impl Cli { + pub fn new(client: Client, config: T) -> Self { + Self { client, config } + } + + pub fn get_command(cmd: CliCommand) -> ::clap::Command { + match cmd { + CliCommand::DoPing => Self::cli_do_ping(), + } + } + + pub fn cli_do_ping() -> ::clap::Command { + ::clap::Command::new("").long_about("Ping") + } + + pub async fn execute( + &self, + cmd: CliCommand, + matches: &::clap::ArgMatches, + ) -> anyhow::Result<()> { + match cmd { + CliCommand::DoPing => self.execute_do_ping(matches).await, + } + } + + pub async fn execute_do_ping(&self, matches: &::clap::ArgMatches) -> anyhow::Result<()> { + let mut request = self.client.do_ping(); + self.config.execute_do_ping(matches, &mut request)?; + let result = request.send().await; + match result { + Ok(r) => { + self.config.success_no_item(&r); + Ok(()) + } + Err(r) => { + self.config.error(&r); + Err(anyhow::Error::new(r)) + } + } + } +} + +pub trait CliConfig { + fn success_item(&self, value: &ResponseValue) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn success_no_item(&self, value: &ResponseValue<()>); + fn error(&self, value: &Error) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_start(&self) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_item(&self, value: &T) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_end_success(&self) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn list_end_error(&self, value: &Error) + where + T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug; + fn execute_do_ping( + &self, + matches: &::clap::ArgMatches, + request: &mut builder::DoPing, + ) -> anyhow::Result<()> { + Ok(()) + } +} + +#[derive(Copy, Clone, Debug)] +pub enum CliCommand { + DoPing, +} + +impl CliCommand { + pub fn iter() -> impl Iterator { + vec![CliCommand::DoPing].into_iter() + } +} diff --git a/progenitor-impl/tests/output/src/missing_operation_id_httpmock.rs b/progenitor-impl/tests/output/src/missing_operation_id_httpmock.rs new file mode 100644 index 00000000..c4e832af --- /dev/null +++ b/progenitor-impl/tests/output/src/missing_operation_id_httpmock.rs @@ -0,0 +1,59 @@ +pub mod operations { + #![doc = r" [`When`](::httpmock::When) and [`Then`](::httpmock::Then)"] + #![doc = r" wrappers for each operation. Each can be converted to"] + #![doc = r" its inner type with a call to `into_inner()`. This can"] + #![doc = r" be used to explicitly deviate from permitted values."] + use crate::missing_operation_id_builder::*; + pub struct DoPingWhen(::httpmock::When); + impl DoPingWhen { + pub fn new(inner: ::httpmock::When) -> Self { + Self( + inner + .method(::httpmock::Method::POST) + .path_matches(regex::Regex::new("^/$").unwrap()), + ) + } + + pub fn into_inner(self) -> ::httpmock::When { + self.0 + } + } + + pub struct DoPingThen(::httpmock::Then); + impl DoPingThen { + pub fn new(inner: ::httpmock::Then) -> Self { + Self(inner) + } + + pub fn into_inner(self) -> ::httpmock::Then { + self.0 + } + + pub fn ok(self) -> Self { + Self(self.0.status(200u16)) + } + } +} + +#[doc = r" An extension trait for [`MockServer`](::httpmock::MockServer) that"] +#[doc = r" adds a method for each operation. These are the equivalent of"] +#[doc = r" type-checked [`mock()`](::httpmock::MockServer::mock) calls."] +pub trait MockServerExt { + fn do_ping(&self, config_fn: F) -> ::httpmock::Mock<'_> + where + F: FnOnce(operations::DoPingWhen, operations::DoPingThen); +} + +impl MockServerExt for ::httpmock::MockServer { + fn do_ping(&self, config_fn: F) -> ::httpmock::Mock<'_> + where + F: FnOnce(operations::DoPingWhen, operations::DoPingThen), + { + self.mock(|when, then| { + config_fn( + operations::DoPingWhen::new(when), + operations::DoPingThen::new(then), + ) + }) + } +} diff --git a/progenitor-impl/tests/output/src/missing_operation_id_positional.rs b/progenitor-impl/tests/output/src/missing_operation_id_positional.rs new file mode 100644 index 00000000..36f99633 --- /dev/null +++ b/progenitor-impl/tests/output/src/missing_operation_id_positional.rs @@ -0,0 +1,134 @@ +#[allow(unused_imports)] +use progenitor_client::{encode_path, ClientHooks, OperationInfo, RequestBuilderExt}; +#[allow(unused_imports)] +pub use progenitor_client::{ByteStream, ClientInfo, Error, ResponseValue}; +/// Types used as operation parameters and responses. +#[allow(clippy::all)] +pub mod types { + /// Error types. + pub mod error { + /// Error from a `TryFrom` or `FromStr` implementation. + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } + } +} + +#[derive(Clone, Debug)] +///Client for Missing operation ids test +/// +///Minimal API for testing missing operation id strategies +/// +///Version: v1 +pub struct Client { + pub(crate) baseurl: String, + pub(crate) client: reqwest::Client, +} + +impl Client { + /// Create a new client. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new(baseurl: &str) -> Self { + #[cfg(not(target_arch = "wasm32"))] + let client = { + let dur = ::std::time::Duration::from_secs(15u64); + reqwest::ClientBuilder::new() + .connect_timeout(dur) + .timeout(dur) + }; + #[cfg(target_arch = "wasm32")] + let client = reqwest::ClientBuilder::new(); + Self::new_with_client(baseurl, client.build().unwrap()) + } + + /// Construct a new client with an existing `reqwest::Client`, + /// allowing more control over its configuration. + /// + /// `baseurl` is the base URL provided to the internal + /// `reqwest::Client`, and should include a scheme and hostname, + /// as well as port and a path stem if applicable. + pub fn new_with_client(baseurl: &str, client: reqwest::Client) -> Self { + Self { + baseurl: baseurl.to_string(), + client, + } + } +} + +impl ClientInfo<()> for Client { + fn api_version() -> &'static str { + "v1" + } + + fn baseurl(&self) -> &str { + self.baseurl.as_str() + } + + fn client(&self) -> &reqwest::Client { + &self.client + } + + fn inner(&self) -> &() { + &() + } +} + +impl ClientHooks<()> for &Client {} +#[allow(clippy::all)] +impl Client { + ///Ping + /// + ///Sends a `POST` request to `/` + pub async fn do_ping<'a>(&'a self) -> Result, Error<()>> { + let url = format!("{}/", self.baseurl,); + let mut header_map = ::reqwest::header::HeaderMap::with_capacity(1usize); + header_map.append( + ::reqwest::header::HeaderName::from_static("api-version"), + ::reqwest::header::HeaderValue::from_static(Self::api_version()), + ); + #[allow(unused_mut)] + let mut request = self.client.post(url).headers(header_map).build()?; + let info = OperationInfo { + operation_id: "do_ping", + }; + self.pre(&mut request, &info).await?; + let result = self.exec(request, &info).await; + self.post(&result, &info).await?; + let response = result?; + match response.status().as_u16() { + 200u16 => Ok(ResponseValue::empty(response)), + _ => Err(Error::UnexpectedResponse(response)), + } + } +} + +/// Items consumers will typically use such as the Client. +pub mod prelude { + #[allow(unused_imports)] + pub use super::Client; +} diff --git a/progenitor-impl/tests/output/src/nexus_builder_tagged.rs b/progenitor-impl/tests/output/src/nexus_builder_tagged.rs index fe2021fb..efba916f 100644 --- a/progenitor-impl/tests/output/src/nexus_builder_tagged.rs +++ b/progenitor-impl/tests/output/src/nexus_builder_tagged.rs @@ -64,7 +64,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Baseboard { pub part: ::std::string::String, pub revision: i64, @@ -170,7 +172,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum BinRangedouble { ///A range unbounded below and exclusively above, `..end`. @@ -278,7 +282,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum BinRangeint64 { ///A range unbounded below and exclusively above, `..end`. @@ -331,7 +337,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Bindouble { ///The total count of samples in this bin. pub count: u64, @@ -383,7 +391,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Binint64 { ///The total count of samples in this bin. pub count: u64, @@ -419,7 +429,7 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug)] + #[derive(:: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] #[serde(transparent)] pub struct BlockSize(i64); impl ::std::ops::Deref for BlockSize { @@ -487,7 +497,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(transparent)] pub struct ByteCount(pub u64); impl ::std::ops::Deref for ByteCount { @@ -602,7 +614,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Certificate { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -683,7 +697,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct CertificateCreate { ///PEM file containing public certificate chain pub cert: ::std::vec::Vec, @@ -738,7 +754,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct CertificateResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -803,7 +821,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ComponentUpdate { pub component_type: UpdateableComponentType, ///unique, immutable, system-controlled identifier for each resource @@ -858,7 +878,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ComponentUpdateResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -904,7 +926,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Cumulativedouble { pub start_time: ::chrono::DateTime<::chrono::offset::Utc>, pub value: f64, @@ -947,7 +971,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Cumulativeint64 { pub start_time: ::chrono::DateTime<::chrono::offset::Utc>, pub value: i64, @@ -1147,7 +1173,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "datum")] pub enum Datum { #[serde(rename = "bool")] @@ -1257,6 +1285,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum DatumType { #[serde(rename = "bool")] @@ -1370,7 +1399,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DerEncodedKeyPair { ///request signing private key (base64 encoded der file) pub private_key: ::std::string::String, @@ -1417,7 +1448,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DeviceAccessTokenRequest { pub client_id: ::uuid::Uuid, pub device_code: ::std::string::String, @@ -1455,7 +1488,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DeviceAuthRequest { pub client_id: ::uuid::Uuid, } @@ -1490,7 +1525,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DeviceAuthVerify { pub user_code: ::std::string::String, } @@ -1536,7 +1573,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "value")] pub enum Digest { #[serde(rename = "sha256")] @@ -1633,7 +1672,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Disk { pub block_size: ByteCount, ///human-readable free-form text about a resource @@ -1711,7 +1752,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DiskCreate { pub description: ::std::string::String, ///initial source for this disk @@ -1756,7 +1799,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DiskIdentifier { pub name: Name, } @@ -1802,6 +1847,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum DiskMetricName { #[serde(rename = "activated")] @@ -1895,7 +1941,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DiskPath { pub disk: NameOrId, } @@ -1943,7 +1991,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DiskResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -2061,7 +2111,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum DiskSource { ///Create a blank disk @@ -2220,7 +2272,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "state", content = "instance")] pub enum DiskState { #[serde(rename = "creating")] @@ -2279,7 +2333,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Distribution { ///The name of the distribution (e.g. "alpine" or "ubuntu") pub name: Name, @@ -2325,7 +2381,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Error { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub error_code: ::std::option::Option<::std::string::String>, @@ -2368,7 +2426,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ExternalIp { pub ip: ::std::net::IpAddr, pub kind: IpKind, @@ -2430,7 +2490,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum ExternalIpCreate { ///An IP address providing both inbound and outbound access. The @@ -2480,7 +2542,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ExternalIpResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -2529,7 +2593,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct FieldSchema { pub name: ::std::string::String, pub source: FieldSource, @@ -2575,6 +2641,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum FieldSource { #[serde(rename = "target")] @@ -2664,6 +2731,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum FieldType { #[serde(rename = "string")] @@ -2761,6 +2829,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum FleetRole { #[serde(rename = "admin")] @@ -2855,7 +2924,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct FleetRolePolicy { ///Roles directly assigned on this resource pub role_assignments: ::std::vec::Vec, @@ -2910,7 +2981,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct FleetRoleRoleAssignment { pub identity_id: ::uuid::Uuid, pub identity_type: IdentityType, @@ -3028,7 +3101,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct GlobalImage { ///size of blocks in bytes pub block_size: ByteCount, @@ -3120,7 +3195,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct GlobalImageCreate { ///block size in bytes pub block_size: BlockSize, @@ -3175,7 +3252,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct GlobalImageResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -3227,7 +3306,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Group { ///Human-readable name that can identify the group pub display_name: ::std::string::String, @@ -3279,7 +3360,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct GroupResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -3405,7 +3488,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Histogramdouble { pub bins: ::std::vec::Vec, pub n_samples: u64, @@ -3529,7 +3614,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Histogramint64 { pub bins: ::std::vec::Vec, pub n_samples: u64, @@ -3581,6 +3668,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum IdSortMode { ///sort in increasing order of "id" @@ -3695,7 +3783,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IdentityProvider { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -3754,7 +3844,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IdentityProviderResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -3804,6 +3896,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum IdentityProviderType { ///SAML identity provider @@ -3886,6 +3979,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum IdentityType { #[serde(rename = "silo_user")] @@ -3992,7 +4086,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum IdpMetadataSource { #[serde(rename = "url")] @@ -4109,7 +4205,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Image { ///size of blocks in bytes pub block_size: ByteCount, @@ -4193,7 +4291,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ImageCreate { ///block size in bytes pub block_size: BlockSize, @@ -4246,7 +4346,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ImageResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -4332,7 +4434,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum ImageSource { #[serde(rename = "url")] @@ -4436,7 +4540,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Instance { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -4485,7 +4591,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(transparent)] pub struct InstanceCpuCount(pub u16); impl ::std::ops::Deref for InstanceCpuCount { @@ -4633,7 +4741,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceCreate { pub description: ::std::string::String, ///The disks to be created or attached for this instance. @@ -4753,7 +4863,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum InstanceDiskAttachment { ///During instance creation, create and attach disks @@ -4802,7 +4914,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceMigrate { pub dst_sled_id: ::uuid::Uuid, } @@ -4891,7 +5005,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "params")] pub enum InstanceNetworkInterfaceAttachment { ///Create one or more `NetworkInterface`s for the `Instance`. @@ -4951,7 +5067,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -5008,7 +5126,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceSerialConsoleData { ///The bytes starting from the requested offset up to either the end of /// the buffer or the request's `max_bytes`. Provided as a u8 array @@ -5134,6 +5254,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum InstanceState { ///The instance is being created. @@ -5265,6 +5386,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum IpKind { #[serde(rename = "ephemeral")] @@ -5351,7 +5473,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(untagged)] pub enum IpNet { V4(Ipv4Net), @@ -5474,7 +5598,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IpPool { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -5526,7 +5652,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IpPoolCreate { pub description: ::std::string::String, pub name: Name, @@ -5572,7 +5700,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IpPoolRange { pub id: ::uuid::Uuid, pub range: IpRange, @@ -5622,7 +5752,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IpPoolRangeResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -5674,7 +5806,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IpPoolResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -5728,7 +5862,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct IpPoolUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -5784,7 +5920,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(untagged)] pub enum IpRange { V4(Ipv4Range), @@ -5828,7 +5966,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct Ipv4Net(::std::string::String); impl ::std::ops::Deref for Ipv4Net { @@ -5940,7 +6088,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Ipv4Range { pub first: ::std::net::Ipv4Addr, pub last: ::std::net::Ipv4Addr, @@ -5976,7 +6126,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct Ipv6Net(::std::string::String); impl ::std::ops::Deref for Ipv6Net { @@ -6087,7 +6247,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Ipv6Range { pub first: ::std::net::Ipv6Addr, pub last: ::std::net::Ipv6Addr, @@ -6125,7 +6287,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct L4PortRange(::std::string::String); impl ::std::ops::Deref for L4PortRange { @@ -6223,7 +6395,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct MacAddr(::std::string::String); impl ::std::ops::Deref for MacAddr { @@ -6330,7 +6512,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Measurement { pub datum: Datum, pub timestamp: ::chrono::DateTime<::chrono::offset::Utc>, @@ -6379,7 +6563,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct MeasurementResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -6421,7 +6607,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct Name(::std::string::String); impl ::std::ops::Deref for Name { @@ -6527,7 +6723,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(untagged)] pub enum NameOrId { Id(::uuid::Uuid), @@ -6644,6 +6842,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum NameOrIdSortMode { ///sort in increasing order of "name" @@ -6743,6 +6942,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum NameSortMode { ///sort in increasing order of "name" @@ -6888,7 +7088,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct NetworkInterface { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -6978,7 +7180,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct NetworkInterfaceCreate { pub description: ::std::string::String, ///The IP address for the interface. One will be auto-assigned if not @@ -7035,7 +7239,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct NetworkInterfaceResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -7108,7 +7314,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct NetworkInterfaceUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -7180,6 +7388,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] #[serde(transparent)] pub struct NodeName(pub ::std::string::String); @@ -7270,7 +7479,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Organization { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -7321,7 +7532,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct OrganizationCreate { pub description: ::std::string::String, pub name: Name, @@ -7370,7 +7583,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct OrganizationResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -7417,6 +7632,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum OrganizationRole { #[serde(rename = "admin")] @@ -7511,7 +7727,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct OrganizationRolePolicy { ///Roles directly assigned on this resource pub role_assignments: ::std::vec::Vec, @@ -7566,7 +7784,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct OrganizationRoleRoleAssignment { pub identity_id: ::uuid::Uuid, pub identity_type: IdentityType, @@ -7620,7 +7840,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct OrganizationUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -7662,7 +7884,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct Password(::std::string::String); impl ::std::ops::Deref for Password { @@ -7790,7 +8022,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct PhysicalDisk { pub disk_type: PhysicalDiskType, ///unique, immutable, system-controlled identifier for each resource @@ -7850,7 +8084,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct PhysicalDiskResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -7896,6 +8132,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum PhysicalDiskType { #[serde(rename = "internal")] @@ -8009,7 +8246,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Project { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -8061,7 +8300,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ProjectCreate { pub description: ::std::string::String, pub name: Name, @@ -8110,7 +8351,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ProjectResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -8157,6 +8400,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum ProjectRole { #[serde(rename = "admin")] @@ -8251,7 +8495,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ProjectRolePolicy { ///Roles directly assigned on this resource pub role_assignments: ::std::vec::Vec, @@ -8306,7 +8552,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ProjectRoleRoleAssignment { pub identity_id: ::uuid::Uuid, pub identity_type: IdentityType, @@ -8360,7 +8608,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct ProjectUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -8423,7 +8673,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Rack { ///unique, immutable, system-controlled identifier for each resource pub id: ::uuid::Uuid, @@ -8476,7 +8728,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct RackResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -8520,7 +8774,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Role { pub description: ::std::string::String, pub name: RoleName, @@ -8553,7 +8809,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct RoleName(::std::string::String); impl ::std::ops::Deref for RoleName { @@ -8659,7 +8925,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct RoleResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -8781,7 +9049,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "value")] pub enum RouteDestination { ///Route applies to traffic destined for a specific IP address @@ -8926,7 +9196,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "value")] pub enum RouteTarget { ///Forward traffic to a particular IP address. @@ -9033,7 +9305,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct RouterRoute { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -9096,7 +9370,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct RouterRouteCreateParams { pub description: ::std::string::String, pub destination: RouteDestination, @@ -9176,6 +9452,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum RouterRouteKind { ///Determines the default destination of traffic, such as whether it @@ -9287,7 +9564,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct RouterRouteResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -9351,7 +9630,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct RouterRouteUpdateParams { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -9396,7 +9677,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Saga { pub id: ::uuid::Uuid, pub state: SagaState, @@ -9509,7 +9792,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "error")] pub enum SagaErrorInfo { #[serde(rename = "action_failed")] @@ -9561,7 +9846,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SagaResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -9643,7 +9930,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "state")] pub enum SagaState { #[serde(rename = "running")] @@ -9750,7 +10039,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SamlIdentityProvider { ///service provider endpoint where the response will be sent pub acs_url: ::std::string::String, @@ -9875,7 +10166,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SamlIdentityProviderCreate { ///service provider endpoint where the response will be sent pub acs_url: ::std::string::String, @@ -9924,7 +10217,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct SemverVersion(::std::string::String); impl ::std::ops::Deref for SemverVersion { @@ -10029,6 +10332,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum ServiceUsingCertificate { ///This certificate is intended for access to the external API. @@ -10148,7 +10452,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Silo { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -10224,7 +10530,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SiloCreate { ///If set, this group will be created during Silo creation and granted /// the "Silo Admin" role. Identity providers can assert that users @@ -10298,6 +10606,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum SiloIdentityMode { ///Users are authenticated with SAML using an external authentication @@ -10394,7 +10703,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SiloResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -10441,6 +10752,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum SiloRole { #[serde(rename = "admin")] @@ -10535,7 +10847,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SiloRolePolicy { ///Roles directly assigned on this resource pub role_assignments: ::std::vec::Vec, @@ -10590,7 +10904,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SiloRoleRoleAssignment { pub identity_id: ::uuid::Uuid, pub identity_type: IdentityType, @@ -10651,7 +10967,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Sled { pub baseboard: Baseboard, ///unique, immutable, system-controlled identifier for each resource @@ -10706,7 +11024,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SledResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -10794,7 +11114,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Snapshot { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -10858,7 +11180,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SnapshotCreate { pub description: ::std::string::String, ///The name of the disk to be snapshotted @@ -10909,7 +11233,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SnapshotResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -10957,6 +11283,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum SnapshotState { #[serde(rename = "creating")] @@ -11042,7 +11369,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SpoofLoginBody { pub username: ::std::string::String, } @@ -11120,7 +11449,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SshKey { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -11181,7 +11512,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SshKeyCreate { pub description: ::std::string::String, pub name: Name, @@ -11232,7 +11565,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SshKeyResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -11279,6 +11614,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum SystemMetricName { #[serde(rename = "virtual_disk_space_provisioned")] @@ -11382,7 +11718,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SystemUpdate { ///unique, immutable, system-controlled identifier for each resource pub id: ::uuid::Uuid, @@ -11436,7 +11774,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SystemUpdateResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -11475,7 +11815,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SystemUpdateStart { pub version: SemverVersion, } @@ -11514,7 +11856,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct SystemVersion { pub status: UpdateStatus, pub version_range: VersionRange, @@ -11550,7 +11894,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct TimeseriesName(::std::string::String); impl ::std::ops::Deref for TimeseriesName { @@ -11670,7 +12024,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct TimeseriesSchema { pub created: ::chrono::DateTime<::chrono::offset::Utc>, pub datum_type: DatumType, @@ -11721,7 +12077,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct TimeseriesSchemaResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -11786,7 +12144,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UpdateDeployment { ///unique, immutable, system-controlled identifier for each resource pub id: ::uuid::Uuid, @@ -11841,7 +12201,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UpdateDeploymentResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -11912,6 +12274,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] #[serde(tag = "status")] pub enum UpdateStatus { @@ -12028,7 +12391,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UpdateableComponent { pub component_type: UpdateableComponentType, pub device_id: ::std::string::String, @@ -12086,7 +12451,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UpdateableComponentResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -12142,6 +12509,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum UpdateableComponentType { #[serde(rename = "bootloader_for_rot")] @@ -12272,7 +12640,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct User { ///Human-readable name that can identify the user pub display_name: ::std::string::String, @@ -12342,7 +12712,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UserBuiltin { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -12399,7 +12771,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UserBuiltinResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -12454,7 +12828,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UserCreate { ///username used to log in pub external_id: UserId, @@ -12495,7 +12871,17 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Serialize, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, + )] #[serde(transparent)] pub struct UserId(::std::string::String); impl ::std::ops::Deref for UserId { @@ -12620,7 +13006,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "user_password_value", content = "details")] pub enum UserPassword { ///Sets the user's password to the provided value @@ -12673,7 +13061,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UserResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -12717,7 +13107,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct UsernamePasswordCredentials { pub password: Password, pub username: UserId, @@ -12757,7 +13149,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VersionRange { pub high: SemverVersion, pub low: SemverVersion, @@ -12856,7 +13250,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Vpc { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -12936,7 +13332,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcCreate { pub description: ::std::string::String, pub dns_name: Name, @@ -13072,7 +13470,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcFirewallRule { ///whether traffic matching the rule should be allowed or dropped pub action: VpcFirewallRuleAction, @@ -13137,6 +13537,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum VpcFirewallRuleAction { #[serde(rename = "allow")] @@ -13221,6 +13622,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum VpcFirewallRuleDirection { #[serde(rename = "inbound")] @@ -13330,7 +13732,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcFirewallRuleFilter { ///If present, the sources (if incoming) or destinations (if outgoing) /// this rule applies to. @@ -13481,7 +13885,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "value")] pub enum VpcFirewallRuleHostFilter { ///The rule applies to traffic from/to all instances in the VPC @@ -13547,6 +13953,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum VpcFirewallRuleProtocol { #[serde(rename = "TCP")] @@ -13635,6 +14042,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum VpcFirewallRuleStatus { #[serde(rename = "disabled")] @@ -13805,7 +14213,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type", content = "value")] pub enum VpcFirewallRuleTarget { ///The rule applies to all instances in the VPC @@ -13926,7 +14336,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcFirewallRuleUpdate { ///whether traffic matching the rule should be allowed or dropped pub action: VpcFirewallRuleAction, @@ -13984,7 +14396,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcFirewallRuleUpdateParams { pub rules: ::std::vec::Vec, } @@ -14023,7 +14437,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcFirewallRules { pub rules: ::std::vec::Vec, } @@ -14071,7 +14487,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -14153,7 +14571,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcRouter { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -14207,7 +14627,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcRouterCreate { pub description: ::std::string::String, pub name: Name, @@ -14250,6 +14672,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum VpcRouterKind { #[serde(rename = "system")] @@ -14340,7 +14763,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcRouterResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -14396,7 +14821,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcRouterUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -14502,7 +14929,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcSubnet { ///human-readable free-form text about a resource pub description: ::std::string::String, @@ -14589,7 +15018,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcSubnetCreate { pub description: ::std::string::String, ///The IPv4 address range for this subnet. @@ -14651,7 +15082,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcSubnetResultsPage { ///list of items on this page of results pub items: ::std::vec::Vec, @@ -14707,7 +15140,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcSubnetUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, @@ -14784,7 +15219,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct VpcUpdate { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub description: ::std::option::Option<::std::string::String>, diff --git a/progenitor-impl/tests/output/src/propolis_server_builder_tagged.rs b/progenitor-impl/tests/output/src/propolis_server_builder_tagged.rs index f270d677..27eb077b 100644 --- a/progenitor-impl/tests/output/src/propolis_server_builder_tagged.rs +++ b/progenitor-impl/tests/output/src/propolis_server_builder_tagged.rs @@ -107,7 +107,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct CrucibleOpts { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub cert_pem: ::std::option::Option<::std::string::String>, @@ -168,7 +170,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DiskAttachment { pub disk_id: ::uuid::Uuid, pub generation_id: u64, @@ -219,7 +223,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub enum DiskAttachmentState { Detached, Destroyed, @@ -279,7 +285,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct DiskRequest { pub device: ::std::string::String, pub gen: u64, @@ -327,7 +335,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Error { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub error_code: ::std::option::Option<::std::string::String>, @@ -383,7 +393,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct Instance { pub disks: ::std::vec::Vec, pub nics: ::std::vec::Vec, @@ -456,7 +468,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceEnsureRequest { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub cloud_init_bytes: ::std::option::Option<::std::string::String>, @@ -508,7 +522,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceEnsureResponse { #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] pub migrate: ::std::option::Option, @@ -552,7 +568,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceGetResponse { pub instance: Instance, } @@ -597,7 +615,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceMigrateInitiateRequest { pub migration_id: ::uuid::Uuid, pub src_addr: ::std::string::String, @@ -635,7 +655,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceMigrateInitiateResponse { pub migration_id: ::uuid::Uuid, } @@ -671,7 +693,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceMigrateStatusRequest { pub migration_id: ::uuid::Uuid, } @@ -706,7 +730,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceMigrateStatusResponse { pub state: MigrationState, } @@ -780,7 +806,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceProperties { ///ID of the bootrom used to initialize this Instance. pub bootrom_id: ::uuid::Uuid, @@ -844,6 +872,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum InstanceState { Creating, @@ -945,7 +974,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceStateMonitorRequest { pub gen: u64, } @@ -986,7 +1017,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct InstanceStateMonitorResponse { pub gen: u64, pub state: InstanceState, @@ -1031,6 +1064,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum InstanceStateRequested { Run, @@ -1127,6 +1161,7 @@ pub mod types { Ord, PartialEq, PartialOrd, + schemars :: JsonSchema, )] pub enum MigrationState { Sync, @@ -1230,7 +1265,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct NetworkInterface { pub attachment: NetworkInterfaceAttachmentState, pub name: ::std::string::String, @@ -1278,7 +1315,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub enum NetworkInterfaceAttachmentState { Detached, Faulted, @@ -1319,7 +1358,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] pub struct NetworkInterfaceRequest { pub name: ::std::string::String, pub slot: Slot, @@ -1352,7 +1393,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(transparent)] pub struct Slot(pub u8); impl ::std::ops::Deref for Slot { @@ -1560,7 +1603,9 @@ pub mod types { ///} /// ``` /// - #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] + #[derive( + :: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema, + )] #[serde(tag = "type")] pub enum VolumeConstructionRequest { #[serde(rename = "volume")] diff --git a/progenitor-impl/tests/test_output.rs b/progenitor-impl/tests/test_output.rs index 010315d9..49643612 100644 --- a/progenitor-impl/tests/test_output.rs +++ b/progenitor-impl/tests/test_output.rs @@ -6,7 +6,8 @@ use std::{ }; use progenitor_impl::{ - space_out_items, GenerationSettings, Generator, InterfaceStyle, TagStyle, TypeImpl, TypePatch, + space_out_items, GenerationSettings, Generator, InterfaceStyle, OperationIdStrategy, TagStyle, + TypeImpl, TypePatch, }; use openapiv3::OpenAPI; @@ -41,8 +42,12 @@ fn reformat_code(content: TokenStream) -> String { space_out_items(rustfmt_wrapper::rustfmt_config(rustfmt_config, content).unwrap()).unwrap() } -#[track_caller] fn verify_apis(openapi_file: &str) { + verify_apis_with_settings(openapi_file, &GenerationSettings::default()) +} + +#[track_caller] +fn verify_apis_with_settings(openapi_file: &str, settings: &GenerationSettings) { let mut in_path = PathBuf::from("../sample_openapi"); in_path.push(openapi_file); let openapi_stem = openapi_file.split('.').next().unwrap().replace('-', "_"); @@ -50,7 +55,7 @@ fn verify_apis(openapi_file: &str) { let spec = load_api(in_path); // Positional generation. - let mut generator = Generator::default(); + let mut generator = Generator::new(settings); let output = generate_formatted(&mut generator, &spec); expectorate::assert_contents( format!("tests/output/src/{}_positional.rs", openapi_stem), @@ -58,8 +63,9 @@ fn verify_apis(openapi_file: &str) { ); // Builder generation with derives and patches. + let mut settings = settings.clone(); let mut generator = Generator::new( - GenerationSettings::default() + settings .with_interface(InterfaceStyle::Builder) .with_tag(TagStyle::Merged) .with_derive("schemars::JsonSchema") @@ -81,8 +87,9 @@ fn verify_apis(openapi_file: &str) { ); // Builder generation with tags. + let mut settings = settings.clone(); let mut generator = Generator::new( - GenerationSettings::default() + settings .with_interface(InterfaceStyle::Builder) .with_cli_bounds("std::clone::Clone") .with_tag(TagStyle::Separate), @@ -181,6 +188,22 @@ fn test_nexus_with_different_timeout() { ); } +#[test] +fn test_missing_operation_id() { + verify_apis_with_settings( + "missing-operation-id.json", + GenerationSettings::new().with_operation_id_strategy(OperationIdStrategy::OmitMissing), + ); +} + +#[test] +fn test_generated_operation_id() { + verify_apis_with_settings( + "generated-operation-id.json", + GenerationSettings::new().with_operation_id_strategy(OperationIdStrategy::GenerateMissing), + ); +} + // TODO this file is full of inconsistencies and incorrectly specified types. // It's an interesting test to consider whether we try to do our best to // interpret the intent or just fail. diff --git a/sample_openapi/generated-operation-id.json b/sample_openapi/generated-operation-id.json new file mode 100644 index 00000000..a5f03b4c --- /dev/null +++ b/sample_openapi/generated-operation-id.json @@ -0,0 +1,31 @@ +{ + "openapi": "3.0.0", + "info": { + "description": "Minimal API for testing missing operation id strategies", + "title": "Missing operation ids test", + "version": "v1" + }, + "paths": { + "/": { + "get": { + "description": "Ping", + "responses": { + "200": { + "description": "Pong", + "type": "string" + } + } + }, + "post": { + "description": "Ping", + "operationId": "do_ping", + "responses": { + "200": { + "description": "Pong", + "type": "string" + } + } + } + } + } +} diff --git a/sample_openapi/missing-operation-id.json b/sample_openapi/missing-operation-id.json new file mode 100644 index 00000000..a5f03b4c --- /dev/null +++ b/sample_openapi/missing-operation-id.json @@ -0,0 +1,31 @@ +{ + "openapi": "3.0.0", + "info": { + "description": "Minimal API for testing missing operation id strategies", + "title": "Missing operation ids test", + "version": "v1" + }, + "paths": { + "/": { + "get": { + "description": "Ping", + "responses": { + "200": { + "description": "Pong", + "type": "string" + } + } + }, + "post": { + "description": "Ping", + "operationId": "do_ping", + "responses": { + "200": { + "description": "Pong", + "type": "string" + } + } + } + } + } +} From 636baeaa1f433943d94c7a0713d47b4d9ddf90df Mon Sep 17 00:00:00 2001 From: Alexander Lyon Date: Thu, 6 Nov 2025 11:48:13 +0000 Subject: [PATCH 4/4] add arg to cargo-progenitor --- cargo-progenitor/src/main.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cargo-progenitor/src/main.rs b/cargo-progenitor/src/main.rs index 191675a7..146adbb5 100644 --- a/cargo-progenitor/src/main.rs +++ b/cargo-progenitor/src/main.rs @@ -9,7 +9,7 @@ use std::{ use anyhow::{bail, Result}; use clap::{Parser, ValueEnum}; use openapiv3::OpenAPI; -use progenitor::{GenerationSettings, Generator, InterfaceStyle, TagStyle}; +use progenitor::{GenerationSettings, Generator, InterfaceStyle, OperationIdStrategy, TagStyle}; use progenitor_impl::space_out_items; fn is_non_release() -> bool { @@ -51,6 +51,9 @@ struct Args { /// SDK tag style #[clap(value_enum, long, default_value_t = TagArg::Merged)] tags: TagArg, + /// SDK operation id style + #[clap(value_enum, long, default_value_t = OperationIdStrategyArg::RejectMissing)] + operation_id_strategy: OperationIdStrategyArg, /// Include client code rather than depending on progenitor-client #[clap(default_value = match is_non_release() { true => "true", false => "false" }, long, action = clap::ArgAction::Set)] include_client: bool, @@ -86,6 +89,23 @@ impl From for TagStyle { } } +#[derive(Copy, Clone, ValueEnum)] +enum OperationIdStrategyArg { + RejectMissing, + OmitMissing, + GenerateMissing, +} + +impl From for OperationIdStrategy { + fn from(arg: OperationIdStrategyArg) -> Self { + match arg { + OperationIdStrategyArg::RejectMissing => OperationIdStrategy::RejectMissing, + OperationIdStrategyArg::OmitMissing => OperationIdStrategy::OmitMissing, + OperationIdStrategyArg::GenerateMissing => OperationIdStrategy::GenerateMissing, + } + } +} + fn reformat_code(input: String) -> String { let config = rustfmt_wrapper::config::Config { normalize_doc_attributes: Some(true), @@ -119,7 +139,8 @@ fn main() -> Result<()> { let mut builder = Generator::new( GenerationSettings::default() .with_interface(args.interface.into()) - .with_tag(args.tags.into()), + .with_tag(args.tags.into()) + .with_operation_id_strategy(args.operation_id_strategy.into()), ); match builder.generate_tokens(&api) {