wadl-0.1.4/.cargo_vcs_info.json0000644000000001360000000000100117650ustar { "git": { "sha1": "dd19c22d3e41c56f76a01f0bdec64eef7ae5d130" }, "path_in_vcs": "" }wadl-0.1.4/.github/workflows/rust.yml000064400000000000000000000004121046102023000156670ustar 00000000000000name: Rust on: push: pull_request: env: CARGO_TERM_COLOR: always jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Build run: cargo build --verbose - name: Run tests run: cargo test --verbose wadl-0.1.4/.gitignore000064400000000000000000000000121046102023000125360ustar 00000000000000*~ target wadl-0.1.4/Cargo.lock0000644000001003350000000000100077420ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "addr2line" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "anstream" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys", ] [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", ] [[package]] name = "base64" version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "bumpalo" version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "core-foundation" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "encoding_rs" version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] [[package]] name = "env_logger" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "humantime", "is-terminal", "log", "regex", "termcolor", ] [[package]] name = "errno" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ "libc", "windows-sys", ] [[package]] name = "fastrand" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "futures-channel" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", ] [[package]] name = "futures-core" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-sink" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-task", "pin-project-lite", "pin-utils", ] [[package]] name = "gimli" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", "http", "indexmap", "slab", "tokio", "tokio-util", "tracing", ] [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "http" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", "itoa", ] [[package]] name = "http-body" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", "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.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", "http", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", "socket2 0.4.10", "tokio", "tower-service", "tracing", "want", ] [[package]] name = "hyper-tls" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", "hyper", "native-tls", "tokio", "tokio-native-tls", ] [[package]] name = "idna" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", ] [[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.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", "rustix", "windows-sys", ] [[package]] name = "itoa" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "linux-raw-sys" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi", "windows-sys", ] [[package]] name = "native-tls" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", "log", "openssl", "openssl-probe", "openssl-sys", "schannel", "security-framework", "security-framework-sys", "tempfile", ] [[package]] name = "object" version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", "once_cell", "openssl-macros", "openssl-sys", ] [[package]] name = "openssl-macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", "pkg-config", "vcpkg", ] [[package]] name = "percent-encoding" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "proc-macro2" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", "http", "http-body", "hyper", "hyper-tls", "ipnet", "js-sys", "log", "mime", "native-tls", "once_cell", "percent-encoding", "pin-project-lite", "serde", "serde_json", "serde_urlencoded", "system-configuration", "tokio", "tokio-native-tls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", "winreg", ] [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" version = "0.38.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" dependencies = [ "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", "windows-sys", ] [[package]] name = "ryu" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schannel" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ "windows-sys", ] [[package]] name = "security-framework" version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "serde" version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "serde_urlencoded" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", "itoa", "ryu", "serde", ] [[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "socket2" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", ] [[package]] name = "socket2" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys", ] [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "system-configuration" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", ] [[package]] name = "tempfile" version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", "redox_syscall", "rustix", "windows-sys", ] [[package]] name = "termcolor" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "tinyvec" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", "libc", "mio", "pin-project-lite", "socket2 0.5.5", "windows-sys", ] [[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", ] [[package]] name = "tokio-util" version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", "tracing", ] [[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.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "try-lock" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "unicode-bidi" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "url" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "wadl" version = "0.1.4" dependencies = [ "clap", "env_logger", "lazy_static", "log", "mime", "proc-macro2", "quote", "reqwest", "serde_json", "syn", "url", "xmltree", ] [[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.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", "windows-sys", ] [[package]] name = "xml-rs" version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" [[package]] name = "xmltree" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" dependencies = [ "xml-rs", ] wadl-0.1.4/Cargo.toml0000644000000030550000000000100077660ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "wadl" version = "0.1.4" authors = ["Jelmer Vernooij "] default-run = "wadlc" description = "A WADL parser for Rust" readme = "README.md" license = "Apache-2.0" repository = "https://github.com/jelmer/wadl-rs" [[bin]] name = "wadlc" path = "src/bin/wadlc.rs" required-features = ["cli"] [dependencies.clap] version = "4.4.6" features = [ "derive", "env", ] optional = true [dependencies.env_logger] version = "0.10.0" optional = true [dependencies.lazy_static] version = "1.4.0" [dependencies.log] version = "0.4.20" [dependencies.mime] version = "0.3.17" [dependencies.proc-macro2] version = "1" optional = true [dependencies.quote] version = "1" optional = true [dependencies.reqwest] version = "0.11.22" [dependencies.serde_json] version = "1.0.107" [dependencies.syn] version = "2" optional = true [dependencies.url] version = "2.4" [dependencies.xmltree] version = "0.10.3" [features] cli = [ "dep:clap", "dep:env_logger", "codegen", ] codegen = [ "dep:proc-macro2", "dep:quote", "dep:syn", ] default = ["cli"] wadl-0.1.4/Cargo.toml.orig0000644000000015300000000000100107210ustar [package] name = "wadl" version = "0.1.4" edition = "2021" license = "Apache-2.0" description = "A WADL parser for Rust" repository = "https://github.com/jelmer/wadl-rs" authors = ["Jelmer Vernooij "] default-run = "wadlc" [dependencies] clap = { version = "4.4.6", features = ["derive", "env"], optional = true } env_logger = { version = "0.10.0", optional = true } lazy_static = "1.4.0" log = "0.4.20" mime = "0.3.17" proc-macro2 = { version = "1", optional = true } quote = { version = "1", optional = true } reqwest = "0.11.22" serde_json = "1.0.107" syn = { version = "2", optional = true } url = "2.4" xmltree = "0.10.3" [features] default = ["cli"] codegen = ["dep:proc-macro2", "dep:quote", "dep:syn"] cli = ["dep:clap", "dep:env_logger", "codegen"] [[bin]] name = "wadlc" path = "src/bin/wadlc.rs" required-features = ["cli"] wadl-0.1.4/Cargo.toml.orig000064400000000000000000000015301046102023000134430ustar 00000000000000[package] name = "wadl" version = "0.1.4" edition = "2021" license = "Apache-2.0" description = "A WADL parser for Rust" repository = "https://github.com/jelmer/wadl-rs" authors = ["Jelmer Vernooij "] default-run = "wadlc" [dependencies] clap = { version = "4.4.6", features = ["derive", "env"], optional = true } env_logger = { version = "0.10.0", optional = true } lazy_static = "1.4.0" log = "0.4.20" mime = "0.3.17" proc-macro2 = { version = "1", optional = true } quote = { version = "1", optional = true } reqwest = "0.11.22" serde_json = "1.0.107" syn = { version = "2", optional = true } url = "2.4" xmltree = "0.10.3" [features] default = ["cli"] codegen = ["dep:proc-macro2", "dep:quote", "dep:syn"] cli = ["dep:clap", "dep:env_logger", "codegen"] [[bin]] name = "wadlc" path = "src/bin/wadlc.rs" required-features = ["cli"] wadl-0.1.4/README.md000064400000000000000000000003401046102023000120310ustar 00000000000000This crate contains a parser for the [Web Application Description Language (WADL)](https://www.w3.org/submissions/wadl/). It can also generate basic rust bindings based on WADL files, if the ``codegen`` feature is enabled. wadl-0.1.4/disperse.conf000064400000000000000000000001231046102023000132360ustar 00000000000000timeout_days: 5 tag_name: "v$VERSION" github_url: "https://github.com/jelmer/wadl" wadl-0.1.4/src/ast.rs000064400000000000000000000133171046102023000125060ustar 00000000000000use std::collections::HashMap; use url::Url; pub type Id = String; #[derive(Debug, PartialEq, Eq, Clone)] pub enum ParamStyle { Plain, Matrix, Query, Header, Template, } /// A WADL application. #[derive(Debug)] pub struct Application { /// Resources defined at the application level. pub resources: Vec, pub resource_types: Vec, /// Documentation for the application. pub docs: Vec, pub grammars: Vec, pub representations: Vec, } impl Application { pub fn get_resource_type_by_id(&self, id: &str) -> Option<&ResourceType> { self.resource_types .iter() .find(|rt| rt.id.as_ref().map(|i| i == id).unwrap_or(false)) } pub fn get_resource_type_by_href(&self, href: &Url) -> Option<&ResourceType> { // TODO(jelmer): Check that href matches us? if let Some(fragment) = href.fragment() { self.get_resource_type_by_id(fragment) } else { None } } } impl std::str::FromStr for Application { type Err = crate::parse::Error; fn from_str(s: &str) -> Result { crate::parse::parse_string(s) } } #[derive(Debug)] pub struct Resources { /// The base URL for the resources. pub base: Option, /// The resources defined at this level. pub resources: Vec, } #[derive(Debug)] pub struct Grammar { pub href: Url, } #[derive(Debug)] pub enum ResourceTypeRef { Id(Id), Link(Url), } impl ResourceTypeRef { pub fn id(&self) -> Option<&str> { match self { ResourceTypeRef::Id(id) => Some(id), ResourceTypeRef::Link(l) => l.fragment(), } } } #[derive(Debug)] pub enum TypeRef { Simple(String), ResourceType(ResourceTypeRef), EmptyLink, NoType, Options(HashMap>), } impl std::str::FromStr for TypeRef { type Err = String; fn from_str(s: &str) -> Result { if let Some(s) = s.strip_prefix('#') { Ok(TypeRef::ResourceType(ResourceTypeRef::Id(s.to_string()))) } else { Ok(TypeRef::Simple(s.to_string())) } } } #[derive(Debug)] pub struct Resource { /// The ID of the resource. pub id: Option, /// The path of the resource. pub path: Option, /// The type of the resource. pub r#type: Option>, /// The query type of the resource. pub query_type: mime::Mime, /// The methods defined at this level. pub methods: Vec, /// The docs for the resource. pub docs: Vec, /// Sub-resources of this resource. pub subresources: Vec, /// The params for this resource. pub params: Vec, } impl Resource { pub fn url(&self, base_url: Option<&Url>) -> Url { if let Some(base_url) = base_url { base_url.join(self.path.as_ref().unwrap()).unwrap() } else { Url::parse(self.path.as_ref().unwrap()).unwrap() } } } #[derive(Debug)] pub struct Method { pub id: Id, pub name: String, pub docs: Vec, pub request: Request, pub responses: Vec, } #[derive(Debug)] pub struct Doc { /// The title of the documentation. pub title: Option, /// The language of the documentation. pub lang: Option, /// The content of the documentation. pub content: String, /// The namespace of the documentation. pub xmlns: Option, } #[derive(Debug)] pub struct Param { pub style: ParamStyle, pub id: Option, pub name: String, pub r#type: TypeRef, pub path: Option, pub required: bool, pub repeating: bool, pub fixed: Option, } #[derive(Debug)] pub struct RepresentationDef { pub id: Option, pub media_type: Option, pub element: Option, pub profile: Option, pub docs: Vec, pub params: Vec, } #[derive(Debug)] pub enum RepresentationRef { /// A reference to a representation defined in the same document. Id(Id), Link(Url), } impl RepresentationRef { pub fn id(&self) -> Option<&str> { match self { RepresentationRef::Id(id) => Some(id), RepresentationRef::Link(l) => l.fragment(), } } } #[derive(Debug)] pub enum Representation { Reference(RepresentationRef), Definition(RepresentationDef), } impl Representation { pub fn url(&self, base_url: &Url) -> Option { match self { Representation::Reference(RepresentationRef::Id(id)) => { let mut url = base_url.clone(); url.set_fragment(Some(id)); Some(url) } Representation::Reference(RepresentationRef::Link(l)) => Some(l.clone()), Representation::Definition(d) => d.url(base_url), } } } impl RepresentationDef { pub fn url(&self, base_url: &Url) -> Option { if let Some(id) = &self.id { let mut url = base_url.clone(); url.set_fragment(Some(id)); Some(url) } else { None } } } #[derive(Debug, Default)] pub struct Request { pub docs: Vec, pub params: Vec, pub representations: Vec, } #[derive(Debug)] pub struct Response { pub docs: Vec, pub params: Vec, pub status: Option, pub representations: Vec, } #[derive(Debug)] pub struct ResourceType { pub id: Option, pub query_type: mime::Mime, pub methods: Vec, pub docs: Vec, pub subresources: Vec, pub params: Vec, } wadl-0.1.4/src/codegen.rs000064400000000000000000000424231046102023000133230ustar 00000000000000use crate::ast::*; // Convert wadl names (with dashes) to camel-case Rust names fn camel_case_name(name: &str) -> String { let mut it = name.chars().peekable(); let mut result = String::new(); // Uppercase the first letter if let Some(c) = it.next() { result.push_str(&c.to_uppercase().collect::()); } while it.peek().is_some() { let c = it.next().unwrap(); if c == '_' || c == '-' { if let Some(next) = it.next() { result.push_str(&next.to_uppercase().collect::()); } } else { result.push(c); } } result } #[test] fn test_camel_case_name() { assert_eq!(camel_case_name("foo-bar"), "FooBar"); assert_eq!(camel_case_name("foo-bar-baz"), "FooBarBaz"); assert_eq!(camel_case_name("foo-bar-baz-quux"), "FooBarBazQuux"); assert_eq!(camel_case_name("_foo-bar"), "_fooBar"); assert_eq!(camel_case_name("service-root-json"), "ServiceRootJson"); } fn snake_case_name(name: &str) -> String { let mut name = name.to_string(); name = name.replace('-', "_"); let mut it = name.chars().peekable(); let mut result = String::new(); while it.peek().is_some() { let c = it.next().unwrap(); if c.is_uppercase() { if !result.is_empty() && !result.ends_with('_') { result.push('_'); } result.push_str(&c.to_lowercase().collect::()); } else { result.push(c); } } result } #[test] fn test_snake_case_name() { assert_eq!(snake_case_name("FooBar"), "foo_bar"); assert_eq!(snake_case_name("FooBarBaz"), "foo_bar_baz"); assert_eq!(snake_case_name("FooBarBazQuux"), "foo_bar_baz_quux"); assert_eq!(snake_case_name("_FooBar"), "_foo_bar"); } fn generate_doc(input: &Doc, indent: usize) -> Vec { let mut lines: Vec = vec![]; if let Some(title) = input.title.as_ref() { lines.extend(vec![format!("/// # {}\n", title), "///\n".to_string()]); } lines.push(if let Some(xmlns) = &input.xmlns { let lang = match xmlns.as_str() { "http://www.w3.org/2001/XMLSchema" => "xml", "http://www.w3.org/1999/xhtml" => "html", _ => { log::warn!("Unknown xmlns: {}", xmlns); "" } }; format!("/// ```{}\n", lang) } else { "/// ```\n".to_string() }); lines.extend(input.content.lines().map(|line| format!("/// {}\n", line))); lines.push("/// ```\n".to_string()); if indent > 0 { lines = lines .into_iter() .map(|line| format!("{:indent$}{}", "", line, indent = indent * 4)) .collect(); } lines } fn generate_representation(input: &RepresentationDef, config: &Config) -> Vec { let mut lines = vec![]; for doc in &input.docs { lines.extend(generate_doc(doc, 0)); } if input.media_type == Some(mime::APPLICATION_JSON) { lines.extend(generate_representation_struct_json(input, config)); } else { panic!("Unknown media type: {:?}", input.media_type); } let name = input.id.as_ref().unwrap().as_str(); let name = camel_case_name(name); lines.push(format!("impl {} {{\n", name)); for param in &input.params { let field_name = snake_case_name(param.name.as_str()); match ¶m.r#type { TypeRef::ResourceType(r) => { let id = r.id().unwrap(); let field_type = camel_case_name(id); let mut ret_type = format!("Box", field_type); if !param.required { ret_type = format!("Option<{}>", ret_type); } lines.push(format!( " pub fn {}(&self) -> Result<{}, Error> {{\n", field_name, ret_type )); lines.push(" struct MyResource(url::Url);\n".to_string()); lines.push(" impl Resource for MyResource { fn url(&self) -> url::Url { self.0.clone() } }\n".to_string()); lines.push(format!(" impl {} for MyResource {{}}\n", field_type)); if param.required { lines.push(format!( " Ok(Box::new(MyResource(self.{}.clone())))\n", field_name )); } else { lines.push(format!( " Ok(self.{}.as_ref().map(|x| Box::new(MyResource(x.clone())) as Box))\n", field_name, field_type )); } lines.push(" }\n".to_string()); lines.push("\n".to_string()); } _ => {} } } lines.push("}\n".to_string()); lines.push("\n".to_string()); lines } fn param_rust_type(param: &Param, config: &Config) -> (String, Vec) { assert!(param.id.is_none()); assert!(param.fixed.is_none()); let (mut param_type, annotations) = match ¶m.r#type { TypeRef::Simple(name) => match name.as_str() { "xsd:date" => ("chrono::NaiveDate".to_string(), vec![]), "xsd:dateTime" => ("chrono::DateTime".to_string(), vec![]), "xsd:time" => ("(chrono::Time".to_string(), vec![]), "string" => ("String".to_string(), vec![]), "binary" => ("Vec".to_string(), vec![]), u => panic!("Unknown type: {}", u), }, TypeRef::EmptyLink => { // This would be a reference to the representation itself ("url::Url".to_string(), vec![]) } TypeRef::ResourceType(_) => ("url::Url".to_string(), vec![]), TypeRef::Options(_options) => { // TODO: define an enum for this ("String".to_string(), vec![]) } TypeRef::NoType => { let tn = if let Some(guess_name) = config.guess_type_name.as_ref() { guess_name(param.name.as_str()) } else { None }; if let Some(tn) = tn { (tn, vec![]) } else { log::warn!("No type for parameter: {}", param.name); ("serde_json::Value".to_string(), vec![]) } } }; if param.repeating { param_type = format!("Vec<{}>", param_type); } if !param.required { param_type = format!("Option<{}>", param_type); } (param_type, annotations) } fn readonly_rust_type(name: &str) -> String { match name { "String" => "&str".to_string(), x if x.starts_with("Option<") && x.ends_with('>') => { format!("Option<&{}>", x[7..x.len() - 1].trim()) } x if x.starts_with("Vec<") && x.ends_with('>') => { format!("&[{}]", x[4..x.len() - 1].trim()) } x => format!("&{}", x), } } fn generate_representation_struct_json(input: &RepresentationDef, config: &Config) -> Vec { let mut lines: Vec = vec![]; let name = input.id.as_ref().unwrap().as_str(); let name = camel_case_name(name); lines.push( "#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]\n".to_string(), ); lines.push(format!("pub struct {} {{\n", name)); for param in &input.params { let mut param_name = snake_case_name(param.name.as_str()); if ["type", "move"].contains(¶m_name.as_str()) { param_name = format!("r#{}", param_name); } let (param_type, annotations) = param_rust_type(param, config); let comment = match ¶m.r#type { TypeRef::Simple(name) => format!("was: {}", name), TypeRef::EmptyLink => "was: empty link".to_string(), TypeRef::ResourceType(r) => match r { ResourceTypeRef::Id(id) => format!("resource type id: {}", id), ResourceTypeRef::Link(href) => format!("resource type link: {}", href), }, TypeRef::Options(options) => format!("options: {:?}", options), TypeRef::NoType => "no type for parameter in WADL".to_string(), }; let is_pub = !matches!(¶m.r#type, TypeRef::ResourceType(_)); lines.push(format!(" // {}\n", comment)); for ann in annotations { lines.push(format!(" {}\n", ann)); } lines.push(format!( " {}{}: {},\n", if is_pub { "pub " } else { "" }, param_name, param_type )); } lines.push("}\n".to_string()); lines.push("\n".to_string()); lines } fn supported_representation_def(d: &RepresentationDef) -> bool { d.media_type != Some("application/vnd.sun.wadl+xml".parse().unwrap()) && d.media_type != Some("application/xhtml+xml".parse().unwrap()) } pub fn rust_type_for_response(input: &Response, name: &str) -> String { let representations = input .representations .iter() .filter(|r| match r { Representation::Definition(ref d) => supported_representation_def(d), _ => true, }) .collect::>(); if representations.len() == 1 { assert!(input.params.is_empty()); match representations[0] { Representation::Reference(ref r) => { let id = r.id().unwrap().to_string(); camel_case_name(id.as_str()) } Representation::Definition(ref d) => { assert!(d.params.iter().all(|p| p.style == ParamStyle::Header)); let mut ret = Vec::new(); for param in &input.params { let (param_type, annotations) = param_rust_type(param, &Config::default()); ret.push(param_type); } if ret.len() == 1 { ret[0].clone() } else { format!("({})", ret.join(", ")) } } } } else if representations.is_empty() { let mut ret = Vec::new(); for param in &input.params { let (param_type, annotations) = param_rust_type(param, &Config::default()); ret.push(param_type); } if ret.len() == 1 { ret[0].clone() } else { format!("({})", ret.join(", ")) } } else { todo!( "multiple representations for response: {}: {:?}", name, representations ); } } pub fn generate_method(input: &Method, parent_id: &str, config: &Config) -> Vec { let mut lines = vec![]; for doc in &input.docs { lines.extend(generate_doc(doc, 1)); } let name = input.id.as_str(); let name = name .strip_prefix(format!("{}-", parent_id).as_str()) .unwrap_or(name); let name = snake_case_name(name); let mut line = format!(" fn {}(&self", name); let mut params = input.request.params.iter().collect::>(); params.extend( input .request .representations .iter() .filter_map(|r| match r { Representation::Definition(d) => Some(&d.params), Representation::Reference(_) => None, }) .flatten(), ); for param in ¶ms { if param.fixed.is_some() { continue; } let (param_type, annotations) = param_rust_type(param, config); let param_type = readonly_rust_type(param_type.as_str()); let mut param_name = param.name.clone(); if ["type", "move"].contains(¶m_name.as_str()) { param_name = format!("r#{}", param_name); } line.push_str(format!(", {}: {}", param_name, param_type).as_str()); } line.push_str(") -> Result<"); if input.responses.is_empty() { line.push_str("()"); } else { assert_eq!(1, input.responses.len(), "expected 1 response for {}", name); line.push_str(rust_type_for_response(&input.responses[0], input.id.as_str()).as_str()); } line.push_str(", Error> {\n"); lines.push(line); assert!(input .request .params .iter() .all(|p| [ParamStyle::Header, ParamStyle::Query].contains(&p.style))); lines.push(" let mut url_ = self.url();\n".to_string()); for param in params.iter().filter(|p| p.style == ParamStyle::Query) { if let Some(fixed) = param.fixed.as_ref() { assert!(!param.repeating); lines.push(format!( " url_.query_pairs_mut().append_pair(\"{}\", \"{}\");\n", param.name, fixed )); } else { let param_name = param.name.as_str(); let mut param_name = snake_case_name(param_name); if ["type", "move"].contains(¶m_name.as_str()) { param_name = format!("r#{}", param_name); } let (param_type, annotations) = param_rust_type(param, config); let value = format!("&{}.to_string()", param_name); let mut indent = 0; let needs_iter = param.repeating || param_type.starts_with("Vec<") || param_type.starts_with("Option 0 { lines.push(format!("{:indent$} }}\n", "", indent = indent)); indent -= 4; } } } lines.push("\n".to_string()); let method = input.name.as_str(); lines.push(format!( " let mut req = reqwest::blocking::Request::new(reqwest::Method::{}, url_);\n", method )); let mime_types = input .responses .iter() .flat_map(|x| { x.representations.iter().filter_map(|x| match x { Representation::Definition(ref d) if supported_representation_def(d) => { d.media_type.clone() } Representation::Reference(_) => { // TODO: Look up media type of reference Some(mime::APPLICATION_JSON) } _ => None, }) }) .collect::>(); if !mime_types.is_empty() { lines.push(format!( " req.headers_mut().insert(reqwest::header::ACCEPT, \"{}\".parse().unwrap());\n", mime_types .into_iter() .map(|x| x.to_string()) .collect::>() .join(", ") )); } for param in params.iter().filter(|p| p.style == ParamStyle::Header) { let value = if let Some(fixed) = param.fixed.as_ref() { format!("\"{}\"", fixed) } else { let param_name = param.name.as_str(); let mut param_name = snake_case_name(param_name); if ["type", "move"].contains(¶m_name.as_str()) { param_name = format!("r#{}", param_name); } format!("&{}.to_string()", param_name) }; lines.push(format!( " req.headers_mut().insert(\"{}\", {});\n", param.name, value )); } lines.push("\n".to_string()); lines.push(" let client = reqwest::blocking::Client::new();\n".to_string()); lines.push(" let resp = client.execute(req)?.error_for_status()?;\n".to_string()); lines.push(" Ok(resp.json()?)\n".to_string()); lines.push(" }\n".to_string()); lines.push("\n".to_string()); lines } pub fn generate_resource_type(input: &ResourceType, config: &Config) -> Vec { let mut lines = vec![]; for doc in &input.docs { lines.extend(generate_doc(doc, 0)); } let name = input.id.as_ref().unwrap().as_str(); let name = camel_case_name(name); lines.push(format!("pub trait {} : Resource {{\n", name)); for method in &input.methods { lines.extend(generate_method( method, input.id.as_ref().unwrap().as_str(), config, )); } lines.push("}\n".to_string()); lines.push("\n".to_string()); lines } #[derive(Default)] pub struct Config { pub guess_type_name: Option Option>>, } pub fn generate(app: &Application, config: &Config) -> String { let mut lines = vec![]; for doc in &app.docs { lines.extend(generate_doc(doc, 0)); } for representation in &app.representations { lines.extend(generate_representation(representation, config)); } for resource_type in &app.resource_types { lines.extend(generate_resource_type(resource_type, config)); } lines.concat() } wadl-0.1.4/src/lib.rs000064400000000000000000000023221046102023000124570ustar 00000000000000pub mod ast; #[cfg(feature = "codegen")] pub mod codegen; mod parse; pub use parse::{parse, parse_bytes, parse_file, parse_string, Error as ParseError}; use url::Url; /// The root of the web service. pub trait Resource { /// The URL of the root of the web service. fn url(&self) -> Url; } #[derive(Debug)] pub enum Error { InvalidUrl, Reqwest(reqwest::Error), Url(url::ParseError), Json(serde_json::Error), } impl From for Error { fn from(err: serde_json::Error) -> Self { Error::Json(err) } } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Error::InvalidUrl => write!(f, "Invalid URL"), Error::Reqwest(err) => write!(f, "Reqwest error: {}", err), Error::Url(err) => write!(f, "URL error: {}", err), Error::Json(err) => write!(f, "JSON error: {}", err), } } } impl std::error::Error for Error {} impl From for Error { fn from(err: reqwest::Error) -> Self { Error::Reqwest(err) } } impl From for Error { fn from(err: url::ParseError) -> Self { Error::Url(err) } } wadl-0.1.4/src/parse.rs000064400000000000000000000342711046102023000130330ustar 00000000000000use crate::ast::*; use std::collections::HashMap; use std::io::Read; use url::Url; use xmltree::Element; #[allow(unused)] pub const WADL_NS: &str = "http://wadl.dev.java.net/2009/02"; #[derive(Debug)] pub enum Error { Io(std::io::Error), Xml(xmltree::ParseError), Url(url::ParseError), Mime(mime::FromStrError), } impl From for Error { fn from(e: std::io::Error) -> Self { Error::Io(e) } } impl From for Error { fn from(e: xmltree::ParseError) -> Self { Error::Xml(e) } } impl From for Error { fn from(e: url::ParseError) -> Self { Error::Url(e) } } impl From for Error { fn from(e: mime::FromStrError) -> Self { Error::Mime(e) } } pub fn parse_options(element: &Element) -> Option>> { let mut options = HashMap::new(); for option_node in &element.children { if let Some(element) = option_node.as_element() { if element.name == "option" { let value = element.attributes.get("value").cloned(); let media_type = element.attributes.get("mediaType").cloned(); options.insert(value.unwrap(), media_type); } } } if options.is_empty() { None } else { Some(options) } } pub fn parse_params(resource_element: &Element, allowed_styles: &[ParamStyle]) -> Vec { let mut params = Vec::new(); for param_node in &resource_element.children { if let Some(element) = param_node.as_element() { if element.name == "param" { let style = element .attributes .get("style") .cloned() .map(|s| match s.as_str() { "plain" => ParamStyle::Plain, "matrix" => ParamStyle::Matrix, "query" => ParamStyle::Query, "header" => ParamStyle::Header, "template" => ParamStyle::Template, _ => panic!("Unknown param style: {}", s), }) .unwrap(); let options = parse_options(element); let id = element.attributes.get("id").cloned(); let name = element.attributes.get("name").cloned().unwrap(); let link_type = element.children.iter().find_map(|node| { if let Some(element) = node.as_element() { if element.name == "link" { match element.attributes.get("resource_type") { Some(href) => Some(TypeRef::ResourceType( if let Some(s) = href.strip_prefix('#') { ResourceTypeRef::Id(s.to_string()) } else { ResourceTypeRef::Link(href.parse().unwrap()) }, )), None => Some(TypeRef::EmptyLink), } } else { None } } else { None } }); let r#type = if let Some(t) = link_type { Some(t) } else { element .attributes .get("type") .map(|t| TypeRef::Simple(t.clone())) }; let path = element.attributes.get("path").cloned(); let required = element .attributes .get("required") .cloned() .map(|s| s == "true") .unwrap_or(false); let repeating = element .attributes .get("repeating") .cloned() .map(|s| s == "true") .unwrap_or(false); let fixed = element.attributes.get("fixed").cloned(); if !allowed_styles.contains(&style) { log::warn!( "Invalid param style: {:?} for element {} (expected one of: {:?})", style, name, allowed_styles ); } let r#type = match r#type { Some(t) => t, None if options.is_some() => TypeRef::Options(options.unwrap()), None => TypeRef::NoType, }; params.push(Param { style, id, name, r#type, path, required, repeating, fixed, }); } } } params } fn parse_resource(element: &Element) -> Result { let id = element.attributes.get("id").cloned(); let path = element.attributes.get("path").cloned(); let r#type = element.attributes.get("type").cloned().map(|s| { s.split(' ') .map(|x| x.parse::().unwrap()) .collect() }); let query_type: mime::Mime = element .attributes .get("queryType") .cloned() .unwrap_or("application/x-www-form-urlencoded".to_string()) .parse()?; let docs = parse_docs(element); let methods = parse_methods(element); let subresources = parse_resources(element)?; let params = parse_params( element, &[ ParamStyle::Matrix, ParamStyle::Query, ParamStyle::Header, ParamStyle::Template, ], ); Ok(Resource { id, path, r#type, query_type, methods, docs, subresources, params, }) } fn parse_resources(resources_element: &Element) -> Result, Error> { let mut resources = Vec::new(); for resource_node in &resources_element.children { if let Some(element) = resource_node.as_element() { if element.name == "resource" { resources.push(parse_resource(element)?); } } } Ok(resources) } fn parse_docs(resource_element: &Element) -> Vec { let mut docs = Vec::new(); for doc_node in &resource_element.children { if let Some(element) = doc_node.as_element() { if element.name == "doc" { let title = element.attributes.get("title").cloned(); let content = element.get_text().unwrap_or_default().trim().to_string(); let lang = element .attributes .get("{http://www.w3.org/XML/1998/namespace}lang") .cloned(); let xmlns = element .attributes .get("xmlns") .cloned() .map(|u| u.parse().unwrap()); docs.push(Doc { title, lang, content, xmlns, }); } } } docs } fn parse_resource_type(resource_type_element: &Element) -> Result { let id = resource_type_element.attributes.get("id").cloned(); let query_type: mime::Mime = resource_type_element .attributes .get("queryType") .cloned() .unwrap_or("application/x-www-form-urlencoded".to_string()) .parse()?; let docs = parse_docs(resource_type_element); let methods = parse_methods(resource_type_element); let subresources = parse_resources(resource_type_element)?; let params = parse_params( resource_type_element, &[ParamStyle::Header, ParamStyle::Query], ); Ok(ResourceType { id, query_type, methods, docs, subresources, params, }) } pub fn parse(reader: R) -> Result { let mut resources = Vec::new(); let mut resource_types = Vec::new(); let mut grammars = Vec::new(); let root = Element::parse(reader).map_err(Error::Xml)?; for resource_node in &root.children { if let Some(element) = resource_node.as_element() { if element.name == "resources" { let more_resources = parse_resources(element)?; let base = element.attributes.get("base").cloned(); resources.push(Resources { base: base.map(|s| s.parse().unwrap()), resources: more_resources, }); } else if element.name == "grammars" { for grammar_node in &element.children { if let Some(element) = grammar_node.as_element() { if element.name == "include" { let href: Url = element .attributes .get("href") .cloned() .unwrap() .parse() .unwrap(); grammars.push(Grammar { href }); } } } } else if element.name == "resource_type" { resource_types.push(parse_resource_type(element)?); } } } let docs = parse_docs(&root); let representations = parse_representations(&root); Ok(Application { resources, docs, resource_types, grammars, representations: representations .into_iter() .map(|r| match r { Representation::Definition(r) => r, Representation::Reference(_) => panic!("Reference in root"), }) .collect(), }) } pub fn parse_file>(path: P) -> Result { let file = std::fs::File::open(path).map_err(Error::Io)?; parse(file) } pub fn parse_string(s: &str) -> Result { parse(s.as_bytes()) } pub fn parse_bytes(bytes: &[u8]) -> Result { parse(bytes) } fn parse_representations(request_element: &Element) -> Vec { let mut representations = Vec::new(); for representation_node in &request_element.children { if let Some(element) = representation_node.as_element() { if element.name == "representation" { if let Some(href) = element.attributes.get("href") { if let Some(id) = href.strip_prefix('#') { representations.push(Representation::Reference(RepresentationRef::Id( id.to_string(), ))); } else { representations.push(Representation::Reference(RepresentationRef::Link( href.parse().unwrap(), ))); } } else { let element_name = element.attributes.get("element").cloned(); let media_type = element .attributes .get("mediaType") .map(|s| s.parse().unwrap()); let docs = parse_docs(element); let id = element.attributes.get("id").cloned(); let profile = element.attributes.get("profile").cloned(); let params = parse_params(element, &[ParamStyle::Plain, ParamStyle::Query]); representations.push(Representation::Definition(RepresentationDef { id, media_type, docs, element: element_name, profile, params, })); } } } } representations } fn parse_response(response_element: &Element) -> Response { let docs = parse_docs(response_element); let representations = parse_representations(response_element); let status = response_element .attributes .get("status") .map(|s| s.parse().unwrap()); let params = parse_params(response_element, &[ParamStyle::Header]); Response { docs, params, status, representations, } } fn parse_request(request_element: &Element) -> Request { let docs = parse_docs(request_element); let params = parse_params(request_element, &[ParamStyle::Header, ParamStyle::Query]); let representations = parse_representations(request_element); Request { docs, params, representations, } } fn parse_method(method_element: &Element) -> Method { let id = method_element .attributes .get("id") .cloned() .unwrap_or_default(); let name = method_element .attributes .get("name") .cloned() .unwrap_or_default(); let request_element = method_element .children .iter() .find(|node| node.as_element().map_or(false, |e| e.name == "request")) .and_then(|node| node.as_element()); let request = request_element.map(parse_request).unwrap_or_default(); let responses = method_element .children .iter() .filter(|node| node.as_element().map_or(false, |e| e.name == "response")) .map(|node| node.as_element().unwrap()) .map(parse_response) .collect(); let docs = parse_docs(method_element); Method { id, name, docs, request, responses, } } fn parse_methods(resource_element: &Element) -> Vec { let mut methods = Vec::new(); for method_node in &resource_element.children { if let Some(element) = method_node.as_element() { if element.name == "method" { methods.push(parse_method(element)); } } } methods }