Skip to content

Commit 957afea

Browse files
authored
Enable custom trait bounds for CLI (#1195)
Allow users to specify additional trait bounds on `CliConfig` methods.
1 parent d38cd70 commit 957afea

File tree

10 files changed

+64
-49
lines changed

10 files changed

+64
-49
lines changed

progenitor-impl/src/cli.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::collections::BTreeMap;
55
use heck::ToKebabCase;
66
use openapiv3::OpenAPI;
77
use proc_macro2::TokenStream;
8-
use quote::{format_ident, quote};
8+
use quote::{format_ident, quote, ToTokens};
99
use typify::{Type, TypeEnumVariant, TypeSpaceImpl, TypeStructPropInfo};
1010

1111
use crate::{
@@ -79,6 +79,13 @@ impl Generator {
7979
path: syn::parse_str(crate_name).unwrap(),
8080
};
8181

82+
let cli_bounds: Vec<_> = self
83+
.settings
84+
.extra_cli_bounds
85+
.iter()
86+
.map(|b| syn::parse_str::<syn::Path>(b).unwrap().into_token_stream())
87+
.collect();
88+
8289
let code = quote! {
8390
use #crate_path::*;
8491

@@ -125,24 +132,24 @@ impl Generator {
125132
pub trait CliConfig {
126133
fn success_item<T>(&self, value: &ResponseValue<T>)
127134
where
128-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
135+
T: #(#cli_bounds+)* schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
129136
fn success_no_item(&self, value: &ResponseValue<()>);
130137
fn error<T>(&self, value: &Error<T>)
131138
where
132-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
139+
T: #(#cli_bounds+)* schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
133140

134141
fn list_start<T>(&self)
135142
where
136-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
143+
T: #(#cli_bounds+)* schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
137144
fn list_item<T>(&self, value: &T)
138145
where
139-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
146+
T: #(#cli_bounds+)* schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
140147
fn list_end_success<T>(&self)
141148
where
142-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
149+
T: #(#cli_bounds+)* schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
143150
fn list_end_error<T>(&self, value: &Error<T>)
144151
where
145-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
152+
T: #(#cli_bounds+)* schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
146153

147154
#(#trait_ops)*
148155
}

progenitor-impl/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub struct GenerationSettings {
6666
post_hook: Option<TokenStream>,
6767
post_hook_async: Option<TokenStream>,
6868
extra_derives: Vec<String>,
69+
extra_cli_bounds: Vec<String>,
6970

7071
map_type: Option<String>,
7172
unknown_crates: UnknownPolicy,
@@ -166,6 +167,12 @@ impl GenerationSettings {
166167
self
167168
}
168169

170+
/// Additional trait bounds applied to `CliConfig` methods.
171+
pub fn with_cli_bounds(&mut self, derive: impl ToString) -> &mut Self {
172+
self.extra_cli_bounds.push(derive.to_string());
173+
self
174+
}
175+
169176
/// Modify a type with the given name.
170177
/// See [typify::TypeSpaceSettings::with_patch].
171178
pub fn with_patch<S: AsRef<str>>(&mut self, type_name: S, patch: &TypePatch) -> &mut Self {

progenitor-impl/tests/output/src/buildomat_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -894,23 +894,23 @@ impl<T: CliConfig> Cli<T> {
894894
pub trait CliConfig {
895895
fn success_item<T>(&self, value: &ResponseValue<T>)
896896
where
897-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
897+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
898898
fn success_no_item(&self, value: &ResponseValue<()>);
899899
fn error<T>(&self, value: &Error<T>)
900900
where
901-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
901+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
902902
fn list_start<T>(&self)
903903
where
904-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
904+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
905905
fn list_item<T>(&self, value: &T)
906906
where
907-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
907+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
908908
fn list_end_success<T>(&self)
909909
where
910-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
910+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
911911
fn list_end_error<T>(&self, value: &Error<T>)
912912
where
913-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
913+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
914914
fn execute_control_hold(
915915
&self,
916916
matches: &::clap::ArgMatches,

progenitor-impl/tests/output/src/cli_gen_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,23 @@ impl<T: CliConfig> Cli<T> {
7878
pub trait CliConfig {
7979
fn success_item<T>(&self, value: &ResponseValue<T>)
8080
where
81-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
81+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8282
fn success_no_item(&self, value: &ResponseValue<()>);
8383
fn error<T>(&self, value: &Error<T>)
8484
where
85-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
85+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8686
fn list_start<T>(&self)
8787
where
88-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
88+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8989
fn list_item<T>(&self, value: &T)
9090
where
91-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
91+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
9292
fn list_end_success<T>(&self)
9393
where
94-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
94+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
9595
fn list_end_error<T>(&self, value: &Error<T>)
9696
where
97-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
97+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
9898
fn execute_uno(
9999
&self,
100100
matches: &::clap::ArgMatches,

progenitor-impl/tests/output/src/keeper_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,23 +381,23 @@ impl<T: CliConfig> Cli<T> {
381381
pub trait CliConfig {
382382
fn success_item<T>(&self, value: &ResponseValue<T>)
383383
where
384-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
384+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
385385
fn success_no_item(&self, value: &ResponseValue<()>);
386386
fn error<T>(&self, value: &Error<T>)
387387
where
388-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
388+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
389389
fn list_start<T>(&self)
390390
where
391-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
391+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
392392
fn list_item<T>(&self, value: &T)
393393
where
394-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
394+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
395395
fn list_end_success<T>(&self)
396396
where
397-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
397+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
398398
fn list_end_error<T>(&self, value: &Error<T>)
399399
where
400-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
400+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
401401
fn execute_enrol(
402402
&self,
403403
matches: &::clap::ArgMatches,

progenitor-impl/tests/output/src/nexus_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12375,23 +12375,23 @@ impl<T: CliConfig> Cli<T> {
1237512375
pub trait CliConfig {
1237612376
fn success_item<T>(&self, value: &ResponseValue<T>)
1237712377
where
12378-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
12378+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
1237912379
fn success_no_item(&self, value: &ResponseValue<()>);
1238012380
fn error<T>(&self, value: &Error<T>)
1238112381
where
12382-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
12382+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
1238312383
fn list_start<T>(&self)
1238412384
where
12385-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
12385+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
1238612386
fn list_item<T>(&self, value: &T)
1238712387
where
12388-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
12388+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
1238912389
fn list_end_success<T>(&self)
1239012390
where
12391-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
12391+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
1239212392
fn list_end_error<T>(&self, value: &Error<T>)
1239312393
where
12394-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
12394+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
1239512395
fn execute_disk_view_by_id(
1239612396
&self,
1239712397
matches: &::clap::ArgMatches,

progenitor-impl/tests/output/src/param_collision_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,23 +116,23 @@ impl<T: CliConfig> Cli<T> {
116116
pub trait CliConfig {
117117
fn success_item<T>(&self, value: &ResponseValue<T>)
118118
where
119-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
119+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
120120
fn success_no_item(&self, value: &ResponseValue<()>);
121121
fn error<T>(&self, value: &Error<T>)
122122
where
123-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
123+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
124124
fn list_start<T>(&self)
125125
where
126-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
126+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
127127
fn list_item<T>(&self, value: &T)
128128
where
129-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
129+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
130130
fn list_end_success<T>(&self)
131131
where
132-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
132+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
133133
fn list_end_error<T>(&self, value: &Error<T>)
134134
where
135-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
135+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
136136
fn execute_key_get(
137137
&self,
138138
matches: &::clap::ArgMatches,

progenitor-impl/tests/output/src/param_overrides_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,23 @@ impl<T: CliConfig> Cli<T> {
7272
pub trait CliConfig {
7373
fn success_item<T>(&self, value: &ResponseValue<T>)
7474
where
75-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
75+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
7676
fn success_no_item(&self, value: &ResponseValue<()>);
7777
fn error<T>(&self, value: &Error<T>)
7878
where
79-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
79+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8080
fn list_start<T>(&self)
8181
where
82-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
82+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8383
fn list_item<T>(&self, value: &T)
8484
where
85-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
85+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8686
fn list_end_success<T>(&self)
8787
where
88-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
88+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
8989
fn list_end_error<T>(&self, value: &Error<T>)
9090
where
91-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
91+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
9292
fn execute_key_get(
9393
&self,
9494
matches: &::clap::ArgMatches,

progenitor-impl/tests/output/src/propolis_server_cli.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,23 +343,23 @@ impl<T: CliConfig> Cli<T> {
343343
pub trait CliConfig {
344344
fn success_item<T>(&self, value: &ResponseValue<T>)
345345
where
346-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
346+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
347347
fn success_no_item(&self, value: &ResponseValue<()>);
348348
fn error<T>(&self, value: &Error<T>)
349349
where
350-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
350+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
351351
fn list_start<T>(&self)
352352
where
353-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
353+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
354354
fn list_item<T>(&self, value: &T)
355355
where
356-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
356+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
357357
fn list_end_success<T>(&self)
358358
where
359-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
359+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
360360
fn list_end_error<T>(&self, value: &Error<T>)
361361
where
362-
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
362+
T: std::clone::Clone + schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
363363
fn execute_instance_get(
364364
&self,
365365
matches: &::clap::ArgMatches,

progenitor-impl/tests/test_output.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ fn verify_apis(openapi_file: &str) {
8484
let mut generator = Generator::new(
8585
GenerationSettings::default()
8686
.with_interface(InterfaceStyle::Builder)
87+
.with_cli_bounds("std::clone::Clone")
8788
.with_tag(TagStyle::Separate),
8889
);
8990
let output = generate_formatted(&mut generator, &spec);

0 commit comments

Comments
 (0)