Skip to content

Commit 1224777

Browse files
authored
feat: Split generated REST into submodules (#169)
* split generated rest into submodules * update docs
1 parent 05899c0 commit 1224777

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+14353
-14490
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,5 @@ Example: official version `13.0.1` is `13.0.100` for crate version. `13.0.102` m
9797
To update current version use provided [update.ts](./update.ts) `deno` script:
9898

9999
```sh
100-
deno run --allow-env=KEYCLOAK_RUST_VERSION,KEYCLOAK_VERSION,KEYCLOAK_RUST_MAJOR_VERSION --allow-read=Cargo.toml --allow-write=Cargo.toml,api/openapi.json,src/types.rs,src/rest/generated_rest.rs,src/resource --allow-net=keycloak.org,www.keycloak.org --allow-run=cargo,gh,git,handlebars-magic update.ts
100+
deno run --allow-env=KEYCLOAK_RUST_VERSION,KEYCLOAK_VERSION,KEYCLOAK_RUST_MAJOR_VERSION --allow-read=Cargo.toml --allow-write=Cargo.toml,api/openapi.json,src/types.rs,src/rest/generated_rest,src/resource --allow-net=keycloak.org,www.keycloak.org --allow-run=cargo,gh,git,handlebars-magic update.ts
101101
```

examples/openapi.rs

Lines changed: 88 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ struct Cli {
1515
enum 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
13951413
impl<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-
14311432
fn 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+
15021505
fn 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

15481564
fn 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+
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Example: official version `13.0.1` is `13.0.100` for crate version. `13.0.102` m
9898
To update current version use provided [update.ts](./update.ts) `deno` script:
9999
100100
```sh
101-
deno run --allow-env=KEYCLOAK_RUST_VERSION,KEYCLOAK_VERSION,KEYCLOAK_RUST_MAJOR_VERSION --allow-read=Cargo.toml --allow-write=Cargo.toml,api/openapi.json,src/types.rs,src/rest/generated_rest.rs,src/resource --allow-net=keycloak.org,www.keycloak.org --allow-run=cargo,gh,git,handlebars-magic update.ts
101+
deno run --allow-env=KEYCLOAK_RUST_VERSION,KEYCLOAK_VERSION,KEYCLOAK_RUST_MAJOR_VERSION --allow-read=Cargo.toml --allow-write=Cargo.toml,api/openapi.json,src/types.rs,src/rest/generated_rest,src/resource --allow-net=keycloak.org,www.keycloak.org --allow-run=cargo,gh,git,handlebars-magic update.ts
102102
```
103103
104104
*/

src/resource/attack_detection.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ impl<'a, TS: KeycloakTokenSupplier> KeycloakRealmAdmin<'a, TS> {
1414
///
1515
/// `DELETE /admin/realms/{realm}/attack-detection/brute-force/users`
1616
///
17-
/// Documentation: <https://www.keycloak.org/docs-api/26.3.1/rest-api/index.html#_delete_adminrealmsrealmattack_detectionbrute_forceusers>
17+
/// Documentation: <https://www.keycloak.org/docs-api/26.3.2/rest-api/index.html#_delete_adminrealmsrealmattack_detectionbrute_forceusers>
1818
pub fn attack_detection_brute_force_users_delete(
1919
&'a self,
2020
) -> impl Future<Output = Result<DefaultResponse, KeycloakError>> + use<'a, TS> {
@@ -33,7 +33,7 @@ impl<'a, TS: KeycloakTokenSupplier> KeycloakRealmAdmin<'a, TS> {
3333
///
3434
/// `GET /admin/realms/{realm}/attack-detection/brute-force/users/{user_id}`
3535
///
36-
/// Documentation: <https://www.keycloak.org/docs-api/26.3.1/rest-api/index.html#_get_adminrealmsrealmattack_detectionbrute_forceusersuserid>
36+
/// Documentation: <https://www.keycloak.org/docs-api/26.3.2/rest-api/index.html#_get_adminrealmsrealmattack_detectionbrute_forceusersuserid>
3737
///
3838
/// REST method: `GET /admin/realms/{realm}/attack-detection/brute-force/users/{userId}`
3939
pub fn attack_detection_brute_force_users_with_user_id_get(
@@ -57,7 +57,7 @@ impl<'a, TS: KeycloakTokenSupplier> KeycloakRealmAdmin<'a, TS> {
5757
///
5858
/// `DELETE /admin/realms/{realm}/attack-detection/brute-force/users/{user_id}`
5959
///
60-
/// Documentation: <https://www.keycloak.org/docs-api/26.3.1/rest-api/index.html#_delete_adminrealmsrealmattack_detectionbrute_forceusersuserid>
60+
/// Documentation: <https://www.keycloak.org/docs-api/26.3.2/rest-api/index.html#_delete_adminrealmsrealmattack_detectionbrute_forceusersuserid>
6161
///
6262
/// REST method: `DELETE /admin/realms/{realm}/attack-detection/brute-force/users/{userId}`
6363
pub fn attack_detection_brute_force_users_with_user_id_delete(

0 commit comments

Comments
 (0)