From 51c8829dd1cc0aa04670d4185e406c55070a44d5 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Sat, 8 Jul 2023 21:23:26 -0400 Subject: [PATCH 01/13] basic sdk root module generator --- Cargo.lock | 797 ++++++++++++++---- crates/cloudtruth-sdk-codegen/Cargo.toml | 17 + crates/cloudtruth-sdk-codegen/src/lib.rs | 19 + crates/cloudtruth-sdk-codegen/src/main.rs | 5 + crates/cloudtruth-sdk-codegen/src/method.rs | 55 ++ crates/cloudtruth-sdk-codegen/src/modules.rs | 41 + .../src/modules/root.rs | 27 + crates/cloudtruth-sdk/Cargo.toml | 10 + crates/cloudtruth-sdk/src/lib.rs | 16 + crates/cloudtruth-sdk/src/main.rs | 3 + 10 files changed, 844 insertions(+), 146 deletions(-) create mode 100644 crates/cloudtruth-sdk-codegen/Cargo.toml create mode 100644 crates/cloudtruth-sdk-codegen/src/lib.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/main.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/method.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/modules.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/modules/root.rs create mode 100644 crates/cloudtruth-sdk/Cargo.toml create mode 100644 crates/cloudtruth-sdk/src/lib.rs create mode 100644 crates/cloudtruth-sdk/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index b21dabae..0aae2b24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,11 +65,20 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" dependencies = [ - "memchr", + "memchr 0.1.11", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr 2.5.0", ] [[package]] @@ -102,11 +111,17 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +[[package]] +name = "anstyle" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" + [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "askama" @@ -162,7 +177,7 @@ version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0b2340f55d9661d76793b2bfc2eb0e62689bd79d067a95707ea762afd5e9dd" dependencies = [ - "anstyle", + "anstyle 0.3.5", "bstr", "doc-comment", "predicates", @@ -177,6 +192,19 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-compression" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0122885821398cc923ece939e24d1056a2384ee719432397fa9db87230ff11" +dependencies = [ + "flate2", + "futures-core", + "memchr 2.5.0", + "pin-project-lite", + "tokio 1.26.0", +] + [[package]] name = "atty" version = "0.2.14" @@ -218,6 +246,15 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "base64" version = "0.10.1" @@ -233,12 +270,24 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "block-buffer" version = "0.9.0" @@ -254,9 +303,9 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" dependencies = [ - "memchr", + "memchr 2.5.0", "once_cell", - "regex-automata", + "regex-automata 0.1.10", "serde", ] @@ -380,7 +429,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim", "textwrap 0.11.0", "unicode-width", @@ -389,36 +438,42 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.13" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c911b090850d79fc64fe9ea01e28e465f65e821e08813ced95bced72f7a8a9b" +checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", - "clap_lex", "once_cell", ] +[[package]] +name = "clap_builder" +version = "4.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +dependencies = [ + "anstyle 1.0.1", + "clap_lex", +] + [[package]] name = "clap_derive" -version = "4.1.12" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a932373bab67b984c790ddf2c9ca295d8e3af3b7ef92de5a5bacdccdee4b09b" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.23", ] [[package]] name = "clap_lex" -version = "0.3.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" -dependencies = [ - "os_str_bytes", -] +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "cloudabi" @@ -426,7 +481,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -456,7 +511,7 @@ dependencies = [ "powershell_script 0.2.1", "prettytable-rs", "rand_core 0.6.4", - "reqwest", + "reqwest 0.9.24", "rpassword", "rusty-hook", "serde", @@ -495,7 +550,7 @@ name = "cloudtruth-installer" version = "1.2.3" dependencies = [ "powershell_script 1.0.4", - "reqwest", + "reqwest 0.9.24", "serde_json", "tempfile", ] @@ -504,13 +559,36 @@ dependencies = [ name = "cloudtruth-restapi" version = "1.0.0" dependencies = [ - "reqwest", + "reqwest 0.9.24", "serde", "serde_derive", "serde_json", "url 2.3.1", ] +[[package]] +name = "cloudtruth-sdk" +version = "0.1.0" +dependencies = [ + "once_cell", + "reqwest 0.11.18", +] + +[[package]] +name = "cloudtruth-sdk-codegen" +version = "0.1.0" +dependencies = [ + "color-eyre 0.6.2", + "http 0.2.9", + "indexmap 1.9.2", + "openapiv3", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.23", + "uritemplate", +] + [[package]] name = "cloudtruth-test-harness" version = "1.2.3" @@ -541,7 +619,7 @@ version = "1.2.3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.23", ] [[package]] @@ -615,7 +693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes 1.4.0", - "memchr", + "memchr 2.5.0", ] [[package]] @@ -624,7 +702,7 @@ version = "0.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7b3e3c41e9488eeda196b6806dbf487742107d61b2e16485bcca6c25ed5755b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "concolor-query", "is-terminal", ] @@ -661,7 +739,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" dependencies = [ - "memchr", + "memchr 2.5.0", ] [[package]] @@ -851,7 +929,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "memchr", + "memchr 2.5.0", ] [[package]] @@ -920,7 +998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ "cfg-if 1.0.0", - "hashbrown", + "hashbrown 0.12.3", "lock_api 0.4.9", "once_cell", "parking_lot_core 0.9.7", @@ -1094,7 +1172,7 @@ dependencies = [ "atty", "humantime", "log", - "regex", + "regex 1.9.1", "termcolor", ] @@ -1105,19 +1183,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2d328fc287c61314c4a61af7cfdcbd7e678e39778488c7cb13ec133ce0f4059" dependencies = [ "fsio", - "indexmap", + "indexmap 1.9.2", ] [[package]] -name = "errno" -version = "0.2.8" +name = "equivalent" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi 0.3.9", -] +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" [[package]] name = "errno" @@ -1260,7 +1333,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags", + "bitflags 1.3.2", "fuchsia-zircon-sys", ] @@ -1303,9 +1376,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-cpupool" @@ -1369,7 +1442,7 @@ dependencies = [ "futures-macro", "futures-sink", "futures-task", - "memchr", + "memchr 2.5.0", "pin-project-lite", "pin-utils", "slab", @@ -1437,14 +1510,33 @@ dependencies = [ "bytes 0.4.12", "fnv", "futures 0.1.31", - "http", - "indexmap", + "http 0.1.21", + "indexmap 1.9.2", "log", "slab", "string", "tokio-io", ] +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +dependencies = [ + "bytes 1.4.0", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.9", + "indexmap 1.9.2", + "slab", + "tokio 1.26.0", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1454,6 +1546,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -1521,6 +1619,17 @@ dependencies = [ "itoa 0.4.8", ] +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes 1.4.0", + "fnv", + "itoa 1.0.5", +] + [[package]] name = "http-body" version = "0.1.0" @@ -1529,16 +1638,33 @@ checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ "bytes 0.4.12", "futures 0.1.31", - "http", + "http 0.1.21", "tokio-buf", ] +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes 1.4.0", + "http 0.2.9", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + [[package]] name = "humansize" version = "1.1.1" @@ -1570,9 +1696,9 @@ dependencies = [ "bytes 0.4.12", "futures 0.1.31", "futures-cpupool", - "h2", - "http", - "http-body", + "h2 0.1.26", + "http 0.1.21", + "http-body 0.1.0", "httparse", "iovec", "itoa 0.4.8", @@ -1588,7 +1714,45 @@ dependencies = [ "tokio-tcp", "tokio-threadpool", "tokio-timer", - "want", + "want 0.2.0", +] + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes 1.4.0", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.20", + "http 0.2.9", + "http-body 0.4.5", + "httparse", + "httpdate", + "itoa 1.0.5", + "pin-project-lite", + "socket2", + "tokio 1.26.0", + "tower-service", + "tracing", + "want 0.3.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http 0.2.9", + "hyper 0.14.27", + "rustls", + "tokio 1.26.0", + "tokio-rustls", ] [[package]] @@ -1599,11 +1763,24 @@ checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" dependencies = [ "bytes 0.4.12", "futures 0.1.31", - "hyper", + "hyper 0.12.36", "native-tls", "tokio-io", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes 1.4.0", + "hyper 0.14.27", + "native-tls", + "tokio 1.26.0", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.53" @@ -1673,7 +1850,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg 1.1.0", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", ] [[package]] @@ -1716,16 +1904,21 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.1", - "io-lifetimes", - "rustix 0.36.8", - "windows-sys 0.45.0", + "rustix 0.38.3", + "windows-sys 0.48.0", ] [[package]] @@ -1802,9 +1995,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "link-cplusplus" @@ -1823,15 +2016,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" @@ -1888,6 +2081,15 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +[[package]] +name = "memchr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" +dependencies = [ + "libc", +] + [[package]] name = "memchr" version = "2.5.0" @@ -1914,11 +2116,12 @@ dependencies = [ [[package]] name = "miette" -version = "5.6.0" +version = "5.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07749fb52853e739208049fb513287c6f448de9103dfa78b05ae01f2fc5809bb" +checksum = "a236ff270093b0b67451bc50a509bd1bad302cb1d3c7d37d5efe931238581fa9" dependencies = [ "backtrace", + "backtrace-ext", "is-terminal", "miette-derive", "once_cell", @@ -1934,13 +2137,13 @@ dependencies = [ [[package]] name = "miette-derive" -version = "5.6.0" +version = "5.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a07ad93a80d1b92bb44cb42d7c49b49c9aab1778befefad49cceb5e4c5bf460" +checksum = "4901771e1d44ddb37964565c654a3223ba41a594d02b8da471cc4464912b5cfa" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.23", ] [[package]] @@ -1993,6 +2196,18 @@ dependencies = [ "winapi 0.2.8", ] +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + [[package]] name = "miow" version = "0.2.2" @@ -2052,7 +2267,7 @@ version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "memchr", + "memchr 2.5.0", "minimal-lexical", ] @@ -2096,14 +2311,14 @@ version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ - "memchr", + "memchr 2.5.0", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -2111,13 +2326,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openapiv3" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1a9f106eb0a780abd17ba9fca8e0843e3461630bcbe2af0ad4d5d3ba4e9aa4" +dependencies = [ + "indexmap 1.9.2", + "serde", + "serde_json", +] + [[package]] name = "openssl" version = "0.10.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "foreign-types", "libc", @@ -2176,12 +2402,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "os_str_bytes" -version = "6.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" - [[package]] name = "owo-colors" version = "1.3.0" @@ -2345,13 +2565,13 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c575290b64d24745b6c57a12a31465f0a66f3a4799686a6921526a33b0797965" dependencies = [ - "anstyle", + "anstyle 0.3.5", "difflib", "float-cmp", "itertools", "normalize-line-endings", "predicates-core", - "regex", + "regex 1.9.1", ] [[package]] @@ -2386,9 +2606,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.54" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] @@ -2405,9 +2625,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -2600,7 +2820,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -2609,7 +2829,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -2625,13 +2845,27 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" +dependencies = [ + "aho-corasick 0.5.3", + "memchr 0.1.11", + "regex-syntax 0.3.9", + "thread_local 0.2.7", + "utf8-ranges", +] + +[[package]] +name = "regex" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "aho-corasick 1.0.2", + "memchr 2.5.0", + "regex-automata 0.3.2", + "regex-syntax 0.7.3", ] [[package]] @@ -2640,11 +2874,28 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +dependencies = [ + "aho-corasick 1.0.2", + "memchr 2.5.0", + "regex-syntax 0.7.3", +] + +[[package]] +name = "regex-syntax" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" + [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "reqwest" @@ -2659,16 +2910,16 @@ dependencies = [ "encoding_rs", "flate2", "futures 0.1.31", - "http", - "hyper", - "hyper-tls", + "http 0.1.21", + "hyper 0.12.36", + "hyper-tls 0.3.2", "log", "mime", "mime_guess", "native-tls", "serde", "serde_json", - "serde_urlencoded", + "serde_urlencoded 0.5.5", "time", "tokio 0.1.22", "tokio-executor", @@ -2677,7 +2928,66 @@ dependencies = [ "tokio-timer", "url 1.7.2", "uuid 0.7.4", - "winreg", + "winreg 0.6.2", +] + +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "async-compression", + "base64 0.21.2", + "bytes 1.4.0", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.20", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-rustls", + "hyper-tls 0.5.0", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding 2.2.0", + "pin-project-lite", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded 0.7.1", + "tokio 1.26.0", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url 2.3.1", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.10.1", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi 0.3.9", ] [[package]] @@ -2716,30 +3026,72 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.8" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" dependencies = [ - "bitflags", - "errno 0.2.8", + "bitflags 1.3.2", + "errno", "io-lifetimes", "libc", - "linux-raw-sys 0.1.4", + "linux-raw-sys 0.3.1", "windows-sys 0.45.0", ] [[package]] name = "rustix" -version = "0.37.3" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" dependencies = [ - "bitflags", - "errno 0.3.1", - "io-lifetimes", + "bitflags 2.3.3", + "errno", "libc", - "linux-raw-sys 0.3.1", - "windows-sys 0.45.0", + "linux-raw-sys 0.4.3", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.2", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +dependencies = [ + "ring", + "untrusted", ] [[package]] @@ -2796,13 +3148,23 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2842,29 +3204,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.23", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa 1.0.5", "ryu", @@ -2882,9 +3244,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -2901,13 +3263,25 @@ dependencies = [ "url 1.7.2", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.5", + "ryu", + "serde", +] + [[package]] name = "serde_yaml" version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ - "indexmap", + "indexmap 1.9.2", "ryu", "serde", "yaml-rust", @@ -2919,7 +3293,7 @@ version = "0.9.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82e6c8c047aa50a7328632d067bcae6ef38772a79e28daf32f735e0e4f3dd10" dependencies = [ - "indexmap", + "indexmap 1.9.2", "itoa 1.0.5", "ryu", "serde", @@ -3075,6 +3449,22 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaaf09df9f0eeae82be96290918520214530e738a7fe5a351b0f24cf77c0ca31" +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "string" version = "0.2.1" @@ -3148,9 +3538,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.12" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -3255,7 +3645,26 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.12", + "syn 2.0.23", +] + +[[package]] +name = "thread-id" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" +dependencies = [ + "kernel32-sys", + "libc", +] + +[[package]] +name = "thread_local" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" +dependencies = [ + "thread-id", ] [[package]] @@ -3302,7 +3711,7 @@ checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" dependencies = [ "bytes 0.4.12", "futures 0.1.31", - "mio", + "mio 0.6.23", "num_cpus", "tokio-current-thread", "tokio-executor", @@ -3320,8 +3729,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" dependencies = [ "autocfg 1.1.0", + "bytes 1.4.0", + "libc", + "memchr 2.5.0", + "mio 0.8.8", "num_cpus", "pin-project-lite", + "socket2", "tokio-macros", "windows-sys 0.45.0", ] @@ -3379,6 +3793,16 @@ dependencies = [ "syn 1.0.107", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio 1.26.0", +] + [[package]] name = "tokio-reactor" version = "0.1.12" @@ -3389,7 +3813,7 @@ dependencies = [ "futures 0.1.31", "lazy_static", "log", - "mio", + "mio 0.6.23", "num_cpus", "parking_lot 0.9.0", "slab", @@ -3398,6 +3822,16 @@ dependencies = [ "tokio-sync", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio 1.26.0", +] + [[package]] name = "tokio-stream" version = "0.1.12" @@ -3428,7 +3862,7 @@ dependencies = [ "bytes 0.4.12", "futures 0.1.31", "iovec", - "mio", + "mio 0.6.23", "tokio-io", "tokio-reactor", ] @@ -3462,6 +3896,20 @@ dependencies = [ "tokio-executor", ] +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes 1.4.0", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio 1.26.0", + "tracing", +] + [[package]] name = "toml" version = "0.5.11" @@ -3473,26 +3921,32 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.8" +version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -3553,7 +4007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ "sharded-slab", - "thread_local", + "thread_local 1.1.7", "tracing-core", ] @@ -3564,7 +4018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ "sharded-slab", - "thread_local", + "thread_local 1.1.7", "tracing-core", ] @@ -3622,9 +4076,9 @@ checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-linebreak" @@ -3632,8 +4086,8 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" dependencies = [ - "hashbrown", - "regex", + "hashbrown 0.12.3", + "regex 1.9.1", ] [[package]] @@ -3673,6 +4127,21 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad2024452afd3874bf539695e04af6732ba06517424dbf958fdb16a01f3bef6c" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "uritemplate" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01eaa32c7380d40c2fd400fb0a95e394b6c40632ca4bcb4bc1683f0fbbf22749" +dependencies = [ + "regex 0.1.80", +] + [[package]] name = "url" version = "1.7.2" @@ -3701,6 +4170,12 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" +[[package]] +name = "utf8-ranges" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" + [[package]] name = "uuid" version = "0.7.4" @@ -3781,6 +4256,15 @@ dependencies = [ "try-lock", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -3818,6 +4302,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.84" @@ -4077,11 +4573,11 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.1" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" dependencies = [ - "memchr", + "memchr 2.5.0", ] [[package]] @@ -4093,6 +4589,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -4109,7 +4614,7 @@ version = "0.1.0" dependencies = [ "anyhow", "askama", - "clap 4.1.13", + "clap 4.3.11", "duct", "futures 0.3.27", "itertools", diff --git a/crates/cloudtruth-sdk-codegen/Cargo.toml b/crates/cloudtruth-sdk-codegen/Cargo.toml new file mode 100644 index 00000000..c836451b --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "cloudtruth-sdk-codegen" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +color-eyre = "0.6.2" +http = "0.2.9" +indexmap = "1" +openapiv3 = { version = "1" } +proc-macro2 = "1.0.63" +quote = "1.0.29" +serde_json = "1.0" +syn = "2.0.23" +uritemplate = "0.1.2" diff --git a/crates/cloudtruth-sdk-codegen/src/lib.rs b/crates/cloudtruth-sdk-codegen/src/lib.rs new file mode 100644 index 00000000..12232e04 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/lib.rs @@ -0,0 +1,19 @@ +mod method; +mod modules; + +use color_eyre::Result; +use openapiv3::OpenAPI; + +use crate::method::SdkOperation; + +pub fn generate_sdk() -> Result<()> { + let data = include_str!("../../../openapi.json"); + let openapi: OpenAPI = serde_json::from_str(data).unwrap(); + let _methods = openapi + .operations() + .filter(|(path, _, _)| path.starts_with("/api/v1/integrations/azure/key_vault/")) + .map(|(path, method, op)| SdkOperation::from_openapi_operation(path, method, op.clone())) + .collect::>(); + modules::root().write()?; + Ok(()) +} diff --git a/crates/cloudtruth-sdk-codegen/src/main.rs b/crates/cloudtruth-sdk-codegen/src/main.rs new file mode 100644 index 00000000..a8db262d --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/main.rs @@ -0,0 +1,5 @@ +use color_eyre::Result; +fn main() -> Result<()> { + color_eyre::install()?; + cloudtruth_sdk_codegen::generate_sdk() +} diff --git a/crates/cloudtruth-sdk-codegen/src/method.rs b/crates/cloudtruth-sdk-codegen/src/method.rs new file mode 100644 index 00000000..b264e453 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/method.rs @@ -0,0 +1,55 @@ +use color_eyre::Result; +use indexmap::IndexMap; +use openapiv3::{Operation, Parameter, RequestBody, Responses}; + +use uritemplate::UriTemplate; + +pub struct SdkOperation { + pub path_template: UriTemplate, + pub http_method: http::Method, + pub summary: Option, + pub description: Option, + pub operation_id: Option, + pub tags: Vec, + pub deprecated: bool, + pub request_body: Option, + pub parameters: Vec, + pub responses: Responses, + pub security: Option>>>, +} + +impl SdkOperation { + pub fn from_openapi_operation(path: &str, method: &str, op: Operation) -> Result { + let Operation { + description, + summary, + operation_id, + tags, + request_body, + parameters, + responses, + deprecated, + security, + .. + } = op; + let request_body = request_body.map(|b| b.into_item().unwrap()); + let parameters: Vec = parameters + .into_iter() + .map(|p| p.into_item().unwrap()) + .collect(); + + Ok(SdkOperation { + path_template: UriTemplate::new(path), + http_method: method.parse()?, + description, + summary, + operation_id, + tags, + deprecated, + request_body, + parameters, + responses, + security, + }) + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/modules.rs b/crates/cloudtruth-sdk-codegen/src/modules.rs new file mode 100644 index 00000000..8d52e638 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/modules.rs @@ -0,0 +1,41 @@ +mod root; + +pub use root::root; + +use std::{borrow::Cow, fs::File, io::Write, path::Path, process::Command}; + +use color_eyre::{eyre::Context, Result}; +use proc_macro2::TokenStream; + +#[macro_export] +macro_rules! sdk_path { + ($($path:expr),* $(,)?) => { + std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../cloudtruth-sdk/", $($path),*)) + }; +} + +#[derive(Debug, Clone)] +pub struct SdkModule { + path: Cow<'static, Path>, + tokens: TokenStream, +} + +impl SdkModule { + pub fn new(path: impl Into>, tokens: impl Into) -> Self { + SdkModule { + path: path.into(), + tokens: tokens.into(), + } + } + + pub fn write(&self) -> Result<()> { + File::create(self.path.as_ref()) + .with_context(move || format!("Could not open: {}", self.path.display()))? + .write_all(self.tokens.to_string().as_bytes())?; + Command::new("rustfmt") + .arg(self.path.as_os_str()) + .spawn()? + .wait()?; + Ok(()) + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/modules/root.rs b/crates/cloudtruth-sdk-codegen/src/modules/root.rs new file mode 100644 index 00000000..d669f9f5 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/modules/root.rs @@ -0,0 +1,27 @@ +use super::SdkModule; +use crate::sdk_path; +use quote::quote; + +pub fn root() -> SdkModule { + SdkModule::new( + sdk_path!("src/lib.rs"), + quote! { + use once_cell::sync::OnceCell; + use reqwest::Client; + + pub struct CloudtruthSdk { + pub client: Client + } + + impl CloudtruthSdk { + fn new() -> CloudtruthSdk { + CloudtruthSdk { client: Client::new() } + } + pub fn instance() -> &'static CloudtruthSdk { + static ONCE: OnceCell = OnceCell::new(); + ONCE.get_or_init(CloudtruthSdk::new) + } + } + }, + ) +} diff --git a/crates/cloudtruth-sdk/Cargo.toml b/crates/cloudtruth-sdk/Cargo.toml new file mode 100644 index 00000000..6dafcafb --- /dev/null +++ b/crates/cloudtruth-sdk/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "cloudtruth-sdk" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +once_cell = "1.18.0" +reqwest = { version = "0.11.18", features = ["rustls-tls-native-roots", "json", "gzip"] } diff --git a/crates/cloudtruth-sdk/src/lib.rs b/crates/cloudtruth-sdk/src/lib.rs new file mode 100644 index 00000000..bd484210 --- /dev/null +++ b/crates/cloudtruth-sdk/src/lib.rs @@ -0,0 +1,16 @@ +use once_cell::sync::OnceCell; +use reqwest::Client; +pub struct CloudtruthSdk { + pub client: Client, +} +impl CloudtruthSdk { + fn new() -> CloudtruthSdk { + CloudtruthSdk { + client: Client::new(), + } + } + pub fn instance() -> &'static CloudtruthSdk { + static ONCE: OnceCell = OnceCell::new(); + ONCE.get_or_init(CloudtruthSdk::new) + } +} diff --git a/crates/cloudtruth-sdk/src/main.rs b/crates/cloudtruth-sdk/src/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/crates/cloudtruth-sdk/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 74a5d53b7b278c2cde3bbf1a9001766bd15a4b48 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Sun, 9 Jul 2023 16:36:54 -0400 Subject: [PATCH 02/13] initial attempt at building sdk object tree --- Cargo.lock | 205 ++++++++++-------- crates/cloudtruth-sdk-codegen/Cargo.toml | 2 +- crates/cloudtruth-sdk-codegen/src/api.rs | 5 + .../src/api/operation.rs | 84 +++++++ crates/cloudtruth-sdk-codegen/src/api/spec.rs | 25 +++ .../cloudtruth-sdk-codegen/src/generator.rs | 87 ++++++++ crates/cloudtruth-sdk-codegen/src/lib.rs | 20 +- crates/cloudtruth-sdk-codegen/src/method.rs | 55 ----- crates/cloudtruth-sdk-codegen/src/modules.rs | 5 + .../src/modules/root.rs | 27 --- crates/cloudtruth-sdk-codegen/src/sdk.rs | 4 + .../cloudtruth-sdk-codegen/src/sdk/methods.rs | 23 ++ .../src/sdk/methods/api_method.rs | 24 ++ .../src/sdk/methods/child_constructor.rs | 23 ++ .../src/sdk/methods/root_constructors.rs | 46 ++++ .../cloudtruth-sdk-codegen/src/sdk/object.rs | 64 ++++++ crates/cloudtruth-sdk/src/lib.rs | 8 +- 17 files changed, 516 insertions(+), 191 deletions(-) create mode 100644 crates/cloudtruth-sdk-codegen/src/api.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/api/operation.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/api/spec.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/generator.rs delete mode 100644 crates/cloudtruth-sdk-codegen/src/method.rs delete mode 100644 crates/cloudtruth-sdk-codegen/src/modules/root.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/methods.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/object.rs diff --git a/Cargo.lock b/Cargo.lock index 0aae2b24..5d4820ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,22 +63,13 @@ dependencies = [ "version_check", ] -[[package]] -name = "aho-corasick" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" -dependencies = [ - "memchr 0.1.11", -] - [[package]] name = "aho-corasick" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ - "memchr 2.5.0", + "memchr", ] [[package]] @@ -123,6 +114,12 @@ version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "askama" version = "0.11.1" @@ -161,7 +158,7 @@ dependencies = [ "humansize", "mime", "mime_guess", - "nom", + "nom 7.1.3", "num-traits", "percent-encoding 2.2.0", "proc-macro2", @@ -200,7 +197,7 @@ checksum = "5b0122885821398cc923ece939e24d1056a2384ee719432397fa9db87230ff11" dependencies = [ "flate2", "futures-core", - "memchr 2.5.0", + "memchr", "pin-project-lite", "tokio 1.26.0", ] @@ -288,6 +285,18 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +[[package]] +name = "bitvec" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -303,7 +312,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d4260bcc2e8fc9df1eac4919a720effeb63a3f0952f5bf4944adfa18897f09" dependencies = [ - "memchr 2.5.0", + "memchr", "once_cell", "regex-automata 0.1.10", "serde", @@ -584,9 +593,9 @@ dependencies = [ "openapiv3", "proc-macro2", "quote", + "rfc6570-level-2", "serde_json", "syn 2.0.23", - "uritemplate", ] [[package]] @@ -693,7 +702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes 1.4.0", - "memchr 2.5.0", + "memchr", ] [[package]] @@ -739,7 +748,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" dependencies = [ - "memchr 2.5.0", + "memchr", ] [[package]] @@ -929,7 +938,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "memchr 2.5.0", + "memchr", ] [[package]] @@ -1172,7 +1181,7 @@ dependencies = [ "atty", "humantime", "log", - "regex 1.9.1", + "regex", "termcolor", ] @@ -1343,6 +1352,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "futures" version = "0.1.31" @@ -1442,7 +1457,7 @@ dependencies = [ "futures-macro", "futures-sink", "futures-task", - "memchr 2.5.0", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -1993,6 +2008,19 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec", + "bitflags 1.3.2", + "cfg-if 1.0.0", + "ryu", + "static_assertions", +] + [[package]] name = "libc" version = "0.2.147" @@ -2081,15 +2109,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -[[package]] -name = "memchr" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -dependencies = [ - "libc", -] - [[package]] name = "memchr" version = "2.5.0" @@ -2261,13 +2280,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0" +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec", + "funty", + "lexical-core", + "memchr", + "version_check", +] + [[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "memchr 2.5.0", + "memchr", "minimal-lexical", ] @@ -2311,7 +2343,7 @@ version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ - "memchr 2.5.0", + "memchr", ] [[package]] @@ -2571,7 +2603,7 @@ dependencies = [ "itertools", "normalize-line-endings", "predicates-core", - "regex 1.9.1", + "regex", ] [[package]] @@ -2632,6 +2664,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + [[package]] name = "rand" version = "0.6.5" @@ -2843,29 +2881,16 @@ dependencies = [ "thiserror", ] -[[package]] -name = "regex" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" -dependencies = [ - "aho-corasick 0.5.3", - "memchr 0.1.11", - "regex-syntax 0.3.9", - "thread_local 0.2.7", - "utf8-ranges", -] - [[package]] name = "regex" version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ - "aho-corasick 1.0.2", - "memchr 2.5.0", + "aho-corasick", + "memchr", "regex-automata 0.3.2", - "regex-syntax 0.7.3", + "regex-syntax", ] [[package]] @@ -2880,17 +2905,11 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" dependencies = [ - "aho-corasick 1.0.2", - "memchr 2.5.0", - "regex-syntax 0.7.3", + "aho-corasick", + "memchr", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" - [[package]] name = "regex-syntax" version = "0.7.3" @@ -2975,6 +2994,18 @@ dependencies = [ "winreg 0.10.1", ] +[[package]] +name = "rfc6570-level-2" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bf3499b472ff2440e1618280298a37b8b1bc15e6d494b50cdf8f400dd66edd" +dependencies = [ + "anyhow", + "itertools", + "nom 6.1.2", + "percent-encoding 2.2.0", +] + [[package]] name = "ring" version = "0.16.20" @@ -3465,6 +3496,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "string" version = "0.2.1" @@ -3559,6 +3596,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.5.0" @@ -3648,25 +3691,6 @@ dependencies = [ "syn 2.0.23", ] -[[package]] -name = "thread-id" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -dependencies = [ - "kernel32-sys", - "libc", -] - -[[package]] -name = "thread_local" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" -dependencies = [ - "thread-id", -] - [[package]] name = "thread_local" version = "1.1.7" @@ -3731,7 +3755,7 @@ dependencies = [ "autocfg 1.1.0", "bytes 1.4.0", "libc", - "memchr 2.5.0", + "memchr", "mio 0.8.8", "num_cpus", "pin-project-lite", @@ -4007,7 +4031,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ "sharded-slab", - "thread_local 1.1.7", + "thread_local", "tracing-core", ] @@ -4018,7 +4042,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ "sharded-slab", - "thread_local 1.1.7", + "thread_local", "tracing-core", ] @@ -4087,7 +4111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" dependencies = [ "hashbrown 0.12.3", - "regex 1.9.1", + "regex", ] [[package]] @@ -4133,15 +4157,6 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "uritemplate" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01eaa32c7380d40c2fd400fb0a95e394b6c40632ca4bcb4bc1683f0fbbf22749" -dependencies = [ - "regex 0.1.80", -] - [[package]] name = "url" version = "1.7.2" @@ -4170,12 +4185,6 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" -[[package]] -name = "utf8-ranges" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" - [[package]] name = "uuid" version = "0.7.4" @@ -4577,7 +4586,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" dependencies = [ - "memchr 2.5.0", + "memchr", ] [[package]] @@ -4608,6 +4617,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + [[package]] name = "xtask" version = "0.1.0" diff --git a/crates/cloudtruth-sdk-codegen/Cargo.toml b/crates/cloudtruth-sdk-codegen/Cargo.toml index c836451b..f8266d86 100644 --- a/crates/cloudtruth-sdk-codegen/Cargo.toml +++ b/crates/cloudtruth-sdk-codegen/Cargo.toml @@ -14,4 +14,4 @@ proc-macro2 = "1.0.63" quote = "1.0.29" serde_json = "1.0" syn = "2.0.23" -uritemplate = "0.1.2" +rfc6570-level-2 = "1.2.0" \ No newline at end of file diff --git a/crates/cloudtruth-sdk-codegen/src/api.rs b/crates/cloudtruth-sdk-codegen/src/api.rs new file mode 100644 index 00000000..da3c8cf4 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/api.rs @@ -0,0 +1,5 @@ +mod operation; +mod spec; + +pub use operation::ApiOperation; +pub use spec::ApiSpec; diff --git a/crates/cloudtruth-sdk-codegen/src/api/operation.rs b/crates/cloudtruth-sdk-codegen/src/api/operation.rs new file mode 100644 index 00000000..8f371970 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/api/operation.rs @@ -0,0 +1,84 @@ +use color_eyre::{eyre::eyre, Result}; +use indexmap::IndexMap; +use openapiv3::{Operation, Parameter, RequestBody, Responses}; + +use rfc6570_level_2::UriTemplate; + +#[derive(Debug, Clone)] +pub struct ApiOperation { + path_template: UriTemplate, + http_method: http::Method, + summary: Option, + description: Option, + operation_id: Option, + tags: Vec, + deprecated: bool, + request_body: Option, + parameters: Vec, + responses: Responses, + security: Option>>>, +} + +impl ApiOperation { + pub fn from_openapi(path: &str, method: &str, op: Operation) -> Result { + let Operation { + description, + summary, + operation_id, + tags, + request_body, + parameters, + responses, + deprecated, + security, + .. + } = op; + let request_body = request_body.map(|b| b.into_item().unwrap()); + let parameters: Vec = parameters + .into_iter() + .map(|p| p.into_item().unwrap()) + .collect(); + + Ok(ApiOperation { + path_template: UriTemplate::new(path).map_err(|err| eyre!(Box::new(err)))?, // convert anyhow to eyre + http_method: method.parse()?, + description, + summary, + operation_id, + tags, + deprecated, + request_body, + parameters, + responses, + security, + }) + } + + pub fn uri(&self) -> &str { + self.path_template.uri() + } + + pub fn http_method(&self) -> &http::Method { + &self.http_method + } + + pub fn summary(&self) -> Option<&str> { + self.summary.as_deref() + } + + pub fn description(&self) -> Option<&str> { + self.description.as_deref() + } + + pub fn operation_id(&self) -> Option<&str> { + self.operation_id.as_deref() + } + + pub fn tags(&self) -> &[String] { + self.tags.as_ref() + } + + pub fn deprecated(&self) -> bool { + self.deprecated + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/api/spec.rs b/crates/cloudtruth-sdk-codegen/src/api/spec.rs new file mode 100644 index 00000000..a63843bd --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/api/spec.rs @@ -0,0 +1,25 @@ +use color_eyre::Result; +use openapiv3::OpenAPI; + +use crate::api::ApiOperation; + +#[derive(Debug, Clone)] +pub struct ApiSpec { + operations: Vec, +} + +impl ApiSpec { + pub fn new(open_api: OpenAPI) -> Result { + let mut operations = open_api + .operations() + .filter(|(path, _, _)| path.starts_with("/api/v1/integrations/azure/key_vault/")) + .map(|(path, method, op)| ApiOperation::from_openapi(path, method, op.clone())) + .collect::>>()?; + operations.sort_by(|a, b| a.uri().cmp(b.uri())); + Ok(Self { operations }) + } + + pub fn operations(&self) -> &[ApiOperation] { + &self.operations + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs new file mode 100644 index 00000000..63f04778 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -0,0 +1,87 @@ +use std::{borrow::BorrowMut, cell::RefCell}; + +use crate::{ + api::{ApiOperation, ApiSpec}, + sdk::{ + methods::{SdkRootConstructor, SdkStaticRootConstructor}, + SdkObject, + }, +}; + +pub struct SdkGenerator { + spec: ApiSpec, + root_prefix: String, +} + +impl SdkGenerator { + pub fn new(spec: ApiSpec) -> Self { + Self { + spec, + root_prefix: String::new(), + } + } + + pub fn spec(&self) -> &ApiSpec { + &self.spec + } + + pub fn root_prefix(&mut self, prefix: impl Into) -> &mut Self { + self.root_prefix = prefix.into(); + self + } + + fn build_root_object<'a>(&'a self) -> SdkObject<'a> { + let mut root = SdkObject::new("CloudtruthSdk"); + root.add_method(SdkRootConstructor::new(&root)); + root.add_method(SdkStaticRootConstructor::new()); + root + } + + pub fn build_object_tree<'a>(&'a self) -> SdkObject<'a> { + let operations = self.spec.operations().into_iter(); + let mut root = self.build_root_object(); + let mut ancestors: Vec<(&str, &mut SdkObject)> = Vec::with_capacity(operations.len()); + ancestors.push((self.root_prefix.as_ref(), &mut root)); + for op in operations { + let uri = op.uri(); + let prefix = ancestors.last().unwrap().0; + match uri.strip_prefix(prefix) { + // same path, different method + Some("") => {} + // child path + Some(path) => { + let parent = &mut *ancestors.last_mut().unwrap().1; + let current = SdkObject::new("foo"); + parent.add_child(current); + ancestors.push((prefix, parent.children_mut().last_mut().unwrap())); + prefix = uri; + } + // unwind stack to find ancestor + _ => { + while let Some((ancestor_prefix, ancestor)) = ancestors.pop() { + if uri.starts_with(ancestor_prefix) { + ancestors.push((ancestor_prefix, ancestor)); + break; + } + } + } + } + } + root + } +} + +// pub fn longest_common_prefix<'a>(str1: &'a str, str2: &'a str) -> &'a str { +// for (i, byte) in str1.as_bytes().iter().enumerate() { +// if str2.as_bytes().get(i) != Some(byte) { +// let mut end = i; +// while !str1.is_char_boundary(end) { +// end -= 1; +// } +// return &str1[0..end]; +// } +// } + +// // entire string is common prefix +// str1 +// } diff --git a/crates/cloudtruth-sdk-codegen/src/lib.rs b/crates/cloudtruth-sdk-codegen/src/lib.rs index 12232e04..0effc195 100644 --- a/crates/cloudtruth-sdk-codegen/src/lib.rs +++ b/crates/cloudtruth-sdk-codegen/src/lib.rs @@ -1,19 +1,17 @@ -mod method; -mod modules; +pub mod api; +pub mod generator; +pub mod sdk; +use api::ApiSpec; use color_eyre::Result; use openapiv3::OpenAPI; -use crate::method::SdkOperation; - pub fn generate_sdk() -> Result<()> { let data = include_str!("../../../openapi.json"); - let openapi: OpenAPI = serde_json::from_str(data).unwrap(); - let _methods = openapi - .operations() - .filter(|(path, _, _)| path.starts_with("/api/v1/integrations/azure/key_vault/")) - .map(|(path, method, op)| SdkOperation::from_openapi_operation(path, method, op.clone())) - .collect::>(); - modules::root().write()?; + let open_api: OpenAPI = serde_json::from_str(data).unwrap(); + let spec = ApiSpec::new(open_api)?; + for op in spec.operations() { + println!("{}", op.uri()); + } Ok(()) } diff --git a/crates/cloudtruth-sdk-codegen/src/method.rs b/crates/cloudtruth-sdk-codegen/src/method.rs deleted file mode 100644 index b264e453..00000000 --- a/crates/cloudtruth-sdk-codegen/src/method.rs +++ /dev/null @@ -1,55 +0,0 @@ -use color_eyre::Result; -use indexmap::IndexMap; -use openapiv3::{Operation, Parameter, RequestBody, Responses}; - -use uritemplate::UriTemplate; - -pub struct SdkOperation { - pub path_template: UriTemplate, - pub http_method: http::Method, - pub summary: Option, - pub description: Option, - pub operation_id: Option, - pub tags: Vec, - pub deprecated: bool, - pub request_body: Option, - pub parameters: Vec, - pub responses: Responses, - pub security: Option>>>, -} - -impl SdkOperation { - pub fn from_openapi_operation(path: &str, method: &str, op: Operation) -> Result { - let Operation { - description, - summary, - operation_id, - tags, - request_body, - parameters, - responses, - deprecated, - security, - .. - } = op; - let request_body = request_body.map(|b| b.into_item().unwrap()); - let parameters: Vec = parameters - .into_iter() - .map(|p| p.into_item().unwrap()) - .collect(); - - Ok(SdkOperation { - path_template: UriTemplate::new(path), - http_method: method.parse()?, - description, - summary, - operation_id, - tags, - deprecated, - request_body, - parameters, - responses, - security, - }) - } -} diff --git a/crates/cloudtruth-sdk-codegen/src/modules.rs b/crates/cloudtruth-sdk-codegen/src/modules.rs index 8d52e638..493a8614 100644 --- a/crates/cloudtruth-sdk-codegen/src/modules.rs +++ b/crates/cloudtruth-sdk-codegen/src/modules.rs @@ -39,3 +39,8 @@ impl SdkModule { Ok(()) } } + +pub fn root() -> SdkModule { + let root = SdkRoot::new(); + SdkModule::new(sdk_path!("src/lib.rs"), quote!(#root)) +} diff --git a/crates/cloudtruth-sdk-codegen/src/modules/root.rs b/crates/cloudtruth-sdk-codegen/src/modules/root.rs deleted file mode 100644 index d669f9f5..00000000 --- a/crates/cloudtruth-sdk-codegen/src/modules/root.rs +++ /dev/null @@ -1,27 +0,0 @@ -use super::SdkModule; -use crate::sdk_path; -use quote::quote; - -pub fn root() -> SdkModule { - SdkModule::new( - sdk_path!("src/lib.rs"), - quote! { - use once_cell::sync::OnceCell; - use reqwest::Client; - - pub struct CloudtruthSdk { - pub client: Client - } - - impl CloudtruthSdk { - fn new() -> CloudtruthSdk { - CloudtruthSdk { client: Client::new() } - } - pub fn instance() -> &'static CloudtruthSdk { - static ONCE: OnceCell = OnceCell::new(); - ONCE.get_or_init(CloudtruthSdk::new) - } - } - }, - ) -} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk.rs b/crates/cloudtruth-sdk-codegen/src/sdk.rs new file mode 100644 index 00000000..3acfb2af --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk.rs @@ -0,0 +1,4 @@ +pub mod methods; +mod object; + +pub use object::SdkObject; diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs new file mode 100644 index 00000000..d355a0d9 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs @@ -0,0 +1,23 @@ +mod api_method; +mod child_constructor; +mod root_constructors; + +pub use api_method::SdkApiMethod; +pub use child_constructor::SdkChildConstructor; +pub use root_constructors::{SdkRootConstructor, SdkStaticRootConstructor}; + +use super::SdkObject; +use crate::api::ApiOperation; +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; +use std::borrow::Cow; + +pub trait SdkMethod { + fn generate_fn(&self) -> syn::ItemFn; +} + +impl ToTokens for dyn SdkMethod { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.extend(self.generate_fn().to_token_stream()) + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs new file mode 100644 index 00000000..60abac85 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs @@ -0,0 +1,24 @@ +use std::borrow::Cow; + +use syn::parse_quote; + +use crate::api::ApiOperation; + +use super::SdkMethod; + +#[derive(Debug, Clone)] +pub struct SdkApiMethod<'a> { + name: Cow<'a, str>, + api_op: ApiOperation, +} + +impl<'a> SdkMethod for SdkApiMethod<'a> { + fn generate_fn(&self) -> syn::ItemFn { + let SdkApiMethod { name, .. } = self; + parse_quote! { + pub fn #(#name)() { + + } + } + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs new file mode 100644 index 00000000..9aeff03b --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs @@ -0,0 +1,23 @@ +use std::borrow::Cow; + +use syn::parse_quote; + +use crate::sdk::SdkObject; + +use super::SdkMethod; + +pub struct SdkChildConstructor<'a> { + name: Cow<'a, str>, + object: &'a SdkObject<'a>, +} + +impl<'a> SdkMethod for SdkChildConstructor<'a> { + fn generate_fn(&self) -> syn::ItemFn { + let SdkChildConstructor { name, .. } = self; + parse_quote! { + pub fn #(#name)() { + + } + } + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs new file mode 100644 index 00000000..010b9f39 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs @@ -0,0 +1,46 @@ +use syn::parse_quote; + +use crate::sdk::SdkObject; + +use super::SdkMethod; + +pub struct SdkRootConstructor<'a>(&'a SdkObject<'a>); + +impl<'a> SdkRootConstructor<'a> { + pub fn new(root: &'a SdkObject<'a>) -> Self { + SdkRootConstructor(root) + } +} + +impl<'a> SdkMethod for SdkRootConstructor<'a> { + fn generate_fn(&self) -> syn::ItemFn { + let name = self.0.name(); + parse_quote! { + fn new() -> Self { + #name { + client: Arc::new(Client::new()), + } + } + } + } +} + +#[derive(Debug, Clone)] +pub struct SdkStaticRootConstructor(); + +impl SdkStaticRootConstructor { + pub fn new() -> Self { + SdkStaticRootConstructor() + } +} + +impl SdkMethod for SdkStaticRootConstructor { + fn generate_fn(&self) -> syn::ItemFn { + parse_quote! { + pub fn instance() -> &'static Self { + static ONCE: OnceCell = OnceCell::new(); + ONCE.get_or_init(CloudtruthSdk::new) + } + } + } +} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs new file mode 100644 index 00000000..afa316b5 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs @@ -0,0 +1,64 @@ +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; +use std::borrow::Cow; + +use super::methods::SdkMethod; + +pub struct SdkObject<'a> { + name: Cow<'a, str>, + methods: Vec>, + children: Vec>, +} + +impl<'a> SdkObject<'a> { + pub fn new(name: impl Into>) -> Self { + let name = name.into(); + Self { + name, + methods: Vec::new(), + children: Vec::new(), + } + } + + pub fn name(&self) -> &str { + &self.name + } + + pub fn methods(&self) -> &[Box] { + &self.methods + } + + pub fn add_method(&mut self, method: impl SdkMethod + 'static) -> &mut Self { + self.methods.push(Box::new(method)); + self + } + + pub fn children(&self) -> &[SdkObject<'a>] { + &self.children + } + + pub fn children_mut(&mut self) -> &mut [SdkObject<'a>] { + &mut self.children + } + + pub fn add_child(&mut self, child: SdkObject<'a>) { + self.children.push(child); + } +} + +impl<'a> ToTokens for SdkObject<'a> { + fn to_tokens(&self, tokens: &mut TokenStream) { + let SdkObject { + name: type_name, + methods, + .. + } = self; + tokens.extend(quote! { + pub struct #type_name { + } + impl #type_name { + #(#methods)* + } + }); + } +} diff --git a/crates/cloudtruth-sdk/src/lib.rs b/crates/cloudtruth-sdk/src/lib.rs index bd484210..a9fa3690 100644 --- a/crates/cloudtruth-sdk/src/lib.rs +++ b/crates/cloudtruth-sdk/src/lib.rs @@ -1,12 +1,16 @@ +use std::sync::Arc; + use once_cell::sync::OnceCell; use reqwest::Client; + pub struct CloudtruthSdk { - pub client: Client, + pub client: Arc, } + impl CloudtruthSdk { fn new() -> CloudtruthSdk { CloudtruthSdk { - client: Client::new(), + client: Arc::new(Client::new()), } } pub fn instance() -> &'static CloudtruthSdk { From 03bf85d3e1fa691ac3bfe197600aba453171bfdb Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Sun, 9 Jul 2023 21:34:42 -0400 Subject: [PATCH 03/13] Rc all the things --- Cargo.lock | 7 +++ crates/cloudtruth-sdk-codegen/Cargo.toml | 5 +- .../cloudtruth-sdk-codegen/src/generator.rs | 35 +++++------ .../cloudtruth-sdk-codegen/src/sdk/methods.rs | 10 +-- .../src/sdk/methods/api_method.rs | 8 +-- .../src/sdk/methods/child_constructor.rs | 11 ++-- .../src/sdk/methods/root_constructors.rs | 23 ++++--- .../cloudtruth-sdk-codegen/src/sdk/object.rs | 23 +++---- crates/cloudtruth-sdk-codegen/src/sdk/root.rs | 61 +++++++++++++++++++ 9 files changed, 126 insertions(+), 57 deletions(-) create mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/root.rs diff --git a/Cargo.lock b/Cargo.lock index 5d4820ed..ce9eb625 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,6 +588,7 @@ name = "cloudtruth-sdk-codegen" version = "0.1.0" dependencies = [ "color-eyre 0.6.2", + "dyn-clone", "http 0.2.9", "indexmap 1.9.2", "openapiv3", @@ -1141,6 +1142,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +[[package]] +name = "dyn-clone" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" + [[package]] name = "edit" version = "0.1.4" diff --git a/crates/cloudtruth-sdk-codegen/Cargo.toml b/crates/cloudtruth-sdk-codegen/Cargo.toml index f8266d86..9e169ff7 100644 --- a/crates/cloudtruth-sdk-codegen/Cargo.toml +++ b/crates/cloudtruth-sdk-codegen/Cargo.toml @@ -13,5 +13,6 @@ openapiv3 = { version = "1" } proc-macro2 = "1.0.63" quote = "1.0.29" serde_json = "1.0" -syn = "2.0.23" -rfc6570-level-2 = "1.2.0" \ No newline at end of file +syn = { version = "2.0.23", features = ["full"] } +rfc6570-level-2 = "1.2.0" +dyn-clone = "1.0.11" diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 63f04778..7c557093 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -1,7 +1,7 @@ -use std::{borrow::BorrowMut, cell::RefCell}; +use std::rc::Rc; use crate::{ - api::{ApiOperation, ApiSpec}, + api::ApiSpec, sdk::{ methods::{SdkRootConstructor, SdkStaticRootConstructor}, SdkObject, @@ -30,18 +30,11 @@ impl SdkGenerator { self } - fn build_root_object<'a>(&'a self) -> SdkObject<'a> { - let mut root = SdkObject::new("CloudtruthSdk"); - root.add_method(SdkRootConstructor::new(&root)); - root.add_method(SdkStaticRootConstructor::new()); - root - } - - pub fn build_object_tree<'a>(&'a self) -> SdkObject<'a> { - let operations = self.spec.operations().into_iter(); - let mut root = self.build_root_object(); - let mut ancestors: Vec<(&str, &mut SdkObject)> = Vec::with_capacity(operations.len()); - ancestors.push((self.root_prefix.as_ref(), &mut root)); + pub fn build_object_tree(&self) -> Rc { + let mut root = Rc::new(SdkObject::new("CloudtruthSdk")); + let operations = self.spec.operations().iter(); + let mut ancestors: Vec<(&str, Rc)> = Vec::with_capacity(operations.len()); + ancestors.push((self.root_prefix.as_ref(), root.clone())); for op in operations { let uri = op.uri(); let prefix = ancestors.last().unwrap().0; @@ -49,12 +42,11 @@ impl SdkGenerator { // same path, different method Some("") => {} // child path - Some(path) => { - let parent = &mut *ancestors.last_mut().unwrap().1; - let current = SdkObject::new("foo"); - parent.add_child(current); - ancestors.push((prefix, parent.children_mut().last_mut().unwrap())); - prefix = uri; + Some(_path) => { + let mut parent = ancestors.last().unwrap().1.clone(); + let current = Rc::new(SdkObject::new("foo")); + Rc::make_mut(&mut parent).add_child(current); + ancestors.push((prefix, parent.children().last().unwrap().clone())); } // unwind stack to find ancestor _ => { @@ -67,6 +59,9 @@ impl SdkGenerator { } } } + let root_ref = Rc::make_mut(&mut root); + root_ref.add_method(SdkRootConstructor::new(root_ref.name().clone())); + root_ref.add_method(SdkStaticRootConstructor::new()); root } } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs index d355a0d9..169dd960 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods.rs @@ -4,18 +4,18 @@ mod root_constructors; pub use api_method::SdkApiMethod; pub use child_constructor::SdkChildConstructor; +use dyn_clone::DynClone; pub use root_constructors::{SdkRootConstructor, SdkStaticRootConstructor}; -use super::SdkObject; -use crate::api::ApiOperation; use proc_macro2::TokenStream; -use quote::{quote, ToTokens}; -use std::borrow::Cow; +use quote::ToTokens; -pub trait SdkMethod { +pub trait SdkMethod: DynClone { fn generate_fn(&self) -> syn::ItemFn; } +dyn_clone::clone_trait_object!(SdkMethod); + impl ToTokens for dyn SdkMethod { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.extend(self.generate_fn().to_token_stream()) diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs index 60abac85..2190dfed 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use std::rc::Rc; use syn::parse_quote; @@ -7,12 +7,12 @@ use crate::api::ApiOperation; use super::SdkMethod; #[derive(Debug, Clone)] -pub struct SdkApiMethod<'a> { - name: Cow<'a, str>, +pub struct SdkApiMethod { + name: Rc, api_op: ApiOperation, } -impl<'a> SdkMethod for SdkApiMethod<'a> { +impl SdkMethod for SdkApiMethod { fn generate_fn(&self) -> syn::ItemFn { let SdkApiMethod { name, .. } = self; parse_quote! { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs index 9aeff03b..41e4c2ae 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use std::rc::Rc; use syn::parse_quote; @@ -6,12 +6,13 @@ use crate::sdk::SdkObject; use super::SdkMethod; -pub struct SdkChildConstructor<'a> { - name: Cow<'a, str>, - object: &'a SdkObject<'a>, +#[derive(Clone)] +pub struct SdkChildConstructor { + name: Rc, + object: Rc, } -impl<'a> SdkMethod for SdkChildConstructor<'a> { +impl SdkMethod for SdkChildConstructor { fn generate_fn(&self) -> syn::ItemFn { let SdkChildConstructor { name, .. } = self; parse_quote! { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs index 010b9f39..d9585e75 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs @@ -1,20 +1,23 @@ -use syn::parse_quote; +use std::rc::Rc; -use crate::sdk::SdkObject; +use syn::parse_quote; use super::SdkMethod; -pub struct SdkRootConstructor<'a>(&'a SdkObject<'a>); +#[derive(Clone)] +pub struct SdkRootConstructor { + root_name: Rc, +} -impl<'a> SdkRootConstructor<'a> { - pub fn new(root: &'a SdkObject<'a>) -> Self { - SdkRootConstructor(root) +impl SdkRootConstructor { + pub fn new(root_name: Rc) -> Self { + SdkRootConstructor { root_name } } } -impl<'a> SdkMethod for SdkRootConstructor<'a> { +impl SdkMethod for SdkRootConstructor { fn generate_fn(&self) -> syn::ItemFn { - let name = self.0.name(); + let name = &self.root_name; parse_quote! { fn new() -> Self { #name { @@ -25,12 +28,12 @@ impl<'a> SdkMethod for SdkRootConstructor<'a> { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct SdkStaticRootConstructor(); impl SdkStaticRootConstructor { pub fn new() -> Self { - SdkStaticRootConstructor() + SdkStaticRootConstructor::default() } } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs index afa316b5..be870f97 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs @@ -1,17 +1,18 @@ use proc_macro2::TokenStream; use quote::{quote, ToTokens}; -use std::borrow::Cow; +use std::rc::Rc; use super::methods::SdkMethod; -pub struct SdkObject<'a> { - name: Cow<'a, str>, +#[derive(Clone)] +pub struct SdkObject { + name: Rc, methods: Vec>, - children: Vec>, + children: Vec>, } -impl<'a> SdkObject<'a> { - pub fn new(name: impl Into>) -> Self { +impl SdkObject { + pub fn new(name: impl Into>) -> Self { let name = name.into(); Self { name, @@ -20,7 +21,7 @@ impl<'a> SdkObject<'a> { } } - pub fn name(&self) -> &str { + pub fn name(&self) -> &Rc { &self.name } @@ -33,20 +34,20 @@ impl<'a> SdkObject<'a> { self } - pub fn children(&self) -> &[SdkObject<'a>] { + pub fn children(&self) -> &[Rc] { &self.children } - pub fn children_mut(&mut self) -> &mut [SdkObject<'a>] { + pub fn children_mut(&mut self) -> &mut [Rc] { &mut self.children } - pub fn add_child(&mut self, child: SdkObject<'a>) { + pub fn add_child(&mut self, child: Rc) { self.children.push(child); } } -impl<'a> ToTokens for SdkObject<'a> { +impl ToTokens for SdkObject { fn to_tokens(&self, tokens: &mut TokenStream) { let SdkObject { name: type_name, diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/root.rs b/crates/cloudtruth-sdk-codegen/src/sdk/root.rs new file mode 100644 index 00000000..a066e6e8 --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/sdk/root.rs @@ -0,0 +1,61 @@ +use std::borrow::Cow; + +use quote::{quote, ToTokens}; + +use super::SdkObject; + +pub struct SdkRoot<'a> { + type_name: Cow<'a, str>, + children: Vec>, +} + +impl<'a> SdkRoot<'a> { + pub fn new(type_name: impl Into>) -> Self { + let type_name = type_name.into(); + Self { + type_name, + children: Vec::new(), + } + } +} + +impl<'a> HasChildren> for SdkRoot<'a> { + fn children(&self) -> &[SdkObject<'a>] { + &self.children + } + fn children_mut(&mut self) -> &mut [SdkObject<'a>] { + &mut self.children + } + fn add_child(&mut self, child: SdkObject<'a>) { + self.children.push(child); + } +} + +impl<'a> ToTokens for SdkRoot<'a> { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let Self { type_name, .. } = self; + tokens.extend(quote! { + use std::sync::Arc; + + use once_cell::sync::OnceCell; + use reqwest::Client; + + pub struct #type_name { + pub client: Arc, + } + + impl #type_name { + fn new() -> Self { + CloudtruthSdk { + client: Arc::new(Client::new()), + } + } + pub fn instance() -> &'static Self { + static ONCE: OnceCell = OnceCell::new(); + ONCE.get_or_init(CloudtruthSdk::new) + } + } + + }) + } +} From 9c8236bcbe9aa595682d5ab2383883fed7583c65 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 21:35:14 -0400 Subject: [PATCH 04/13] make corrections to object tree builder --- .../src/api/operation.rs | 32 ++++--- crates/cloudtruth-sdk-codegen/src/api/spec.rs | 16 +++- .../cloudtruth-sdk-codegen/src/generator.rs | 93 ++++++++++--------- crates/cloudtruth-sdk-codegen/src/lib.rs | 7 +- .../src/sdk/methods/api_method.rs | 16 +++- .../cloudtruth-sdk-codegen/src/sdk/object.rs | 14 --- 6 files changed, 96 insertions(+), 82 deletions(-) diff --git a/crates/cloudtruth-sdk-codegen/src/api/operation.rs b/crates/cloudtruth-sdk-codegen/src/api/operation.rs index 8f371970..35e50b27 100644 --- a/crates/cloudtruth-sdk-codegen/src/api/operation.rs +++ b/crates/cloudtruth-sdk-codegen/src/api/operation.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use color_eyre::{eyre::eyre, Result}; use indexmap::IndexMap; use openapiv3::{Operation, Parameter, RequestBody, Responses}; @@ -8,10 +10,10 @@ use rfc6570_level_2::UriTemplate; pub struct ApiOperation { path_template: UriTemplate, http_method: http::Method, - summary: Option, - description: Option, - operation_id: Option, - tags: Vec, + summary: Option>, + description: Option>, + operation_id: Option>, + tags: Vec>, deprecated: bool, request_body: Option, parameters: Vec, @@ -42,10 +44,10 @@ impl ApiOperation { Ok(ApiOperation { path_template: UriTemplate::new(path).map_err(|err| eyre!(Box::new(err)))?, // convert anyhow to eyre http_method: method.parse()?, - description, - summary, - operation_id, - tags, + description: description.map(|s| Rc::from(s.as_str())), + summary: summary.map(|s| Rc::from(s.as_str())), + operation_id: operation_id.map(|s| Rc::from(s.as_str())), + tags: tags.into_iter().map(|s| Rc::from(s.as_str())).collect(), deprecated, request_body, parameters, @@ -62,19 +64,19 @@ impl ApiOperation { &self.http_method } - pub fn summary(&self) -> Option<&str> { - self.summary.as_deref() + pub fn summary(&self) -> Option<&Rc> { + self.summary.as_ref() } - pub fn description(&self) -> Option<&str> { - self.description.as_deref() + pub fn description(&self) -> Option<&Rc> { + self.description.as_ref() } - pub fn operation_id(&self) -> Option<&str> { - self.operation_id.as_deref() + pub fn operation_id(&self) -> Option<&Rc> { + self.operation_id.as_ref() } - pub fn tags(&self) -> &[String] { + pub fn tags(&self) -> &[Rc] { self.tags.as_ref() } diff --git a/crates/cloudtruth-sdk-codegen/src/api/spec.rs b/crates/cloudtruth-sdk-codegen/src/api/spec.rs index a63843bd..a1878d6e 100644 --- a/crates/cloudtruth-sdk-codegen/src/api/spec.rs +++ b/crates/cloudtruth-sdk-codegen/src/api/spec.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use color_eyre::Result; use openapiv3::OpenAPI; @@ -5,7 +7,7 @@ use crate::api::ApiOperation; #[derive(Debug, Clone)] pub struct ApiSpec { - operations: Vec, + operations: Vec>, } impl ApiSpec { @@ -13,13 +15,19 @@ impl ApiSpec { let mut operations = open_api .operations() .filter(|(path, _, _)| path.starts_with("/api/v1/integrations/azure/key_vault/")) - .map(|(path, method, op)| ApiOperation::from_openapi(path, method, op.clone())) - .collect::>>()?; + .map(|(path, method, op)| { + Ok(Rc::new(ApiOperation::from_openapi( + path, + method, + op.clone(), + )?)) + }) + .collect::>>>()?; operations.sort_by(|a, b| a.uri().cmp(b.uri())); Ok(Self { operations }) } - pub fn operations(&self) -> &[ApiOperation] { + pub fn operations(&self) -> &[Rc] { &self.operations } } diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 7c557093..3550b2d1 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use crate::{ api::ApiSpec, sdk::{ - methods::{SdkRootConstructor, SdkStaticRootConstructor}, + methods::{SdkApiMethod, SdkRootConstructor, SdkStaticRootConstructor}, SdkObject, }, }; @@ -30,53 +30,60 @@ impl SdkGenerator { self } - pub fn build_object_tree(&self) -> Rc { - let mut root = Rc::new(SdkObject::new("CloudtruthSdk")); - let operations = self.spec.operations().iter(); + pub fn build_objects(&self) -> Vec> { + // list of objects that we are building + let mut objects = Vec::new(); + // iterator over API operations from the spec (assumed to besorted) + let operations = self.spec.operations(); + // a stack of ancestors from iterations let mut ancestors: Vec<(&str, Rc)> = Vec::with_capacity(operations.len()); - ancestors.push((self.root_prefix.as_ref(), root.clone())); - for op in operations { - let uri = op.uri(); - let prefix = ancestors.last().unwrap().0; - match uri.strip_prefix(prefix) { - // same path, different method - Some("") => {} - // child path - Some(_path) => { - let mut parent = ancestors.last().unwrap().1.clone(); - let current = Rc::new(SdkObject::new("foo")); - Rc::make_mut(&mut parent).add_child(current); - ancestors.push((prefix, parent.children().last().unwrap().clone())); + // create root SDK object + let mut root = SdkObject::new("CloudtruthSdk"); + root.add_method(SdkRootConstructor::new(root.name().clone())); + root.add_method(SdkStaticRootConstructor::new()); + // add root to ancestor stack + ancestors.push((self.root_prefix.as_ref(), Rc::new(root))); + + for op in operations.iter() { + // println!(); + let uri = op.uri().trim_end_matches('/'); + let _method = op.http_method(); + // println!("{method} {uri}"); + // find the ancestor of current path in the stack and get the descendant path segments + let descendant_path = loop { + match ancestors.last() { + Some((ancestor_prefix, _)) => match uri.strip_prefix(ancestor_prefix) { + // found ancestor, return the descendant path + Some(descendant_path) => break descendant_path, + // not an ancestor, pop from stack and append to our output list + None => objects.push(ancestors.pop().unwrap().1), + }, + // no valid anceestor (unexpected behavior) + None => panic!("No ancestor found for {uri}"), } - // unwind stack to find ancestor - _ => { - while let Some((ancestor_prefix, ancestor)) = ancestors.pop() { - if uri.starts_with(ancestor_prefix) { - ancestors.push((ancestor_prefix, ancestor)); - break; - } + }; + for child_segment in descendant_path.split('/').skip(1) { + if child_segment.is_empty() + || child_segment.starts_with('{') && child_segment.ends_with('}') + { + let size = ancestors.len(); + if let Some((_, previous_object)) = ancestors.get_mut(size - 1) { + Rc::get_mut(previous_object) + .expect("Could not add method to object because other references to this object were found") + .add_method(SdkApiMethod::new(op.clone())); } + } else { + let current_object = Rc::new(SdkObject::new(child_segment)); + // append this path segment to current prefix + let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; + let segment_end = segment_start + child_segment.len(); + let path = &uri[..segment_end]; + ancestors.push((path, current_object)); } } } - let root_ref = Rc::make_mut(&mut root); - root_ref.add_method(SdkRootConstructor::new(root_ref.name().clone())); - root_ref.add_method(SdkStaticRootConstructor::new()); - root + // add any remaining ancestors in stack to output list + objects.extend(ancestors.into_iter().map(|(_, ancestor)| ancestor)); + objects } } - -// pub fn longest_common_prefix<'a>(str1: &'a str, str2: &'a str) -> &'a str { -// for (i, byte) in str1.as_bytes().iter().enumerate() { -// if str2.as_bytes().get(i) != Some(byte) { -// let mut end = i; -// while !str1.is_char_boundary(end) { -// end -= 1; -// } -// return &str1[0..end]; -// } -// } - -// // entire string is common prefix -// str1 -// } diff --git a/crates/cloudtruth-sdk-codegen/src/lib.rs b/crates/cloudtruth-sdk-codegen/src/lib.rs index 0effc195..122727b6 100644 --- a/crates/cloudtruth-sdk-codegen/src/lib.rs +++ b/crates/cloudtruth-sdk-codegen/src/lib.rs @@ -4,14 +4,15 @@ pub mod sdk; use api::ApiSpec; use color_eyre::Result; +use generator::SdkGenerator; use openapiv3::OpenAPI; pub fn generate_sdk() -> Result<()> { let data = include_str!("../../../openapi.json"); let open_api: OpenAPI = serde_json::from_str(data).unwrap(); let spec = ApiSpec::new(open_api)?; - for op in spec.operations() { - println!("{}", op.uri()); - } + let mut generator = SdkGenerator::new(spec); + generator.root_prefix("/api/v1"); + let _root = generator.build_objects(); Ok(()) } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs index 2190dfed..f6a4ed34 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs @@ -8,13 +8,23 @@ use super::SdkMethod; #[derive(Debug, Clone)] pub struct SdkApiMethod { - name: Rc, - api_op: ApiOperation, + api_op: Rc, +} + +impl SdkApiMethod { + pub fn new(api_op: impl Into>) -> Self { + let api_op = api_op.into(); + SdkApiMethod { api_op } + } + + fn name(&self) -> &Rc { + self.api_op.operation_id().unwrap() + } } impl SdkMethod for SdkApiMethod { fn generate_fn(&self) -> syn::ItemFn { - let SdkApiMethod { name, .. } = self; + let name = self.name(); parse_quote! { pub fn #(#name)() { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs index be870f97..85e9e697 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs @@ -8,7 +8,6 @@ use super::methods::SdkMethod; pub struct SdkObject { name: Rc, methods: Vec>, - children: Vec>, } impl SdkObject { @@ -17,7 +16,6 @@ impl SdkObject { Self { name, methods: Vec::new(), - children: Vec::new(), } } @@ -33,18 +31,6 @@ impl SdkObject { self.methods.push(Box::new(method)); self } - - pub fn children(&self) -> &[Rc] { - &self.children - } - - pub fn children_mut(&mut self) -> &mut [Rc] { - &mut self.children - } - - pub fn add_child(&mut self, child: Rc) { - self.children.push(child); - } } impl ToTokens for SdkObject { From a7070ef72a9c5b4341421e87a83a69539724dfd0 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 21:37:16 -0400 Subject: [PATCH 05/13] fix comment typos --- crates/cloudtruth-sdk-codegen/src/generator.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 3550b2d1..09908a61 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -33,9 +33,9 @@ impl SdkGenerator { pub fn build_objects(&self) -> Vec> { // list of objects that we are building let mut objects = Vec::new(); - // iterator over API operations from the spec (assumed to besorted) + // iterator over API operations from the spec (assumed to be sorted) let operations = self.spec.operations(); - // a stack of ancestors from iterations + // a stack of ancestors from pervious iterations let mut ancestors: Vec<(&str, Rc)> = Vec::with_capacity(operations.len()); // create root SDK object let mut root = SdkObject::new("CloudtruthSdk"); @@ -47,8 +47,9 @@ impl SdkGenerator { for op in operations.iter() { // println!(); let uri = op.uri().trim_end_matches('/'); - let _method = op.http_method(); + // let method = op.http_method(); // println!("{method} {uri}"); + // find the ancestor of current path in the stack and get the descendant path segments let descendant_path = loop { match ancestors.last() { From ffe8d3863fb41a456366a6844fa60dba184803ca Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 21:39:17 -0400 Subject: [PATCH 06/13] fix comment typos --- crates/cloudtruth-sdk-codegen/src/generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 09908a61..fc6ab31f 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -59,7 +59,7 @@ impl SdkGenerator { // not an ancestor, pop from stack and append to our output list None => objects.push(ancestors.pop().unwrap().1), }, - // no valid anceestor (unexpected behavior) + // no valid ancestor (unexpected behavior) None => panic!("No ancestor found for {uri}"), } }; From 84d285d6547d87689a6e9f98055b3371397ec32f Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 21:43:32 -0400 Subject: [PATCH 07/13] skip leading slash with trim_start_matches instead of skip --- crates/cloudtruth-sdk-codegen/src/generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index fc6ab31f..6403c78d 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -63,7 +63,7 @@ impl SdkGenerator { None => panic!("No ancestor found for {uri}"), } }; - for child_segment in descendant_path.split('/').skip(1) { + for child_segment in descendant_path.trim_start_matches("/").split('/') { if child_segment.is_empty() || child_segment.starts_with('{') && child_segment.ends_with('}') { From 1081bd9dfbcd8687b160457e0fedffedcaa22256 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 21:43:52 -0400 Subject: [PATCH 08/13] skip leading slash with trim_start_matches instead of skip --- crates/cloudtruth-sdk-codegen/src/generator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 6403c78d..e5614bf2 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -63,7 +63,7 @@ impl SdkGenerator { None => panic!("No ancestor found for {uri}"), } }; - for child_segment in descendant_path.trim_start_matches("/").split('/') { + for child_segment in descendant_path.trim_start_matches('/').split('/') { if child_segment.is_empty() || child_segment.starts_with('{') && child_segment.ends_with('}') { From 959b64ccb09af9d7c398f4f876a04023c01ff378 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 23:15:32 -0400 Subject: [PATCH 09/13] do not create rc until end of build_objects mtehod --- crates/cloudtruth-sdk-codegen/src/generator.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index e5614bf2..d73493ce 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -36,13 +36,13 @@ impl SdkGenerator { // iterator over API operations from the spec (assumed to be sorted) let operations = self.spec.operations(); // a stack of ancestors from pervious iterations - let mut ancestors: Vec<(&str, Rc)> = Vec::with_capacity(operations.len()); + let mut ancestors = Vec::with_capacity(operations.len()); // create root SDK object let mut root = SdkObject::new("CloudtruthSdk"); root.add_method(SdkRootConstructor::new(root.name().clone())); root.add_method(SdkStaticRootConstructor::new()); // add root to ancestor stack - ancestors.push((self.root_prefix.as_ref(), Rc::new(root))); + ancestors.push((self.root_prefix.as_ref(), root)); for op in operations.iter() { // println!(); @@ -57,7 +57,7 @@ impl SdkGenerator { // found ancestor, return the descendant path Some(descendant_path) => break descendant_path, // not an ancestor, pop from stack and append to our output list - None => objects.push(ancestors.pop().unwrap().1), + None => objects.push(Rc::new(ancestors.pop().unwrap().1)), }, // no valid ancestor (unexpected behavior) None => panic!("No ancestor found for {uri}"), @@ -69,12 +69,10 @@ impl SdkGenerator { { let size = ancestors.len(); if let Some((_, previous_object)) = ancestors.get_mut(size - 1) { - Rc::get_mut(previous_object) - .expect("Could not add method to object because other references to this object were found") - .add_method(SdkApiMethod::new(op.clone())); + previous_object.add_method(SdkApiMethod::new(op.clone())); } } else { - let current_object = Rc::new(SdkObject::new(child_segment)); + let current_object = SdkObject::new(child_segment); // append this path segment to current prefix let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; let segment_end = segment_start + child_segment.len(); @@ -84,7 +82,7 @@ impl SdkGenerator { } } // add any remaining ancestors in stack to output list - objects.extend(ancestors.into_iter().map(|(_, ancestor)| ancestor)); + objects.extend(ancestors.into_iter().map(|(_, ancestor)| Rc::new(ancestor))); objects } } From afabfaadc7e0d3f453bca749de7849378362421b Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Mon, 10 Jul 2023 23:20:48 -0400 Subject: [PATCH 10/13] add capacity hint for objects list --- crates/cloudtruth-sdk-codegen/src/generator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index d73493ce..db939fb5 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -31,10 +31,10 @@ impl SdkGenerator { } pub fn build_objects(&self) -> Vec> { - // list of objects that we are building - let mut objects = Vec::new(); // iterator over API operations from the spec (assumed to be sorted) let operations = self.spec.operations(); + // list of objects that we are building + let mut objects = Vec::with_capacity(operations.len()); // a stack of ancestors from pervious iterations let mut ancestors = Vec::with_capacity(operations.len()); // create root SDK object From 9beee153b85f48b9b859f0d9d9af693cb2c6d4f6 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Tue, 11 Jul 2023 13:27:47 -0400 Subject: [PATCH 11/13] add fields and arguments --- .../cloudtruth-sdk-codegen/src/generator.rs | 57 ++++++++++++++----- .../src/sdk/methods/child_constructor.rs | 26 +++++++-- .../src/sdk/methods/root_constructors.rs | 11 ++-- .../cloudtruth-sdk-codegen/src/sdk/object.rs | 32 ++++++++--- 4 files changed, 96 insertions(+), 30 deletions(-) diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index db939fb5..893012fe 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -1,9 +1,13 @@ use std::rc::Rc; +use syn::parse_quote; + use crate::{ api::ApiSpec, sdk::{ - methods::{SdkApiMethod, SdkRootConstructor, SdkStaticRootConstructor}, + methods::{ + SdkApiMethod, SdkChildConstructor, SdkRootConstructor, SdkStaticRootConstructor, + }, SdkObject, }, }; @@ -39,7 +43,7 @@ impl SdkGenerator { let mut ancestors = Vec::with_capacity(operations.len()); // create root SDK object let mut root = SdkObject::new("CloudtruthSdk"); - root.add_method(SdkRootConstructor::new(root.name().clone())); + root.add_method(SdkRootConstructor::new(&root)); root.add_method(SdkStaticRootConstructor::new()); // add root to ancestor stack ancestors.push((self.root_prefix.as_ref(), root)); @@ -63,24 +67,47 @@ impl SdkGenerator { None => panic!("No ancestor found for {uri}"), } }; + // println!("{descendant_path:#}"); for child_segment in descendant_path.trim_start_matches('/').split('/') { - if child_segment.is_empty() - || child_segment.starts_with('{') && child_segment.ends_with('}') - { - let size = ancestors.len(); - if let Some((_, previous_object)) = ancestors.get_mut(size - 1) { - previous_object.add_method(SdkApiMethod::new(op.clone())); - } + if child_segment.is_empty() { + continue; + } + let is_path_var = child_segment.starts_with('{') && child_segment.ends_with('}'); + let name = if is_path_var { + child_segment + .chars() + .filter(|c| *c == '_' || c.is_alphanumeric()) + .collect::() } else { - let current_object = SdkObject::new(child_segment); - // append this path segment to current prefix - let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; - let segment_end = segment_start + child_segment.len(); - let path = &uri[..segment_end]; - ancestors.push((path, current_object)); + child_segment.to_string() + }; + let mut current_object = SdkObject::new(name.as_str()); + if is_path_var { + current_object.add_field(&name, parse_quote![&str]); + } + + // attach getter method to parent object + let size = ancestors.len(); + if let Some((_, previous_object)) = ancestors.get_mut(size - 1) { + let mut method = SdkChildConstructor::new(¤t_object); + if is_path_var { + method.add_arg(&name, parse_quote![&str]); + } + previous_object.add_method(method); } + // append this path segment to current prefix + let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; + let segment_end = segment_start + child_segment.len(); + let path = &uri[..segment_end]; + // add to ancestors stack + ancestors.push((path, current_object)); + } + let size = ancestors.len(); + if let Some((_, last_object)) = ancestors.get_mut(size - 1) { + last_object.add_method(SdkApiMethod::new(op.clone())); } } + // add any remaining ancestors in stack to output list objects.extend(ancestors.into_iter().map(|(_, ancestor)| Rc::new(ancestor))); objects diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs index 41e4c2ae..ca77a461 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use syn::parse_quote; +use syn::{parse_quote, punctuated::Punctuated, token::Comma, FnArg, Type}; use crate::sdk::SdkObject; @@ -9,14 +9,32 @@ use super::SdkMethod; #[derive(Clone)] pub struct SdkChildConstructor { name: Rc, - object: Rc, + args: Punctuated, +} + +impl SdkChildConstructor { + pub fn new(object: &SdkObject) -> Self { + let name = object.name().clone(); + Self { + name, + args: Punctuated::new(), + } + } + + pub fn name(&self) -> &Rc { + &self.name + } + + pub fn add_arg(&mut self, arg_name: &str, arg_type: Type) { + self.args.push(parse_quote! [ #arg_name : #arg_type ]); + } } impl SdkMethod for SdkChildConstructor { fn generate_fn(&self) -> syn::ItemFn { - let SdkChildConstructor { name, .. } = self; + let Self { name, args } = self; parse_quote! { - pub fn #(#name)() { + pub fn #name(#args) { } } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs index d9585e75..b03b2b26 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs @@ -2,22 +2,25 @@ use std::rc::Rc; use syn::parse_quote; +use crate::sdk::SdkObject; + use super::SdkMethod; #[derive(Clone)] pub struct SdkRootConstructor { - root_name: Rc, + name: Rc, } impl SdkRootConstructor { - pub fn new(root_name: Rc) -> Self { - SdkRootConstructor { root_name } + pub fn new(object: &SdkObject) -> Self { + let name = object.name().clone(); + SdkRootConstructor { name } } } impl SdkMethod for SdkRootConstructor { fn generate_fn(&self) -> syn::ItemFn { - let name = &self.root_name; + let name = &self.name; parse_quote! { fn new() -> Self { #name { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs index 85e9e697..67d24642 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs @@ -1,22 +1,27 @@ -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; use std::rc::Rc; +use syn::{parse_quote, punctuated::Punctuated, token::Comma, Field, Ident, Type}; use super::methods::SdkMethod; #[derive(Clone)] pub struct SdkObject { name: Rc, + fields: Punctuated, methods: Vec>, } impl SdkObject { pub fn new(name: impl Into>) -> Self { let name = name.into(); - Self { + let mut object = Self { name, methods: Vec::new(), - } + fields: Punctuated::new(), + }; + object.add_field("client", parse_quote![Arc]); + object } pub fn name(&self) -> &Rc { @@ -31,19 +36,32 @@ impl SdkObject { self.methods.push(Box::new(method)); self } + + pub fn add_field(&mut self, name: &str, field_type: Type) -> &mut Self { + self.fields.push(Field { + attrs: Vec::new(), + vis: syn::Visibility::Inherited, + mutability: syn::FieldMutability::None, + ident: Some(Ident::new(name, Span::call_site())), + colon_token: parse_quote![:], + ty: field_type, + }); + self + } } impl ToTokens for SdkObject { fn to_tokens(&self, tokens: &mut TokenStream) { let SdkObject { - name: type_name, + name, methods, - .. + fields, } = self; tokens.extend(quote! { - pub struct #type_name { + pub struct #name { + #fields } - impl #type_name { + impl #name { #(#methods)* } }); From b02b058de4f10d39cf21c9686da70394a3124550 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Tue, 11 Jul 2023 15:02:07 -0400 Subject: [PATCH 12/13] test code generation and fix some bugs with names --- .../cloudtruth-sdk-codegen/src/generator.rs | 14 +- crates/cloudtruth-sdk-codegen/src/lib.rs | 20 +- .../src/{modules.rs => module.rs} | 16 - .../src/sdk/methods/api_method.rs | 5 +- .../src/sdk/methods/child_constructor.rs | 47 +- .../src/sdk/methods/root_constructors.rs | 7 +- .../cloudtruth-sdk-codegen/src/sdk/object.rs | 28 +- crates/cloudtruth-sdk-codegen/src/sdk/root.rs | 61 --- crates/cloudtruth-sdk/src/lib.rs | 456 +++++++++++++++++- 9 files changed, 531 insertions(+), 123 deletions(-) rename crates/cloudtruth-sdk-codegen/src/{modules.rs => module.rs} (71%) delete mode 100644 crates/cloudtruth-sdk-codegen/src/sdk/root.rs diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 893012fe..10bee4da 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -42,7 +42,8 @@ impl SdkGenerator { // a stack of ancestors from pervious iterations let mut ancestors = Vec::with_capacity(operations.len()); // create root SDK object - let mut root = SdkObject::new("CloudtruthSdk"); + let mut root = SdkObject::new("CloudtruthSdk", None); + root.add_field("client", parse_quote![Arc]); root.add_method(SdkRootConstructor::new(&root)); root.add_method(SdkStaticRootConstructor::new()); // add root to ancestor stack @@ -81,19 +82,20 @@ impl SdkGenerator { } else { child_segment.to_string() }; - let mut current_object = SdkObject::new(name.as_str()); + let size = ancestors.len(); + let parent_object = ancestors.get_mut(size - 1).map(|(_, obj)| obj); + let mut current_object = SdkObject::new(name.as_str(), parent_object.as_deref()); if is_path_var { current_object.add_field(&name, parse_quote![&str]); } // attach getter method to parent object - let size = ancestors.len(); - if let Some((_, previous_object)) = ancestors.get_mut(size - 1) { - let mut method = SdkChildConstructor::new(¤t_object); + if let Some(parent_object) = parent_object { + let mut method = SdkChildConstructor::new(parent_object, ¤t_object); if is_path_var { method.add_arg(&name, parse_quote![&str]); } - previous_object.add_method(method); + parent_object.add_method(method); } // append this path segment to current prefix let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; diff --git a/crates/cloudtruth-sdk-codegen/src/lib.rs b/crates/cloudtruth-sdk-codegen/src/lib.rs index 122727b6..a742a8b7 100644 --- a/crates/cloudtruth-sdk-codegen/src/lib.rs +++ b/crates/cloudtruth-sdk-codegen/src/lib.rs @@ -1,11 +1,21 @@ pub mod api; pub mod generator; +pub mod module; pub mod sdk; use api::ApiSpec; use color_eyre::Result; use generator::SdkGenerator; +use module::SdkModule; use openapiv3::OpenAPI; +use quote::quote; + +#[macro_export] +macro_rules! sdk_path { + ($($path:expr),* $(,)?) => { + std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../cloudtruth-sdk/", $($path),*)) + }; +} pub fn generate_sdk() -> Result<()> { let data = include_str!("../../../openapi.json"); @@ -13,6 +23,14 @@ pub fn generate_sdk() -> Result<()> { let spec = ApiSpec::new(open_api)?; let mut generator = SdkGenerator::new(spec); generator.root_prefix("/api/v1"); - let _root = generator.build_objects(); + let objects = generator.build_objects(); + SdkModule::new( + sdk_path!("src/lib.rs"), + quote! { + use std::sync::Arc; + #(#objects )* + }, + ) + .write()?; Ok(()) } diff --git a/crates/cloudtruth-sdk-codegen/src/modules.rs b/crates/cloudtruth-sdk-codegen/src/module.rs similarity index 71% rename from crates/cloudtruth-sdk-codegen/src/modules.rs rename to crates/cloudtruth-sdk-codegen/src/module.rs index 493a8614..31f0efdb 100644 --- a/crates/cloudtruth-sdk-codegen/src/modules.rs +++ b/crates/cloudtruth-sdk-codegen/src/module.rs @@ -1,19 +1,8 @@ -mod root; - -pub use root::root; - use std::{borrow::Cow, fs::File, io::Write, path::Path, process::Command}; use color_eyre::{eyre::Context, Result}; use proc_macro2::TokenStream; -#[macro_export] -macro_rules! sdk_path { - ($($path:expr),* $(,)?) => { - std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../cloudtruth-sdk/", $($path),*)) - }; -} - #[derive(Debug, Clone)] pub struct SdkModule { path: Cow<'static, Path>, @@ -39,8 +28,3 @@ impl SdkModule { Ok(()) } } - -pub fn root() -> SdkModule { - let root = SdkRoot::new(); - SdkModule::new(sdk_path!("src/lib.rs"), quote!(#root)) -} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs index f6a4ed34..120b853d 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs @@ -1,5 +1,6 @@ use std::rc::Rc; +use proc_macro2::{Ident, Span}; use syn::parse_quote; use crate::api::ApiOperation; @@ -24,9 +25,9 @@ impl SdkApiMethod { impl SdkMethod for SdkApiMethod { fn generate_fn(&self) -> syn::ItemFn { - let name = self.name(); + let name = Ident::new(self.name(), Span::call_site()); parse_quote! { - pub fn #(#name)() { + pub fn #name() { } } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs index ca77a461..29aec032 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs @@ -1,6 +1,5 @@ -use std::rc::Rc; - -use syn::{parse_quote, punctuated::Punctuated, token::Comma, FnArg, Type}; +use proc_macro2::{Ident, Span}; +use syn::{parse_quote, Field, FnArg, Type}; use crate::sdk::SdkObject; @@ -8,34 +7,48 @@ use super::SdkMethod; #[derive(Clone)] pub struct SdkChildConstructor { - name: Rc, - args: Punctuated, + name: Ident, + child_name: Ident, + parent_fields: Vec, + args: Vec<(Ident, Type)>, } impl SdkChildConstructor { - pub fn new(object: &SdkObject) -> Self { - let name = object.name().clone(); + pub fn new(parent: &SdkObject, child: &SdkObject) -> Self { Self { - name, - args: Punctuated::new(), + name: child.name().clone(), + child_name: child.name().clone(), + parent_fields: parent + .fields() + .iter() + .map(|Field { ident, .. }| ident.clone().unwrap()) + .collect(), + args: Vec::new(), } } - pub fn name(&self) -> &Rc { - &self.name - } - pub fn add_arg(&mut self, arg_name: &str, arg_type: Type) { - self.args.push(parse_quote! [ #arg_name : #arg_type ]); + let arg_name = Ident::new(arg_name, Span::call_site()); + self.args.push((arg_name, arg_type)); } } impl SdkMethod for SdkChildConstructor { fn generate_fn(&self) -> syn::ItemFn { - let Self { name, args } = self; + let Self { + name, + child_name, + parent_fields, + args, + } = self; + let arg_names = args.iter().map(|(name, _)| name); + let args = args + .iter() + .map::(|(name, ty)| parse_quote!( #name : #ty )); parse_quote! { - pub fn #name(#args) { - + pub fn #name(&self, #(#args,)*) -> #child_name { + let Self { #(#parent_fields,)* } = self; + #child_name { #(#parent_fields,)* #(#arg_names,)* } } } } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs index b03b2b26..88bf49c4 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs @@ -1,5 +1,4 @@ -use std::rc::Rc; - +use proc_macro2::Ident; use syn::parse_quote; use crate::sdk::SdkObject; @@ -8,7 +7,7 @@ use super::SdkMethod; #[derive(Clone)] pub struct SdkRootConstructor { - name: Rc, + name: Ident, } impl SdkRootConstructor { @@ -20,7 +19,7 @@ impl SdkRootConstructor { impl SdkMethod for SdkRootConstructor { fn generate_fn(&self) -> syn::ItemFn { - let name = &self.name; + let Self { name } = self; parse_quote! { fn new() -> Self { #name { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs index 67d24642..d4bf7864 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs @@ -1,30 +1,34 @@ use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; -use std::rc::Rc; + use syn::{parse_quote, punctuated::Punctuated, token::Comma, Field, Ident, Type}; use super::methods::SdkMethod; #[derive(Clone)] pub struct SdkObject { - name: Rc, + name: Ident, fields: Punctuated, methods: Vec>, } impl SdkObject { - pub fn new(name: impl Into>) -> Self { - let name = name.into(); + pub fn new(name: impl AsRef, parent: Option<&SdkObject>) -> Self { let mut object = Self { - name, + name: Ident::new(name.as_ref(), Span::call_site()), methods: Vec::new(), fields: Punctuated::new(), }; - object.add_field("client", parse_quote![Arc]); + // add parent fields + if let Some(parent) = parent { + for field in parent.fields() { + object.add_field_ident(field.ident.clone().unwrap(), field.ty.clone()); + } + } object } - pub fn name(&self) -> &Rc { + pub fn name(&self) -> &Ident { &self.name } @@ -37,12 +41,20 @@ impl SdkObject { self } + pub fn fields(&self) -> &Punctuated { + &self.fields + } + pub fn add_field(&mut self, name: &str, field_type: Type) -> &mut Self { + self.add_field_ident(Ident::new(name, Span::call_site()), field_type) + } + + pub fn add_field_ident(&mut self, ident: Ident, field_type: Type) -> &mut Self { self.fields.push(Field { attrs: Vec::new(), vis: syn::Visibility::Inherited, mutability: syn::FieldMutability::None, - ident: Some(Ident::new(name, Span::call_site())), + ident: Some(ident), colon_token: parse_quote![:], ty: field_type, }); diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/root.rs b/crates/cloudtruth-sdk-codegen/src/sdk/root.rs deleted file mode 100644 index a066e6e8..00000000 --- a/crates/cloudtruth-sdk-codegen/src/sdk/root.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::borrow::Cow; - -use quote::{quote, ToTokens}; - -use super::SdkObject; - -pub struct SdkRoot<'a> { - type_name: Cow<'a, str>, - children: Vec>, -} - -impl<'a> SdkRoot<'a> { - pub fn new(type_name: impl Into>) -> Self { - let type_name = type_name.into(); - Self { - type_name, - children: Vec::new(), - } - } -} - -impl<'a> HasChildren> for SdkRoot<'a> { - fn children(&self) -> &[SdkObject<'a>] { - &self.children - } - fn children_mut(&mut self) -> &mut [SdkObject<'a>] { - &mut self.children - } - fn add_child(&mut self, child: SdkObject<'a>) { - self.children.push(child); - } -} - -impl<'a> ToTokens for SdkRoot<'a> { - fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { - let Self { type_name, .. } = self; - tokens.extend(quote! { - use std::sync::Arc; - - use once_cell::sync::OnceCell; - use reqwest::Client; - - pub struct #type_name { - pub client: Arc, - } - - impl #type_name { - fn new() -> Self { - CloudtruthSdk { - client: Arc::new(Client::new()), - } - } - pub fn instance() -> &'static Self { - static ONCE: OnceCell = OnceCell::new(); - ONCE.get_or_init(CloudtruthSdk::new) - } - } - - }) - } -} diff --git a/crates/cloudtruth-sdk/src/lib.rs b/crates/cloudtruth-sdk/src/lib.rs index a9fa3690..250bc151 100644 --- a/crates/cloudtruth-sdk/src/lib.rs +++ b/crates/cloudtruth-sdk/src/lib.rs @@ -1,20 +1,460 @@ use std::sync::Arc; - -use once_cell::sync::OnceCell; -use reqwest::Client; - +pub struct id { + client: Arc, + akvintegration_pk: &str, + akvpull_pk: &str, + akvpulltask_pk: &str, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_pulls_tasks_steps_retrieve() {} +} +pub struct steps { + client: Arc, + akvintegration_pk: &str, + akvpull_pk: &str, + akvpulltask_pk: &str, +} +impl steps { + pub fn integrations_azure_key_vault_pulls_tasks_steps_list() {} + pub fn id(&self, id: &str) -> id { + let Self { + client, + akvintegration_pk, + akvpull_pk, + akvpulltask_pk, + } = self; + id { + client, + akvintegration_pk, + akvpull_pk, + akvpulltask_pk, + id, + } + } +} +pub struct akvpulltask_pk { + client: Arc, + akvintegration_pk: &str, + akvpull_pk: &str, + akvpulltask_pk: &str, +} +impl akvpulltask_pk { + pub fn steps(&self) -> steps { + let Self { + client, + akvintegration_pk, + akvpull_pk, + akvpulltask_pk, + } = self; + steps { + client, + akvintegration_pk, + akvpull_pk, + akvpulltask_pk, + } + } +} +pub struct id { + client: Arc, + akvintegration_pk: &str, + akvpull_pk: &str, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_pulls_tasks_retrieve() {} +} +pub struct tasks { + client: Arc, + akvintegration_pk: &str, + akvpull_pk: &str, +} +impl tasks { + pub fn integrations_azure_key_vault_pulls_tasks_list() {} + pub fn akvpulltask_pk(&self, akvpulltask_pk: &str) -> akvpulltask_pk { + let Self { + client, + akvintegration_pk, + akvpull_pk, + } = self; + akvpulltask_pk { + client, + akvintegration_pk, + akvpull_pk, + akvpulltask_pk, + } + } + pub fn id(&self, id: &str) -> id { + let Self { + client, + akvintegration_pk, + akvpull_pk, + } = self; + id { + client, + akvintegration_pk, + akvpull_pk, + id, + } + } +} +pub struct akvpull_pk { + client: Arc, + akvintegration_pk: &str, + akvpull_pk: &str, +} +impl akvpull_pk { + pub fn tasks(&self) -> tasks { + let Self { + client, + akvintegration_pk, + akvpull_pk, + } = self; + tasks { + client, + akvintegration_pk, + akvpull_pk, + } + } +} +pub struct sync { + client: Arc, + akvintegration_pk: &str, + id: &str, +} +impl sync { + pub fn integrations_azure_key_vault_pulls_sync_create() {} +} +pub struct id { + client: Arc, + akvintegration_pk: &str, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_pulls_retrieve() {} + pub fn integrations_azure_key_vault_pulls_update() {} + pub fn integrations_azure_key_vault_pulls_destroy() {} + pub fn integrations_azure_key_vault_pulls_partial_update() {} + pub fn sync(&self) -> sync { + let Self { + client, + akvintegration_pk, + id, + } = self; + sync { + client, + akvintegration_pk, + id, + } + } +} +pub struct pulls { + client: Arc, + akvintegration_pk: &str, +} +impl pulls { + pub fn integrations_azure_key_vault_pulls_list() {} + pub fn integrations_azure_key_vault_pulls_create() {} + pub fn akvpull_pk(&self, akvpull_pk: &str) -> akvpull_pk { + let Self { + client, + akvintegration_pk, + } = self; + akvpull_pk { + client, + akvintegration_pk, + akvpull_pk, + } + } + pub fn id(&self, id: &str) -> id { + let Self { + client, + akvintegration_pk, + } = self; + id { + client, + akvintegration_pk, + id, + } + } +} +pub struct id { + client: Arc, + akvintegration_pk: &str, + akvpush_pk: &str, + akvpushtask_pk: &str, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_pushes_tasks_steps_retrieve() {} +} +pub struct steps { + client: Arc, + akvintegration_pk: &str, + akvpush_pk: &str, + akvpushtask_pk: &str, +} +impl steps { + pub fn integrations_azure_key_vault_pushes_tasks_steps_list() {} + pub fn id(&self, id: &str) -> id { + let Self { + client, + akvintegration_pk, + akvpush_pk, + akvpushtask_pk, + } = self; + id { + client, + akvintegration_pk, + akvpush_pk, + akvpushtask_pk, + id, + } + } +} +pub struct akvpushtask_pk { + client: Arc, + akvintegration_pk: &str, + akvpush_pk: &str, + akvpushtask_pk: &str, +} +impl akvpushtask_pk { + pub fn steps(&self) -> steps { + let Self { + client, + akvintegration_pk, + akvpush_pk, + akvpushtask_pk, + } = self; + steps { + client, + akvintegration_pk, + akvpush_pk, + akvpushtask_pk, + } + } +} +pub struct id { + client: Arc, + akvintegration_pk: &str, + akvpush_pk: &str, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_pushes_tasks_retrieve() {} +} +pub struct tasks { + client: Arc, + akvintegration_pk: &str, + akvpush_pk: &str, +} +impl tasks { + pub fn integrations_azure_key_vault_pushes_tasks_list() {} + pub fn akvpushtask_pk(&self, akvpushtask_pk: &str) -> akvpushtask_pk { + let Self { + client, + akvintegration_pk, + akvpush_pk, + } = self; + akvpushtask_pk { + client, + akvintegration_pk, + akvpush_pk, + akvpushtask_pk, + } + } + pub fn id(&self, id: &str) -> id { + let Self { + client, + akvintegration_pk, + akvpush_pk, + } = self; + id { + client, + akvintegration_pk, + akvpush_pk, + id, + } + } +} +pub struct akvpush_pk { + client: Arc, + akvintegration_pk: &str, + akvpush_pk: &str, +} +impl akvpush_pk { + pub fn tasks(&self) -> tasks { + let Self { + client, + akvintegration_pk, + akvpush_pk, + } = self; + tasks { + client, + akvintegration_pk, + akvpush_pk, + } + } +} +pub struct sync { + client: Arc, + akvintegration_pk: &str, + id: &str, +} +impl sync { + pub fn integrations_azure_key_vault_pushes_sync_create() {} +} +pub struct id { + client: Arc, + akvintegration_pk: &str, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_pushes_retrieve() {} + pub fn integrations_azure_key_vault_pushes_update() {} + pub fn integrations_azure_key_vault_pushes_destroy() {} + pub fn integrations_azure_key_vault_pushes_partial_update() {} + pub fn sync(&self) -> sync { + let Self { + client, + akvintegration_pk, + id, + } = self; + sync { + client, + akvintegration_pk, + id, + } + } +} +pub struct pushes { + client: Arc, + akvintegration_pk: &str, +} +impl pushes { + pub fn integrations_azure_key_vault_pushes_list() {} + pub fn integrations_azure_key_vault_pushes_create() {} + pub fn akvpush_pk(&self, akvpush_pk: &str) -> akvpush_pk { + let Self { + client, + akvintegration_pk, + } = self; + akvpush_pk { + client, + akvintegration_pk, + akvpush_pk, + } + } + pub fn id(&self, id: &str) -> id { + let Self { + client, + akvintegration_pk, + } = self; + id { + client, + akvintegration_pk, + id, + } + } +} +pub struct akvintegration_pk { + client: Arc, + akvintegration_pk: &str, +} +impl akvintegration_pk { + pub fn pulls(&self) -> pulls { + let Self { + client, + akvintegration_pk, + } = self; + pulls { + client, + akvintegration_pk, + } + } + pub fn pushes(&self) -> pushes { + let Self { + client, + akvintegration_pk, + } = self; + pushes { + client, + akvintegration_pk, + } + } +} pub struct CloudtruthSdk { - pub client: Arc, + client: Arc, } - impl CloudtruthSdk { - fn new() -> CloudtruthSdk { + fn new() -> Self { CloudtruthSdk { client: Arc::new(Client::new()), } } - pub fn instance() -> &'static CloudtruthSdk { + pub fn instance() -> &'static Self { static ONCE: OnceCell = OnceCell::new(); ONCE.get_or_init(CloudtruthSdk::new) } + pub fn integrations(&self) -> integrations { + let Self { client } = self; + integrations { client } + } +} +pub struct integrations { + client: Arc, +} +impl integrations { + pub fn azure(&self) -> azure { + let Self { client } = self; + azure { client } + } +} +pub struct azure { + client: Arc, +} +impl azure { + pub fn key_vault(&self) -> key_vault { + let Self { client } = self; + key_vault { client } + } +} +pub struct key_vault { + client: Arc, +} +impl key_vault { + pub fn integrations_azure_key_vault_list() {} + pub fn integrations_azure_key_vault_create() {} + pub fn akvintegration_pk(&self, akvintegration_pk: &str) -> akvintegration_pk { + let Self { client } = self; + akvintegration_pk { + client, + akvintegration_pk, + } + } + pub fn id(&self, id: &str) -> id { + let Self { client } = self; + id { client, id } + } +} +pub struct id { + client: Arc, + id: &str, +} +impl id { + pub fn integrations_azure_key_vault_retrieve() {} + pub fn integrations_azure_key_vault_update() {} + pub fn integrations_azure_key_vault_destroy() {} + pub fn integrations_azure_key_vault_partial_update() {} + pub fn scan(&self) -> scan { + let Self { client, id } = self; + scan { client, id } + } +} +pub struct scan { + client: Arc, + id: &str, +} +impl scan { + pub fn integrations_azure_key_vault_scan_create() {} } From b98a2963569090c5bd44892de752210be1483292 Mon Sep 17 00:00:00 2001 From: Adam Curtis Date: Wed, 12 Jul 2023 16:09:02 -0400 Subject: [PATCH 13/13] change generated names to match Rust code conventions --- .../cloudtruth-sdk-codegen/src/generator.rs | 23 +- crates/cloudtruth-sdk-codegen/src/lib.rs | 15 +- crates/cloudtruth-sdk-codegen/src/module.rs | 17 +- crates/cloudtruth-sdk-codegen/src/names.rs | 28 + .../src/sdk/methods/api_method.rs | 27 +- .../src/sdk/methods/child_constructor.rs | 23 +- .../src/sdk/methods/root_constructors.rs | 4 +- .../cloudtruth-sdk-codegen/src/sdk/object.rs | 37 +- crates/cloudtruth-sdk/Cargo.toml | 2 +- crates/cloudtruth-sdk/src/lib.rs | 539 ++++++++++-------- 10 files changed, 430 insertions(+), 285 deletions(-) create mode 100644 crates/cloudtruth-sdk-codegen/src/names.rs diff --git a/crates/cloudtruth-sdk-codegen/src/generator.rs b/crates/cloudtruth-sdk-codegen/src/generator.rs index 10bee4da..06dd00b3 100644 --- a/crates/cloudtruth-sdk-codegen/src/generator.rs +++ b/crates/cloudtruth-sdk-codegen/src/generator.rs @@ -82,31 +82,38 @@ impl SdkGenerator { } else { child_segment.to_string() }; + // append this path segment to current prefix + let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; + let segment_end = segment_start + child_segment.len(); + let path = &uri[..segment_end]; + // get parent object let size = ancestors.len(); let parent_object = ancestors.get_mut(size - 1).map(|(_, obj)| obj); - let mut current_object = SdkObject::new(name.as_str(), parent_object.as_deref()); + // create SDK obect for this node + let mut current_object = SdkObject::new( + path.strip_prefix(&self.root_prefix).unwrap(), + parent_object.as_deref(), + ); + // attach struct field for the path variable if is_path_var { - current_object.add_field(&name, parse_quote![&str]); + current_object.add_field(&name, parse_quote![Arc]); } // attach getter method to parent object if let Some(parent_object) = parent_object { let mut method = SdkChildConstructor::new(parent_object, ¤t_object); if is_path_var { - method.add_arg(&name, parse_quote![&str]); + method.add_arg(&name, parse_quote![impl Into>]); } parent_object.add_method(method); } - // append this path segment to current prefix - let segment_start = child_segment.as_ptr() as usize - uri.as_ptr() as usize; - let segment_end = segment_start + child_segment.len(); - let path = &uri[..segment_end]; + // add to ancestors stack ancestors.push((path, current_object)); } let size = ancestors.len(); if let Some((_, last_object)) = ancestors.get_mut(size - 1) { - last_object.add_method(SdkApiMethod::new(op.clone())); + last_object.add_method(SdkApiMethod::new(uri, op.clone())); } } diff --git a/crates/cloudtruth-sdk-codegen/src/lib.rs b/crates/cloudtruth-sdk-codegen/src/lib.rs index a742a8b7..b34eece2 100644 --- a/crates/cloudtruth-sdk-codegen/src/lib.rs +++ b/crates/cloudtruth-sdk-codegen/src/lib.rs @@ -1,6 +1,7 @@ pub mod api; pub mod generator; pub mod module; +mod names; pub mod sdk; use api::ApiSpec; @@ -10,13 +11,24 @@ use module::SdkModule; use openapiv3::OpenAPI; use quote::quote; -#[macro_export] macro_rules! sdk_path { ($($path:expr),* $(,)?) => { std::path::Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../cloudtruth-sdk/", $($path),*)) }; } +pub(crate) use sdk_path; + +/// Shorthand to quickly create an Ident with call_site macro hygiene +/// Since this is a codegen project, macro hygiene isn't very important for us(?) +macro_rules! ident { + ($path:expr) => { + proc_macro2::Ident::new(&*($path), proc_macro2::Span::call_site()) + }; +} + +pub(crate) use ident; + pub fn generate_sdk() -> Result<()> { let data = include_str!("../../../openapi.json"); let open_api: OpenAPI = serde_json::from_str(data).unwrap(); @@ -27,7 +39,6 @@ pub fn generate_sdk() -> Result<()> { SdkModule::new( sdk_path!("src/lib.rs"), quote! { - use std::sync::Arc; #(#objects )* }, ) diff --git a/crates/cloudtruth-sdk-codegen/src/module.rs b/crates/cloudtruth-sdk-codegen/src/module.rs index 31f0efdb..440b9b8e 100644 --- a/crates/cloudtruth-sdk-codegen/src/module.rs +++ b/crates/cloudtruth-sdk-codegen/src/module.rs @@ -2,6 +2,7 @@ use std::{borrow::Cow, fs::File, io::Write, path::Path, process::Command}; use color_eyre::{eyre::Context, Result}; use proc_macro2::TokenStream; +use quote::quote; #[derive(Debug, Clone)] pub struct SdkModule { @@ -17,10 +18,24 @@ impl SdkModule { } } + fn imports(&self) -> TokenStream { + quote! { + use std::sync::Arc; + use once_cell::sync::OnceCell; + use reqwest::blocking::Client; + } + } + pub fn write(&self) -> Result<()> { + let imports = self.imports(); + let tokens = &self.tokens; + let output = quote! { + #imports + #tokens + }; File::create(self.path.as_ref()) .with_context(move || format!("Could not open: {}", self.path.display()))? - .write_all(self.tokens.to_string().as_bytes())?; + .write_all(output.to_string().as_bytes())?; Command::new("rustfmt") .arg(self.path.as_os_str()) .spawn()? diff --git a/crates/cloudtruth-sdk-codegen/src/names.rs b/crates/cloudtruth-sdk-codegen/src/names.rs new file mode 100644 index 00000000..df8621df --- /dev/null +++ b/crates/cloudtruth-sdk-codegen/src/names.rs @@ -0,0 +1,28 @@ +// Converts a URL with snake_case path segments to PascalCase. +// Forward slashes and underscores are converted to capitalized names +// braces from path variables are ignored +pub fn convert_url_to_type_name(url: &str) -> String { + let mut pascal = String::new(); + let mut capitalize = true; + for ch in url.chars() { + if ch == '{' || ch == '}' { + continue; + } else if ch == '_' || ch == '/' { + capitalize = true; + } else if capitalize { + pascal.push(ch.to_ascii_uppercase()); + capitalize = false; + } else { + pascal.push(ch); + } + } + pascal +} + +// Remove curly brackets from a path variable of them form "{name}" +// If no brackets, string is returned as-is +pub fn trim_path_var_brackets(s: &str) -> &str { + s.strip_prefix('{') + .and_then(|s| s.strip_suffix('}')) + .unwrap_or(s) +} diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs index 120b853d..d53cd845 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/api_method.rs @@ -1,31 +1,46 @@ use std::rc::Rc; -use proc_macro2::{Ident, Span}; use syn::parse_quote; use crate::api::ApiOperation; +use crate::{ident, names}; use super::SdkMethod; #[derive(Debug, Clone)] pub struct SdkApiMethod { api_op: Rc, + fn_name: Rc, } impl SdkApiMethod { - pub fn new(api_op: impl Into>) -> Self { + pub fn new(url_path: impl AsRef, api_op: impl Into>) -> Self { let api_op = api_op.into(); - SdkApiMethod { api_op } + let fn_name = Self::create_method_name(url_path.as_ref(), &api_op); + SdkApiMethod { api_op, fn_name } } - fn name(&self) -> &Rc { - self.api_op.operation_id().unwrap() + fn create_method_name(url_path: &str, api_op: &ApiOperation) -> Rc { + let op_id_parts = api_op.operation_id().unwrap().split('_'); + let path_parts = url_path + .split(|c| c == '/' || c == '_') + .map(names::trim_path_var_brackets) + .collect::>(); + op_id_parts + .filter(|op_id_part| !path_parts.contains(op_id_part)) + .collect::>() + .join("_") + .into() + } + + fn fn_name(&self) -> &Rc { + &self.fn_name } } impl SdkMethod for SdkApiMethod { fn generate_fn(&self) -> syn::ItemFn { - let name = Ident::new(self.name(), Span::call_site()); + let name = ident!(self.fn_name()); parse_quote! { pub fn #name() { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs index 29aec032..89e61b9b 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/child_constructor.rs @@ -1,14 +1,17 @@ -use proc_macro2::{Ident, Span}; +use std::rc::Rc; + +use proc_macro2::Ident; use syn::{parse_quote, Field, FnArg, Type}; +use crate::ident; use crate::sdk::SdkObject; use super::SdkMethod; #[derive(Clone)] pub struct SdkChildConstructor { - name: Ident, - child_name: Ident, + fn_name: Rc, + child_type_name: Rc, parent_fields: Vec, args: Vec<(Ident, Type)>, } @@ -16,8 +19,8 @@ pub struct SdkChildConstructor { impl SdkChildConstructor { pub fn new(parent: &SdkObject, child: &SdkObject) -> Self { Self { - name: child.name().clone(), - child_name: child.name().clone(), + fn_name: child.name().clone(), + child_type_name: child.type_name().clone(), parent_fields: parent .fields() .iter() @@ -28,7 +31,7 @@ impl SdkChildConstructor { } pub fn add_arg(&mut self, arg_name: &str, arg_type: Type) { - let arg_name = Ident::new(arg_name, Span::call_site()); + let arg_name = ident!(arg_name); self.args.push((arg_name, arg_type)); } } @@ -36,8 +39,8 @@ impl SdkChildConstructor { impl SdkMethod for SdkChildConstructor { fn generate_fn(&self) -> syn::ItemFn { let Self { - name, - child_name, + fn_name, + child_type_name, parent_fields, args, } = self; @@ -46,9 +49,9 @@ impl SdkMethod for SdkChildConstructor { .iter() .map::(|(name, ty)| parse_quote!( #name : #ty )); parse_quote! { - pub fn #name(&self, #(#args,)*) -> #child_name { + pub fn #fn_name(&self, #(#args,)*) -> #child_type_name { let Self { #(#parent_fields,)* } = self; - #child_name { #(#parent_fields,)* #(#arg_names,)* } + #child_type_name { #(#parent_fields: #parent_fields.clone(),)* #(#arg_names: #arg_names.into(),)* } } } } diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs index 88bf49c4..485892fc 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/methods/root_constructors.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use proc_macro2::Ident; use syn::parse_quote; @@ -7,7 +9,7 @@ use super::SdkMethod; #[derive(Clone)] pub struct SdkRootConstructor { - name: Ident, + name: Rc, } impl SdkRootConstructor { diff --git a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs index d4bf7864..03925dbf 100644 --- a/crates/cloudtruth-sdk-codegen/src/sdk/object.rs +++ b/crates/cloudtruth-sdk-codegen/src/sdk/object.rs @@ -1,21 +1,33 @@ -use proc_macro2::{Span, TokenStream}; +use std::rc::Rc; + +use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use syn::{parse_quote, punctuated::Punctuated, token::Comma, Field, Ident, Type}; +use crate::ident; +use crate::names; + use super::methods::SdkMethod; #[derive(Clone)] pub struct SdkObject { - name: Ident, + name: Rc, + type_name: Rc, fields: Punctuated, methods: Vec>, } impl SdkObject { - pub fn new(name: impl AsRef, parent: Option<&SdkObject>) -> Self { + pub fn new(url_path: impl AsRef, parent: Option<&SdkObject>) -> Self { + let url_path = url_path.as_ref(); let mut object = Self { - name: Ident::new(name.as_ref(), Span::call_site()), + type_name: Rc::new(ident!(names::convert_url_to_type_name(url_path))), + name: Rc::new(ident!(url_path + .split('/') + .map(names::trim_path_var_brackets) + .last() + .unwrap())), methods: Vec::new(), fields: Punctuated::new(), }; @@ -28,10 +40,16 @@ impl SdkObject { object } - pub fn name(&self) -> &Ident { + /// Returns the name as-is (usually snake_case but depends on naming convention of API) + pub fn name(&self) -> &Rc { &self.name } + /// Returns the name to be used in a Rust type (i.e. PascalCase) + pub fn type_name(&self) -> &Rc { + &self.type_name + } + pub fn methods(&self) -> &[Box] { &self.methods } @@ -46,7 +64,7 @@ impl SdkObject { } pub fn add_field(&mut self, name: &str, field_type: Type) -> &mut Self { - self.add_field_ident(Ident::new(name, Span::call_site()), field_type) + self.add_field_ident(ident!(name), field_type) } pub fn add_field_ident(&mut self, ident: Ident, field_type: Type) -> &mut Self { @@ -65,15 +83,16 @@ impl SdkObject { impl ToTokens for SdkObject { fn to_tokens(&self, tokens: &mut TokenStream) { let SdkObject { - name, + type_name, methods, fields, + .. } = self; tokens.extend(quote! { - pub struct #name { + pub struct #type_name { #fields } - impl #name { + impl #type_name { #(#methods)* } }); diff --git a/crates/cloudtruth-sdk/Cargo.toml b/crates/cloudtruth-sdk/Cargo.toml index 6dafcafb..f84e0b7e 100644 --- a/crates/cloudtruth-sdk/Cargo.toml +++ b/crates/cloudtruth-sdk/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" [dependencies] once_cell = "1.18.0" -reqwest = { version = "0.11.18", features = ["rustls-tls-native-roots", "json", "gzip"] } +reqwest = { version = "0.11.18", features = ["rustls-tls-native-roots", "json", "gzip", "blocking"] } diff --git a/crates/cloudtruth-sdk/src/lib.rs b/crates/cloudtruth-sdk/src/lib.rs index 250bc151..78b41891 100644 --- a/crates/cloudtruth-sdk/src/lib.rs +++ b/crates/cloudtruth-sdk/src/lib.rs @@ -1,385 +1,415 @@ +use once_cell::sync::OnceCell; +use reqwest::blocking::Client; use std::sync::Arc; -pub struct id { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkStepsId { client: Arc, - akvintegration_pk: &str, - akvpull_pk: &str, - akvpulltask_pk: &str, - id: &str, + akvintegration_pk: Arc, + akvpull_pk: Arc, + akvpulltask_pk: Arc, + id: Arc, } -impl id { - pub fn integrations_azure_key_vault_pulls_tasks_steps_retrieve() {} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkStepsId { + pub fn retrieve() {} } -pub struct steps { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkSteps { client: Arc, - akvintegration_pk: &str, - akvpull_pk: &str, - akvpulltask_pk: &str, -} -impl steps { - pub fn integrations_azure_key_vault_pulls_tasks_steps_list() {} - pub fn id(&self, id: &str) -> id { + akvintegration_pk: Arc, + akvpull_pk: Arc, + akvpulltask_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkSteps { + pub fn list() {} + pub fn id( + &self, + id: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkStepsId { let Self { client, akvintegration_pk, akvpull_pk, akvpulltask_pk, } = self; - id { - client, - akvintegration_pk, - akvpull_pk, - akvpulltask_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkStepsId { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpull_pk: akvpull_pk.clone(), + akvpulltask_pk: akvpulltask_pk.clone(), + id: id.into(), } } } -pub struct akvpulltask_pk { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPk { client: Arc, - akvintegration_pk: &str, - akvpull_pk: &str, - akvpulltask_pk: &str, -} -impl akvpulltask_pk { - pub fn steps(&self) -> steps { + akvintegration_pk: Arc, + akvpull_pk: Arc, + akvpulltask_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPk { + pub fn steps( + &self, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkSteps { let Self { client, akvintegration_pk, akvpull_pk, akvpulltask_pk, } = self; - steps { - client, - akvintegration_pk, - akvpull_pk, - akvpulltask_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPkSteps { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpull_pk: akvpull_pk.clone(), + akvpulltask_pk: akvpulltask_pk.clone(), } } } -pub struct id { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksId { client: Arc, - akvintegration_pk: &str, - akvpull_pk: &str, - id: &str, + akvintegration_pk: Arc, + akvpull_pk: Arc, + id: Arc, } -impl id { - pub fn integrations_azure_key_vault_pulls_tasks_retrieve() {} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksId { + pub fn retrieve() {} } -pub struct tasks { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasks { client: Arc, - akvintegration_pk: &str, - akvpull_pk: &str, -} -impl tasks { - pub fn integrations_azure_key_vault_pulls_tasks_list() {} - pub fn akvpulltask_pk(&self, akvpulltask_pk: &str) -> akvpulltask_pk { + akvintegration_pk: Arc, + akvpull_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasks { + pub fn list() {} + pub fn akvpulltask_pk( + &self, + akvpulltask_pk: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPk { let Self { client, akvintegration_pk, akvpull_pk, } = self; - akvpulltask_pk { - client, - akvintegration_pk, - akvpull_pk, - akvpulltask_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksAkvpulltaskPk { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpull_pk: akvpull_pk.clone(), + akvpulltask_pk: akvpulltask_pk.into(), } } - pub fn id(&self, id: &str) -> id { + pub fn id( + &self, + id: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksId { let Self { client, akvintegration_pk, akvpull_pk, } = self; - id { - client, - akvintegration_pk, - akvpull_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasksId { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpull_pk: akvpull_pk.clone(), + id: id.into(), } } } -pub struct akvpull_pk { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPk { client: Arc, - akvintegration_pk: &str, - akvpull_pk: &str, + akvintegration_pk: Arc, + akvpull_pk: Arc, } -impl akvpull_pk { - pub fn tasks(&self) -> tasks { +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPk { + pub fn tasks(&self) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasks { let Self { client, akvintegration_pk, akvpull_pk, } = self; - tasks { - client, - akvintegration_pk, - akvpull_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPkTasks { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpull_pk: akvpull_pk.clone(), } } } -pub struct sync { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsIdSync { client: Arc, - akvintegration_pk: &str, - id: &str, + akvintegration_pk: Arc, + id: Arc, } -impl sync { - pub fn integrations_azure_key_vault_pulls_sync_create() {} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsIdSync { + pub fn create() {} } -pub struct id { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPullsId { client: Arc, - akvintegration_pk: &str, - id: &str, -} -impl id { - pub fn integrations_azure_key_vault_pulls_retrieve() {} - pub fn integrations_azure_key_vault_pulls_update() {} - pub fn integrations_azure_key_vault_pulls_destroy() {} - pub fn integrations_azure_key_vault_pulls_partial_update() {} - pub fn sync(&self) -> sync { + akvintegration_pk: Arc, + id: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPullsId { + pub fn retrieve() {} + pub fn update() {} + pub fn destroy() {} + pub fn partial_update() {} + pub fn sync(&self) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsIdSync { let Self { client, akvintegration_pk, id, } = self; - sync { - client, - akvintegration_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPullsIdSync { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + id: id.clone(), } } } -pub struct pulls { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPulls { client: Arc, - akvintegration_pk: &str, -} -impl pulls { - pub fn integrations_azure_key_vault_pulls_list() {} - pub fn integrations_azure_key_vault_pulls_create() {} - pub fn akvpull_pk(&self, akvpull_pk: &str) -> akvpull_pk { + akvintegration_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPulls { + pub fn list() {} + pub fn create() {} + pub fn akvpull_pk( + &self, + akvpull_pk: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPk { let Self { client, akvintegration_pk, } = self; - akvpull_pk { - client, - akvintegration_pk, - akvpull_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPullsAkvpullPk { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpull_pk: akvpull_pk.into(), } } - pub fn id(&self, id: &str) -> id { + pub fn id(&self, id: impl Into>) -> IntegrationsAzureKeyVaultAkvintegrationPkPullsId { let Self { client, akvintegration_pk, } = self; - id { - client, - akvintegration_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPullsId { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + id: id.into(), } } } -pub struct id { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkStepsId { client: Arc, - akvintegration_pk: &str, - akvpush_pk: &str, - akvpushtask_pk: &str, - id: &str, + akvintegration_pk: Arc, + akvpush_pk: Arc, + akvpushtask_pk: Arc, + id: Arc, } -impl id { - pub fn integrations_azure_key_vault_pushes_tasks_steps_retrieve() {} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkStepsId { + pub fn retrieve() {} } -pub struct steps { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkSteps { client: Arc, - akvintegration_pk: &str, - akvpush_pk: &str, - akvpushtask_pk: &str, -} -impl steps { - pub fn integrations_azure_key_vault_pushes_tasks_steps_list() {} - pub fn id(&self, id: &str) -> id { + akvintegration_pk: Arc, + akvpush_pk: Arc, + akvpushtask_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkSteps { + pub fn list() {} + pub fn id( + &self, + id: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkStepsId { let Self { client, akvintegration_pk, akvpush_pk, akvpushtask_pk, } = self; - id { - client, - akvintegration_pk, - akvpush_pk, - akvpushtask_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkStepsId { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpush_pk: akvpush_pk.clone(), + akvpushtask_pk: akvpushtask_pk.clone(), + id: id.into(), } } } -pub struct akvpushtask_pk { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPk { client: Arc, - akvintegration_pk: &str, - akvpush_pk: &str, - akvpushtask_pk: &str, -} -impl akvpushtask_pk { - pub fn steps(&self) -> steps { + akvintegration_pk: Arc, + akvpush_pk: Arc, + akvpushtask_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPk { + pub fn steps( + &self, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkSteps { let Self { client, akvintegration_pk, akvpush_pk, akvpushtask_pk, } = self; - steps { - client, - akvintegration_pk, - akvpush_pk, - akvpushtask_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPkSteps { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpush_pk: akvpush_pk.clone(), + akvpushtask_pk: akvpushtask_pk.clone(), } } } -pub struct id { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksId { client: Arc, - akvintegration_pk: &str, - akvpush_pk: &str, - id: &str, + akvintegration_pk: Arc, + akvpush_pk: Arc, + id: Arc, } -impl id { - pub fn integrations_azure_key_vault_pushes_tasks_retrieve() {} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksId { + pub fn retrieve() {} } -pub struct tasks { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasks { client: Arc, - akvintegration_pk: &str, - akvpush_pk: &str, -} -impl tasks { - pub fn integrations_azure_key_vault_pushes_tasks_list() {} - pub fn akvpushtask_pk(&self, akvpushtask_pk: &str) -> akvpushtask_pk { + akvintegration_pk: Arc, + akvpush_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasks { + pub fn list() {} + pub fn akvpushtask_pk( + &self, + akvpushtask_pk: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPk { let Self { client, akvintegration_pk, akvpush_pk, } = self; - akvpushtask_pk { - client, - akvintegration_pk, - akvpush_pk, - akvpushtask_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksAkvpushtaskPk { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpush_pk: akvpush_pk.clone(), + akvpushtask_pk: akvpushtask_pk.into(), } } - pub fn id(&self, id: &str) -> id { + pub fn id( + &self, + id: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksId { let Self { client, akvintegration_pk, akvpush_pk, } = self; - id { - client, - akvintegration_pk, - akvpush_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasksId { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpush_pk: akvpush_pk.clone(), + id: id.into(), } } } -pub struct akvpush_pk { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPk { client: Arc, - akvintegration_pk: &str, - akvpush_pk: &str, + akvintegration_pk: Arc, + akvpush_pk: Arc, } -impl akvpush_pk { - pub fn tasks(&self) -> tasks { +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPk { + pub fn tasks(&self) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasks { let Self { client, akvintegration_pk, akvpush_pk, } = self; - tasks { - client, - akvintegration_pk, - akvpush_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPkTasks { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpush_pk: akvpush_pk.clone(), } } } -pub struct sync { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesIdSync { client: Arc, - akvintegration_pk: &str, - id: &str, + akvintegration_pk: Arc, + id: Arc, } -impl sync { - pub fn integrations_azure_key_vault_pushes_sync_create() {} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesIdSync { + pub fn create() {} } -pub struct id { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushesId { client: Arc, - akvintegration_pk: &str, - id: &str, -} -impl id { - pub fn integrations_azure_key_vault_pushes_retrieve() {} - pub fn integrations_azure_key_vault_pushes_update() {} - pub fn integrations_azure_key_vault_pushes_destroy() {} - pub fn integrations_azure_key_vault_pushes_partial_update() {} - pub fn sync(&self) -> sync { + akvintegration_pk: Arc, + id: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushesId { + pub fn retrieve() {} + pub fn update() {} + pub fn destroy() {} + pub fn partial_update() {} + pub fn sync(&self) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesIdSync { let Self { client, akvintegration_pk, id, } = self; - sync { - client, - akvintegration_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPushesIdSync { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + id: id.clone(), } } } -pub struct pushes { +pub struct IntegrationsAzureKeyVaultAkvintegrationPkPushes { client: Arc, - akvintegration_pk: &str, -} -impl pushes { - pub fn integrations_azure_key_vault_pushes_list() {} - pub fn integrations_azure_key_vault_pushes_create() {} - pub fn akvpush_pk(&self, akvpush_pk: &str) -> akvpush_pk { + akvintegration_pk: Arc, +} +impl IntegrationsAzureKeyVaultAkvintegrationPkPushes { + pub fn list() {} + pub fn create() {} + pub fn akvpush_pk( + &self, + akvpush_pk: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPk { let Self { client, akvintegration_pk, } = self; - akvpush_pk { - client, - akvintegration_pk, - akvpush_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPushesAkvpushPk { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + akvpush_pk: akvpush_pk.into(), } } - pub fn id(&self, id: &str) -> id { + pub fn id(&self, id: impl Into>) -> IntegrationsAzureKeyVaultAkvintegrationPkPushesId { let Self { client, akvintegration_pk, } = self; - id { - client, - akvintegration_pk, - id, + IntegrationsAzureKeyVaultAkvintegrationPkPushesId { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), + id: id.into(), } } } -pub struct akvintegration_pk { +pub struct IntegrationsAzureKeyVaultAkvintegrationPk { client: Arc, - akvintegration_pk: &str, + akvintegration_pk: Arc, } -impl akvintegration_pk { - pub fn pulls(&self) -> pulls { +impl IntegrationsAzureKeyVaultAkvintegrationPk { + pub fn pulls(&self) -> IntegrationsAzureKeyVaultAkvintegrationPkPulls { let Self { client, akvintegration_pk, } = self; - pulls { - client, - akvintegration_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPulls { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), } } - pub fn pushes(&self) -> pushes { + pub fn pushes(&self) -> IntegrationsAzureKeyVaultAkvintegrationPkPushes { let Self { client, akvintegration_pk, } = self; - pushes { - client, - akvintegration_pk, + IntegrationsAzureKeyVaultAkvintegrationPkPushes { + client: client.clone(), + akvintegration_pk: akvintegration_pk.clone(), } } } @@ -396,65 +426,80 @@ impl CloudtruthSdk { static ONCE: OnceCell = OnceCell::new(); ONCE.get_or_init(CloudtruthSdk::new) } - pub fn integrations(&self) -> integrations { + pub fn integrations(&self) -> Integrations { let Self { client } = self; - integrations { client } + Integrations { + client: client.clone(), + } } } -pub struct integrations { +pub struct Integrations { client: Arc, } -impl integrations { - pub fn azure(&self) -> azure { +impl Integrations { + pub fn azure(&self) -> IntegrationsAzure { let Self { client } = self; - azure { client } + IntegrationsAzure { + client: client.clone(), + } } } -pub struct azure { +pub struct IntegrationsAzure { client: Arc, } -impl azure { - pub fn key_vault(&self) -> key_vault { +impl IntegrationsAzure { + pub fn key_vault(&self) -> IntegrationsAzureKeyVault { let Self { client } = self; - key_vault { client } + IntegrationsAzureKeyVault { + client: client.clone(), + } } } -pub struct key_vault { +pub struct IntegrationsAzureKeyVault { client: Arc, } -impl key_vault { - pub fn integrations_azure_key_vault_list() {} - pub fn integrations_azure_key_vault_create() {} - pub fn akvintegration_pk(&self, akvintegration_pk: &str) -> akvintegration_pk { +impl IntegrationsAzureKeyVault { + pub fn list() {} + pub fn create() {} + pub fn akvintegration_pk( + &self, + akvintegration_pk: impl Into>, + ) -> IntegrationsAzureKeyVaultAkvintegrationPk { let Self { client } = self; - akvintegration_pk { - client, - akvintegration_pk, + IntegrationsAzureKeyVaultAkvintegrationPk { + client: client.clone(), + akvintegration_pk: akvintegration_pk.into(), } } - pub fn id(&self, id: &str) -> id { + pub fn id(&self, id: impl Into>) -> IntegrationsAzureKeyVaultId { let Self { client } = self; - id { client, id } + IntegrationsAzureKeyVaultId { + client: client.clone(), + id: id.into(), + } } } -pub struct id { +pub struct IntegrationsAzureKeyVaultId { client: Arc, - id: &str, -} -impl id { - pub fn integrations_azure_key_vault_retrieve() {} - pub fn integrations_azure_key_vault_update() {} - pub fn integrations_azure_key_vault_destroy() {} - pub fn integrations_azure_key_vault_partial_update() {} - pub fn scan(&self) -> scan { + id: Arc, +} +impl IntegrationsAzureKeyVaultId { + pub fn retrieve() {} + pub fn update() {} + pub fn destroy() {} + pub fn partial_update() {} + pub fn scan(&self) -> IntegrationsAzureKeyVaultIdScan { let Self { client, id } = self; - scan { client, id } + IntegrationsAzureKeyVaultIdScan { + client: client.clone(), + id: id.clone(), + } } } -pub struct scan { +pub struct IntegrationsAzureKeyVaultIdScan { client: Arc, - id: &str, + id: Arc, } -impl scan { - pub fn integrations_azure_key_vault_scan_create() {} +impl IntegrationsAzureKeyVaultIdScan { + pub fn create() {} }