@@ -15,8 +15,15 @@ struct Cli {
1515enum Command {
1616 /// Generate types
1717 Types ,
18- /// Generate method callers
19- Rest ,
18+ /// Generate low level REST method callers
19+ Rest {
20+ /// Generate REST methods without tags
21+ #[ arg( short, long, default_value_t = false ) ]
22+ no_tag : bool ,
23+ /// Generate REST methods with specific tag (kebab variant of tag name)
24+ #[ arg( short, long) ]
25+ tag : Option < String > ,
26+ } ,
2027 /// Specs
2128 Specs ,
2229 /// Tags
@@ -37,7 +44,8 @@ enum TagsFormat {
3744 Cargo ,
3845 #[ default]
3946 Kebab ,
40- Mod ,
47+ ModResource ,
48+ ModRest ,
4149}
4250
4351#[ derive( Debug ) ]
@@ -112,10 +120,12 @@ mod openapi {
112120 }
113121
114122 impl < ' s > SpecPath < ' s > {
115- pub fn to_rust_rest_client_method ( & self , path : & str ) -> String {
123+ pub fn to_rust_rest_client_method ( & self , path : & str , add_cfg : bool ) -> String {
116124 self . calls
117125 . iter ( )
118- . map ( |( method, call) | call. to_rust_method ( path, method, self . parameters . as_deref ( ) ) )
126+ . map ( |( method, call) | {
127+ call. to_rust_method ( path, method, self . parameters . as_deref ( ) , add_cfg)
128+ } )
119129 . collect :: < Vec < _ > > ( )
120130 . join ( "\n " )
121131 }
@@ -325,6 +335,7 @@ mod openapi {
325335 path : & str ,
326336 method : & Method ,
327337 parameters : Option < & [ Parameter ] > ,
338+ add_cfg : bool ,
328339 ) -> String {
329340 let mut method_name = path
330341 . strip_prefix ( "/admin/realms" )
@@ -406,7 +417,9 @@ mod openapi {
406417 . map ( |tag| "tag-" . to_string ( ) + & tag. as_ref ( ) . to_kebab_case ( ) )
407418 . unwrap_or_else ( || TAG_NONE . to_string ( ) ) ;
408419
409- output. push ( format ! ( r#"#[cfg(feature = "{tag}")]"# ) ) ;
420+ if add_cfg {
421+ output. push ( format ! ( r#"#[cfg(feature = "{tag}")]"# ) ) ;
422+ }
410423
411424 if self . deprecated {
412425 output. push ( "#[deprecated]" . into ( ) ) ;
@@ -1366,12 +1379,19 @@ fn main() {
13661379
13671380 match cli. command {
13681381 Command :: Types => generate_types ( & specs) ,
1369- Command :: Rest => generate_rest ( & specs) ,
1382+ Command :: Rest { no_tag , tag } => generate_rest ( & specs, no_tag , tag ) ,
13701383 Command :: Methods { no_tag, tag } => generate_methods ( & specs, no_tag, tag) ,
13711384 Command :: Tags { format } => match format. unwrap_or_default ( ) {
13721385 TagsFormat :: Cargo => list_tags_for_cargo ( & specs) ,
13731386 TagsFormat :: Kebab => list_tags_as_kebab ( & specs) ,
1374- TagsFormat :: Mod => list_tags_for_mod (
1387+ TagsFormat :: ModResource => list_tags_for_mod_resource (
1388+ & specs,
1389+ std:: env:: var ( "OTHER_METHODS_MOD" )
1390+ . ok ( )
1391+ . as_deref ( )
1392+ . unwrap_or ( "other_methods" ) ,
1393+ ) ,
1394+ TagsFormat :: ModRest => list_tags_for_mod_rest (
13751395 & specs,
13761396 std:: env:: var ( "OTHER_METHODS_MOD" )
13771397 . ok ( )
@@ -1385,24 +1405,20 @@ fn main() {
13851405 }
13861406}
13871407
1388- fn generate_rest ( spec : & openapi:: Spec ) {
1408+ fn generate_rest ( spec : & openapi:: Spec , no_tag : bool , tag_as_kebab : Option < String > ) {
1409+ let ( add_cfg, tag_paths) = collect_tag_paths ( spec, no_tag, tag_as_kebab) ;
13891410 print ! (
1390- r###"use reqwest::header::CONTENT_LENGTH;
1391- use serde_json::Value;
1392-
1393- use super::{{*, url_enc::encode_url_param as p}};
1411+ r###"use super::*;
13941412
13951413impl<TS: KeycloakTokenSupplier> KeycloakAdmin<TS> {{
13961414"###
13971415 ) ;
13981416 let mut path_counts = spec. paths . len ( ) ;
1399- let default = std:: borrow:: Cow :: from ( "default" ) ;
1400- let tag_paths = tags_spec_paths ( spec, & default) ;
14011417 for ( tag, paths) in tag_paths {
14021418 println ! ( " // <h4>{tag}</h4>\n " ) ;
14031419
14041420 for ( path, path_spec) in paths {
1405- println ! ( "{}" , path_spec. to_rust_rest_client_method( path) ) ;
1421+ println ! ( "{}" , path_spec. to_rust_rest_client_method( path, add_cfg ) ) ;
14061422 path_counts -= 1 ;
14071423 }
14081424 }
@@ -1413,21 +1429,6 @@ impl<TS: KeycloakTokenSupplier> KeycloakAdmin<TS> {{
14131429 }
14141430}
14151431
1416- fn tags_spec_paths < ' s > (
1417- spec : & ' s openapi:: Spec < ' s > ,
1418- default : & ' s std:: borrow:: Cow < ' s , str > ,
1419- ) -> impl Iterator <
1420- Item = (
1421- & ' s std:: borrow:: Cow < ' s , str > ,
1422- Vec < ( & ' s String , & ' s openapi:: SpecPath < ' s > ) > ,
1423- ) ,
1424- > {
1425- spec. tags
1426- . iter ( )
1427- . map ( |tag| ( & tag. name , spec_paths_by_tag ( spec, & tag. name ) ) )
1428- . chain ( [ ( default, spec_paths_without_tag ( spec) ) ] )
1429- }
1430-
14311432fn spec_paths_without_tag < ' s > (
14321433 spec : & ' s openapi:: Spec < ' s > ,
14331434) -> Vec < ( & ' s String , & ' s openapi:: SpecPath < ' s > ) > {
@@ -1499,9 +1500,42 @@ pub type TypeVec<I> = Arc<[I]>;"###
14991500 }
15001501}
15011502
1503+ const DEFAULT : Cow < ' static , str > = Cow :: Borrowed ( "default" ) ;
1504+
15021505fn generate_methods ( spec : & openapi:: Spec , no_tag : bool , tag_as_kebab : Option < String > ) {
1503- let default = Cow :: from ( "default" ) ;
1506+ let ( add_cfg, tag_paths) = collect_tag_paths ( spec, no_tag, tag_as_kebab) ;
1507+
1508+ let tag_realm_methods: Vec < _ > = tag_paths
1509+ . into_iter ( )
1510+ . map ( |( tag, paths) | {
1511+ (
1512+ tag,
1513+ paths
1514+ . into_iter ( )
1515+ . flat_map ( |( path, path_spec) | path_spec. to_rust_realm_methods ( path) )
1516+ . collect :: < Vec < _ > > ( ) ,
1517+ )
1518+ } )
1519+ . collect ( ) ;
1520+
1521+ generate_method_impl ( add_cfg, & tag_realm_methods) ;
1522+
1523+ generate_method_structs ( add_cfg, & tag_realm_methods) ;
1524+
1525+ generate_method_builder ( add_cfg, & tag_realm_methods) ;
1526+ }
15041527
1528+ fn collect_tag_paths < ' s > (
1529+ spec : & ' s openapi:: Spec < ' s > ,
1530+ no_tag : bool ,
1531+ tag_as_kebab : Option < String > ,
1532+ ) -> (
1533+ bool ,
1534+ Vec < (
1535+ & ' s Cow < ' s , str > ,
1536+ Vec < ( & ' s String , & ' s openapi:: SpecPath < ' s > ) > ,
1537+ ) > ,
1538+ ) {
15051539 let tags_iter = spec. tags . iter ( ) ;
15061540 let ( tags, add_cfg) : ( Vec < _ > , _ ) = if let Some ( tag) = tag_as_kebab. as_deref ( ) {
15071541 (
@@ -1522,27 +1556,9 @@ fn generate_methods(spec: &openapi::Spec, no_tag: bool, tag_as_kebab: Option<Str
15221556 . collect ( ) ;
15231557
15241558 if no_tag || tag_as_kebab. is_none ( ) {
1525- tag_paths. extend ( [ ( & default , spec_paths_without_tag ( spec) ) ] ) ;
1559+ tag_paths. extend ( [ ( & DEFAULT , spec_paths_without_tag ( spec) ) ] ) ;
15261560 }
1527-
1528- let tag_realm_methods: Vec < _ > = tag_paths
1529- . into_iter ( )
1530- . map ( |( tag, paths) | {
1531- (
1532- tag,
1533- paths
1534- . into_iter ( )
1535- . flat_map ( |( path, path_spec) | path_spec. to_rust_realm_methods ( path) )
1536- . collect :: < Vec < _ > > ( ) ,
1537- )
1538- } )
1539- . collect ( ) ;
1540-
1541- generate_method_impl ( add_cfg, & tag_realm_methods) ;
1542-
1543- generate_method_structs ( add_cfg, & tag_realm_methods) ;
1544-
1545- generate_method_builder ( add_cfg, & tag_realm_methods) ;
1561+ ( add_cfg, tag_paths)
15461562}
15471563
15481564fn generate_method_builder ( add_cfg : bool , tag_realm_methods : & [ ( & Cow < ' _ , str > , Vec < RealmMethod > ) ] ) {
@@ -1846,7 +1862,7 @@ fn list_tags_as_kebab(spec: &openapi::Spec) {
18461862 }
18471863}
18481864
1849- fn list_tags_for_mod ( spec : & openapi:: Spec , other_methods : & str ) {
1865+ fn list_tags_for_mod_resource ( spec : & openapi:: Spec , other_methods : & str ) {
18501866 use heck:: { ToKebabCase , ToSnakeCase } ;
18511867 println ! (
18521868 "use std::{{
@@ -1871,3 +1887,22 @@ use crate::{{
18711887 println ! ( "#[cfg(feature = \" {TAG_NONE}\" )]" ) ;
18721888 println ! ( "pub mod {other_methods};" ) ;
18731889}
1890+
1891+ fn list_tags_for_mod_rest ( spec : & openapi:: Spec , other_methods : & str ) {
1892+ use heck:: { ToKebabCase , ToSnakeCase } ;
1893+ println ! (
1894+ "use reqwest::header::CONTENT_LENGTH;
1895+ use serde_json::Value;
1896+
1897+ use super::{{url_enc::encode_url_param as p, *}};
1898+ "
1899+ ) ;
1900+ for tag in & spec. tags {
1901+ println ! ( "/// {}" , tag. name) ;
1902+ println ! ( "#[cfg(feature = \" tag-{}\" )]" , tag. name. to_kebab_case( ) ) ;
1903+ println ! ( "pub mod {};" , tag. name. to_snake_case( ) ) ;
1904+ }
1905+ println ! ( "/// Other (non tagged) methods" ) ;
1906+ println ! ( "#[cfg(feature = \" {TAG_NONE}\" )]" ) ;
1907+ println ! ( "pub mod {other_methods};" ) ;
1908+ }
0 commit comments