diff options
-rw-r--r-- | rust/Cargo.lock | 651 | ||||
-rw-r--r-- | rust/Cargo.toml | 9 | ||||
-rw-r--r-- | rust/fatcat-api/Cargo.toml | 27 | ||||
-rw-r--r-- | rust/fatcat-api/README.md | 2 | ||||
-rw-r--r-- | rust/fatcat-api/api/swagger.yaml | 57 | ||||
-rw-r--r-- | rust/fatcat-api/examples/client.rs | 415 | ||||
-rw-r--r-- | rust/fatcat-api/examples/server.rs | 64 | ||||
-rw-r--r-- | rust/fatcat-api/examples/server_lib/mod.rs | 18 | ||||
-rw-r--r-- | rust/fatcat-api/examples/server_lib/server.rs | 276 | ||||
-rw-r--r-- | rust/fatcat-api/src/client.rs | 1515 | ||||
-rw-r--r-- | rust/fatcat-api/src/client/mod.rs | 2573 | ||||
-rw-r--r-- | rust/fatcat-api/src/lib.rs | 565 | ||||
-rw-r--r-- | rust/fatcat-api/src/mimetypes.rs | 176 | ||||
-rw-r--r-- | rust/fatcat-api/src/models.rs | 137 | ||||
-rw-r--r-- | rust/fatcat-api/src/server.rs | 1702 | ||||
-rw-r--r-- | rust/fatcat-api/src/server/auth.rs | 93 | ||||
-rw-r--r-- | rust/fatcat-api/src/server/mod.rs | 2485 | ||||
-rw-r--r-- | rust/src/api_lib.rs | 34 | ||||
-rw-r--r-- | rust/src/api_server.rs | 277 | ||||
-rw-r--r-- | rust/src/bin/fatcat-iron.rs | 69 | ||||
-rw-r--r-- | rust/src/bin/fatcat-tokio.rs | 67 | ||||
-rw-r--r-- | rust/src/lib.rs | 18 |
22 files changed, 4138 insertions, 7092 deletions
diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 42759107..b28db6d7 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -15,12 +15,9 @@ dependencies = [ ] [[package]] -name = "arrayvec" -version = "0.4.7" +name = "antidote" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "ascii" @@ -76,23 +73,38 @@ dependencies = [ ] [[package]] -name = "base64" +name = "bitflags" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "bitflags" -version = "0.9.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "bitflags" -version = "1.0.3" +name = "bodyparser" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "persistent 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bodyparser" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "persistent 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "buf_redux" @@ -109,15 +121,6 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "bytes" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "cc" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -184,53 +187,6 @@ dependencies = [ ] [[package]] -name = "core-foundation" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "core-foundation-sys" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-utils" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "diesel" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -261,6 +217,11 @@ dependencies = [ [[package]] name = "dtoa" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -349,43 +310,36 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "fatcat-api 0.1.0", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "iron-slog 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "iron-test 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "swagger 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "swagger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fatcat-api" version = "0.1.0" dependencies = [ + "bodyparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-openssl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "multipart 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "router 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "swagger 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "swagger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "urlencoded 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -422,15 +376,6 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "httparse" version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -454,42 +399,13 @@ dependencies = [ ] [[package]] -name = "hyper" -version = "0.11.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hyper-tls" -version = "0.1.3" +name = "hyper-openssl" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -503,15 +419,6 @@ dependencies = [ ] [[package]] -name = "iovec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "iron" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -567,7 +474,7 @@ dependencies = [ [[package]] name = "itoa" -version = "0.3.4" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -576,15 +483,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "language-tags" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -600,11 +498,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "lazycell" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "libc" version = "0.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -647,11 +540,6 @@ dependencies = [ ] [[package]] -name = "memoffset" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "mime" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -660,14 +548,6 @@ dependencies = [ ] [[package]] -name = "mime" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "mime_guess" version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -679,35 +559,6 @@ dependencies = [ ] [[package]] -name = "mio" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miow" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "modifier" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -732,35 +583,6 @@ dependencies = [ ] [[package]] -name = "native-tls" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "net2" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "nodrop" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "num" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -789,6 +611,14 @@ dependencies = [ [[package]] name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -829,6 +659,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "persistent" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "phf" version = "0.7.22" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -970,19 +809,26 @@ dependencies = [ ] [[package]] -name = "relay" -version = "0.1.1" +name = "remove_dir_all" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "remove_dir_all" +name = "route-recognizer" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "router" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1001,43 +847,9 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "schannel" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "scoped-tls" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "scopeguard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "security-framework" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "security-framework-sys" -version = "0.1.16" +name = "serde" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "serde" @@ -1064,23 +876,23 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.17" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "serde_urlencoded" -version = "0.5.1" +name = "serde_json" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1089,46 +901,26 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "slab" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slab" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "slog" version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "smallvec" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "strsim" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "swagger" -version = "0.10.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1152,11 +944,6 @@ dependencies = [ ] [[package]] -name = "take" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "tempdir" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1216,167 +1003,6 @@ dependencies = [ ] [[package]] -name = "tokio" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-core" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-executor" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-fs" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-io" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-proto" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-service" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-timer" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tls" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-udp" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1416,14 +1042,6 @@ dependencies = [ ] [[package]] -name = "unicase" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1483,6 +1101,17 @@ dependencies = [ ] [[package]] +name = "urlencoded" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bodyparser 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1527,11 +1156,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -1540,11 +1164,6 @@ dependencies = [ ] [[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1554,31 +1173,22 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [metadata] "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum ascii 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae7d751998c189c1d4468cf0a39bb2eae052a9c58d50ebb3b9591ee3813ad50" "checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" "checksum backtrace 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea58cd16fd6c9d120b5bcb01d63883ae4cc7ba2aed35c1841b862a3c7ef6639" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" -"checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum bodyparser 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6928e817538b74a73d1dd6e9a942a2a35c632a597b6bb14fd009480f859a6bf5" +"checksum bodyparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f82c118499b1f91bfe399833d9b6d320ec8775a98cf9ad77af8cc6308b10060c" "checksum buf_redux 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b9279646319ff816b05fb5897883ece50d7d854d12b59992683d4f8a71b0f949" "checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" -"checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59" "checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba" "checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18" "checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00" @@ -1587,14 +1197,10 @@ dependencies = [ "checksum chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" "checksum conduit-mime-types 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95ca30253581af809925ef68c2641cc140d6183f43e12e0af4992d53768bd7b8" -"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" -"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" -"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" -"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81" -"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" "checksum diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24815a0c2094f2c8dafe74ab3b9e975892f44acbb94b4d4b4898025a7615efa4" "checksum diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6471a2b637b414d3ee1504cf230409a550381c79204282f8fe06c527e4ae56be" "checksum dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "400b347fe65ccfbd8f545c9d9a75d04b0caf23fec49aaa838a9a05398f94c019" +"checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" @@ -1610,49 +1216,39 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" -"checksum hyper 0.11.26 (registry+https://github.com/rust-lang/crates.io-index)" = "66b16eb6213713f3c72d0ed14ce56423ae84dced8df73d2a2c8675f0495ae7ea" -"checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca" +"checksum hyper-openssl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5ecb3cd8e4d53f8abe7cb2227e66674bb63c1bd0ba60ca9ba7b74ea1e0054891" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum iron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2440ae846e7a8c7f9b401db8f6e31b4ea5e7d3688b91761337da7e054520c75b" "checksum iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8e17268922834707e1c29e8badbf9c712c9c43378e1b6a3388946baff10be2" "checksum iron-slog 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb0cc34306c77baf5089b3af209a0547c0ce36cdeaee2424a9fa0e45c042f4a0" "checksum iron-test 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1944bcf30f8b3f51ebf01e715517dd9755e9480934778d6de70179a41d283c1" -"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" +"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b28683d0b09bbc20be1c9b3f6f24854efb1356ffcffee08ea3f6e65596e85fa" "checksum mime_guess 1.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b7e2b09d08313f84e0fb82d13a4d859109a17543fe9af3b6d941dc1431f7de79" -"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" "checksum multipart 0.13.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92f54eb45230c3aa20864ccf0c277eeaeadcf5e437e91731db498dbf7fbe0ec6" -"checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" -"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" "checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45" "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" +"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" "checksum openssl-sys 0.9.30 (registry+https://github.com/rust-lang/crates.io-index)" = "73ae718c3562989cd3a0a5c26610feca02f8116822f6f195e6cf4887481e57f5" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum persistent 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c9c94f2ef72dc272c6bcc8157ccf2bc7da14f4c58c69059ac2fc48492d6916" "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" @@ -1670,57 +1266,36 @@ dependencies = [ "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"checksum route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3255338088df8146ba63d60a9b8e3556f1146ce2973bc05a75181a42ce2256" +"checksum router 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b1797ff166029cb632237bb5542696e54961b4cf75a324c6f05c9cf0584e4e" "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "85fd9df495640643ad2d00443b3d78aae69802ad488debab4f1dd52fc1806ade" -"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" -"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" +"checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" "checksum serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "97f6a6c3caba0cf8f883b53331791036404ce3c1bd895961cf8bb2f8cecfd84b" "checksum serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "f51b0ef935cf8a41a77bce553da1f8751a739b7ad82dd73669475a22e6ecedb0" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" +"checksum serde_json 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "67f7d2e9edc3523a9c8ec8cd6ec481b3a27810aafee3e625d311febd3e656b4c" "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1" -"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum slog 2.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2f7bfce6405155042d42ec0e645efe43eddedd7be280063ce0623b120014e7f9" -"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum swagger 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97dbc25f067d3341f3c8fc6d77471891878b1585a614018c7f542d6b5cf1dc61" +"checksum swagger 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "190ef0c6327759d0beb76d969b236fa3cc42469f9e107f626bbcc152727b4d12" "checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5" "checksum syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)" = "77961dcdac942fa8bc033c16f3a790b311c8a27d00811b878ebd8cf9b7ba39d5" -"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tiny_http 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f4d55c9a213880d1f0c89ded183f209c6e45b912ca6c7df6f93c163773572e1" -"checksum tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" -"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" -"checksum tokio-fs 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76766830bbf9a2d5bfb50c95350d56a2e79e2c80f675967fff448bc615899708" -"checksum tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af9eb326f64b2d6b68438e1953341e00ab3cf54de7e35d92bfc73af8555313a" -"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" -"checksum tokio-reactor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3cedc8e5af5131dc3423ffa4f877cce78ad25259a9a62de0613735a13ebc64b" -"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" -"checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" -"checksum tokio-threadpool 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5783254b10c7c84a56f62c74766ef7e5b83d1f13053218c7cab8d3f2c826fa0e" -"checksum tokio-timer 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535fed0ccee189f3d48447587697ba3fd234b3dbbb091f0ec4613ddfec0a7c4c" -"checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" -"checksum tokio-udp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "137bda266504893ac4774e0ec4c2108f7ccdbcb7ac8dced6305fe9e4e0b5041a" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" @@ -1729,6 +1304,7 @@ dependencies = [ "checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" "checksum url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)" = "cbaa8377a162d88e7d15db0cf110c8523453edcbc5bc66d2b6fffccffa34a068" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" +"checksum urlencoded 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c28708636d6f7298a53b1cdb6af40f1ab523209a7cb83cf4d41b3ebc671d319" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" @@ -1736,9 +1312,6 @@ dependencies = [ "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index f35490e5..56144dd3 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -16,14 +16,15 @@ error-chain = "0.11" # API server chrono = { version = "0.4", features = ["serde"] } futures = "0.1" -hyper = "0.11" +hyper = "0.10" +#hyper-openssl = {version = "0.2", optional = true} #hyper-tls = {version = "0.1.2", optional = true} iron = "0.5" iron-slog = "*" iron-test = "*" -swagger = "0.10" -tokio-core = "0.1.6" -tokio-proto = "0.1.1" +swagger = "0.7" +#tokio-core = "0.1.6" +#tokio-proto = "0.1.1" # TODO #sentry = "*" diff --git a/rust/fatcat-api/Cargo.toml b/rust/fatcat-api/Cargo.toml index 8eb4279d..3c226029 100644 --- a/rust/fatcat-api/Cargo.toml +++ b/rust/fatcat-api/Cargo.toml @@ -7,37 +7,32 @@ license = "Unlicense" [features] default = ["client", "server"] -client = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"] -server = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"] +client = ["serde_json", "serde_ignored", "hyper", "hyper-openssl", "uuid"] +server = ["serde_json", "serde_ignored", "hyper", "iron", "router", "bodyparser", "urlencoded", "uuid"] [dependencies] # Required by example server. # chrono = { version = "0.4", features = ["serde"] } futures = "0.1" -hyper = {version = "0.11", optional = true} -hyper-tls = {version = "0.1.2", optional = true} -swagger = "0.10.0" +hyper = {version = "0.10", optional = true} +hyper-openssl = {version = "0.2", optional = true } +iron = {version = "0.5", optional = true} +swagger = "0.7" # Not required by example server. # +bodyparser = {version = "0.7", optional = true} +url = "1.5" lazy_static = "0.2" log = "0.3.0" -mime = "0.3.3" -multipart = {version = "0.13.3", optional = true} -native-tls = {version = "0.1.4", optional = true} -openssl = {version = "0.9.14", optional = true} -percent-encoding = {version = "1.0.0", optional = true} -regex = {version = "0.2", optional = true} +multipart = {version = "0.13", optional = true} +router = {version = "0.5", optional = true} serde = "1.0" serde_derive = "1.0" serde_ignored = {version = "0.0.4", optional = true} serde_json = {version = "1.0", optional = true} -serde_urlencoded = {version = "0.5.1", optional = true} -tokio-core = {version = "0.1.6", optional = true} -tokio-proto = {version = "0.1.1", optional = true} -tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]} -url = {version = "1.5", optional = true} +urlencoded = {version = "0.5", optional = true} uuid = {version = "0.5", optional = true, features = ["serde", "v4"]} # ToDo: this should be updated to point at the official crate once # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream diff --git a/rust/fatcat-api/README.md b/rust/fatcat-api/README.md index 5a24942b..01597021 100644 --- a/rust/fatcat-api/README.md +++ b/rust/fatcat-api/README.md @@ -13,7 +13,7 @@ To see how to make this your own, look here: [README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md) - API version: 0.1.0 -- Build date: 2018-05-15T05:47:34.699Z +- Build date: 2018-05-15T07:25:01.630Z This autogenerated project defines an API crate `fatcat` which contains: * An `Api` trait defining the API in Rust. diff --git a/rust/fatcat-api/api/swagger.yaml b/rust/fatcat-api/api/swagger.yaml index 66f77d5b..a24d52f7 100644 --- a/rust/fatcat-api/api/swagger.yaml +++ b/rust/fatcat-api/api/swagger.yaml @@ -60,9 +60,8 @@ paths: operation_id: "creator_post" uppercase_operation_id: "CREATOR_POST" path: "/creator" - PATH_ID: "CREATOR" - hasPathParams: false HttpMethod: "Post" + httpmethod: "post" /creator/{id}: get: parameters: @@ -103,9 +102,8 @@ paths: operation_id: "creator_id_get" uppercase_operation_id: "CREATOR_ID_GET" path: "/creator/:id" - PATH_ID: "CREATOR_ID" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /creator/lookup: get: parameters: @@ -155,9 +153,8 @@ paths: operation_id: "creator_lookup_get" uppercase_operation_id: "CREATOR_LOOKUP_GET" path: "/creator/lookup" - PATH_ID: "CREATOR_LOOKUP" - hasPathParams: false HttpMethod: "Get" + httpmethod: "get" /container: post: parameters: @@ -204,9 +201,8 @@ paths: operation_id: "container_post" uppercase_operation_id: "CONTAINER_POST" path: "/container" - PATH_ID: "CONTAINER" - hasPathParams: false HttpMethod: "Post" + httpmethod: "post" /container/{id}: get: parameters: @@ -247,9 +243,8 @@ paths: operation_id: "container_id_get" uppercase_operation_id: "CONTAINER_ID_GET" path: "/container/:id" - PATH_ID: "CONTAINER_ID" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /container/lookup: get: parameters: @@ -299,9 +294,8 @@ paths: operation_id: "container_lookup_get" uppercase_operation_id: "CONTAINER_LOOKUP_GET" path: "/container/lookup" - PATH_ID: "CONTAINER_LOOKUP" - hasPathParams: false HttpMethod: "Get" + httpmethod: "get" /file: post: parameters: @@ -348,9 +342,8 @@ paths: operation_id: "file_post" uppercase_operation_id: "FILE_POST" path: "/file" - PATH_ID: "FILE" - hasPathParams: false HttpMethod: "Post" + httpmethod: "post" /file/{id}: get: parameters: @@ -391,9 +384,8 @@ paths: operation_id: "file_id_get" uppercase_operation_id: "FILE_ID_GET" path: "/file/:id" - PATH_ID: "FILE_ID" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /file/lookup: get: parameters: @@ -443,9 +435,8 @@ paths: operation_id: "file_lookup_get" uppercase_operation_id: "FILE_LOOKUP_GET" path: "/file/lookup" - PATH_ID: "FILE_LOOKUP" - hasPathParams: false HttpMethod: "Get" + httpmethod: "get" /release: post: parameters: @@ -492,9 +483,8 @@ paths: operation_id: "release_post" uppercase_operation_id: "RELEASE_POST" path: "/release" - PATH_ID: "RELEASE" - hasPathParams: false HttpMethod: "Post" + httpmethod: "post" /release/{id}: get: parameters: @@ -535,9 +525,8 @@ paths: operation_id: "release_id_get" uppercase_operation_id: "RELEASE_ID_GET" path: "/release/:id" - PATH_ID: "RELEASE_ID" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /release/lookup: get: parameters: @@ -587,9 +576,8 @@ paths: operation_id: "release_lookup_get" uppercase_operation_id: "RELEASE_LOOKUP_GET" path: "/release/lookup" - PATH_ID: "RELEASE_LOOKUP" - hasPathParams: false HttpMethod: "Get" + httpmethod: "get" /work: post: parameters: @@ -636,9 +624,8 @@ paths: operation_id: "work_post" uppercase_operation_id: "WORK_POST" path: "/work" - PATH_ID: "WORK" - hasPathParams: false HttpMethod: "Post" + httpmethod: "post" /work/{id}: get: parameters: @@ -679,9 +666,8 @@ paths: operation_id: "work_id_get" uppercase_operation_id: "WORK_ID_GET" path: "/work/:id" - PATH_ID: "WORK_ID" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /editor/{username}: get: parameters: @@ -722,9 +708,8 @@ paths: operation_id: "editor_username_get" uppercase_operation_id: "EDITOR_USERNAME_GET" path: "/editor/:username" - PATH_ID: "EDITOR_USERNAME" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /editor/{username}/changelog: get: parameters: @@ -765,9 +750,8 @@ paths: operation_id: "editor_username_changelog_get" uppercase_operation_id: "EDITOR_USERNAME_CHANGELOG_GET" path: "/editor/:username/changelog" - PATH_ID: "EDITOR_USERNAME_CHANGELOG" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /editgroup: post: parameters: [] @@ -802,9 +786,8 @@ paths: operation_id: "editgroup_post" uppercase_operation_id: "EDITGROUP_POST" path: "/editgroup" - PATH_ID: "EDITGROUP" - hasPathParams: false HttpMethod: "Post" + httpmethod: "post" /editgroup/{id}: get: parameters: @@ -845,9 +828,8 @@ paths: operation_id: "editgroup_id_get" uppercase_operation_id: "EDITGROUP_ID_GET" path: "/editgroup/:id" - PATH_ID: "EDITGROUP_ID" - hasPathParams: true HttpMethod: "Get" + httpmethod: "get" /editgroup/{id}/accept: post: parameters: @@ -897,9 +879,8 @@ paths: operation_id: "editgroup_id_accept_post" uppercase_operation_id: "EDITGROUP_ID_ACCEPT_POST" path: "/editgroup/:id/accept" - PATH_ID: "EDITGROUP_ID_ACCEPT" - hasPathParams: true HttpMethod: "Post" + httpmethod: "post" definitions: error: type: "object" diff --git a/rust/fatcat-api/examples/client.rs b/rust/fatcat-api/examples/client.rs index 6f7aa151..6693a3b1 100644 --- a/rust/fatcat-api/examples/client.rs +++ b/rust/fatcat-api/examples/client.rs @@ -1,350 +1,201 @@ #![allow(missing_docs, unused_variables, trivial_casts)] -extern crate clap; extern crate fatcat; #[allow(unused_extern_crates)] extern crate futures; #[allow(unused_extern_crates)] extern crate swagger; -extern crate tokio_core; #[allow(unused_extern_crates)] extern crate uuid; +extern crate clap; -use clap::{App, Arg}; #[allow(unused_imports)] -use fatcat::{ApiError, ApiNoContext, ContainerIdGetResponse, ContainerLookupGetResponse, - ContainerPostResponse, ContextWrapperExt, CreatorIdGetResponse, - CreatorLookupGetResponse, CreatorPostResponse, EditgroupIdAcceptPostResponse, - EditgroupIdGetResponse, EditgroupPostResponse, EditorUsernameChangelogGetResponse, - EditorUsernameGetResponse, FileIdGetResponse, FileLookupGetResponse, - FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse, - ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; +use futures::{Future, future, Stream, stream}; #[allow(unused_imports)] -use futures::{future, stream, Future, Stream}; -use tokio_core::reactor; +use fatcat::{ApiNoContext, ContextWrapperExt, + ApiError, + ContainerIdGetResponse, + ContainerLookupGetResponse, + ContainerPostResponse, + CreatorIdGetResponse, + CreatorLookupGetResponse, + CreatorPostResponse, + EditgroupIdAcceptPostResponse, + EditgroupIdGetResponse, + EditgroupPostResponse, + EditorUsernameChangelogGetResponse, + EditorUsernameGetResponse, + FileIdGetResponse, + FileLookupGetResponse, + FilePostResponse, + ReleaseIdGetResponse, + ReleaseLookupGetResponse, + ReleasePostResponse, + WorkIdGetResponse, + WorkPostResponse + }; +use clap::{App, Arg}; fn main() { let matches = App::new("client") - .arg( - Arg::with_name("operation") - .help("Sets the operation to run") - .possible_values(&[ - "ContainerIdGet", - "ContainerLookupGet", - "ContainerPost", - "CreatorIdGet", - "CreatorLookupGet", - "CreatorPost", - "EditgroupIdAcceptPost", - "EditgroupIdGet", - "EditgroupPost", - "EditorUsernameChangelogGet", - "EditorUsernameGet", - "FileIdGet", - "FileLookupGet", - "FilePost", - "ReleaseIdGet", - "ReleaseLookupGet", - "ReleasePost", - "WorkIdGet", - "WorkPost", - ]) - .required(true) - .index(1), - ) - .arg( - Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not"), - ) - .arg( - Arg::with_name("host") - .long("host") - .takes_value(true) - .default_value("api.fatcat.wiki") - .help("Hostname to contact"), - ) - .arg( - Arg::with_name("port") - .long("port") - .takes_value(true) - .default_value("8080") - .help("Port to contact"), - ) + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "ContainerIdGet", + "ContainerLookupGet", + "ContainerPost", + "CreatorIdGet", + "CreatorLookupGet", + "CreatorPost", + "EditgroupIdAcceptPost", + "EditgroupIdGet", + "EditgroupPost", + "EditorUsernameChangelogGet", + "EditorUsernameGet", + "FileIdGet", + "FileLookupGet", + "FilePost", + "ReleaseIdGet", + "ReleaseLookupGet", + "ReleasePost", + "WorkIdGet", + "WorkPost", +]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("api.fatcat.wiki") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) .get_matches(); - let mut core = reactor::Core::new().unwrap(); let is_https = matches.is_present("https"); - let base_url = format!( - "{}://{}:{}", - if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap() - ); - let client = if matches.is_present("https") { + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + let client = if is_https { // Using Simple HTTPS - fatcat::Client::try_new_https(core.handle(), &base_url, "examples/ca.pem") + fatcat::Client::try_new_https(&base_url, "examples/ca.pem") .expect("Failed to create HTTPS client") } else { // Using HTTP - fatcat::Client::try_new_http(core.handle(), &base_url) + fatcat::Client::try_new_http(&base_url) .expect("Failed to create HTTP client") }; // Using a non-default `Context` is not required; this is just an example! - let client = client.with_context(fatcat::Context::new_with_span_id( - self::uuid::Uuid::new_v4().to_string(), - )); + let client = client.with_context(fatcat::Context::new_with_span_id(self::uuid::Uuid::new_v4().to_string())); match matches.value_of("operation") { + Some("ContainerIdGet") => { - let result = core.run(client.container_id_get("id_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.container_id_get("id_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("ContainerLookupGet") => { - let result = core.run(client.container_lookup_get("issn_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.container_lookup_get("issn_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("ContainerPost") => { - let result = core.run(client.container_post(None)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.container_post(None).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("CreatorIdGet") => { - let result = core.run(client.creator_id_get("id_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.creator_id_get("id_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("CreatorLookupGet") => { - let result = core.run(client.creator_lookup_get("orcid_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.creator_lookup_get("orcid_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("CreatorPost") => { - let result = core.run(client.creator_post(None)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.creator_post(None).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("EditgroupIdAcceptPost") => { - let result = core.run(client.editgroup_id_accept_post(56)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.editgroup_id_accept_post(56).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("EditgroupIdGet") => { - let result = core.run(client.editgroup_id_get(56)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.editgroup_id_get(56).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("EditgroupPost") => { - let result = core.run(client.editgroup_post()); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.editgroup_post().wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("EditorUsernameChangelogGet") => { - let result = - core.run(client.editor_username_changelog_get("username_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.editor_username_changelog_get("username_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("EditorUsernameGet") => { - let result = core.run(client.editor_username_get("username_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.editor_username_get("username_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("FileIdGet") => { - let result = core.run(client.file_id_get("id_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.file_id_get("id_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("FileLookupGet") => { - let result = core.run(client.file_lookup_get("sha1_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.file_lookup_get("sha1_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("FilePost") => { - let result = core.run(client.file_post(None)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.file_post(None).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("ReleaseIdGet") => { - let result = core.run(client.release_id_get("id_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.release_id_get("id_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("ReleaseLookupGet") => { - let result = core.run(client.release_lookup_get("doi_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.release_lookup_get("doi_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("ReleasePost") => { - let result = core.run(client.release_post(None)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.release_post(None).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("WorkIdGet") => { - let result = core.run(client.work_id_get("id_example".to_string())); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.work_id_get("id_example".to_string()).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, Some("WorkPost") => { - let result = core.run(client.work_post(None)); - println!( - "{:?} (X-Span-ID: {:?})", - result, - client - .context() - .x_span_id - .clone() - .unwrap_or(String::from("<none>")) - ); - } + let result = client.work_post(None).wait(); + println!("{:?} (X-Span-ID: {:?})", result, client.context().x_span_id.clone().unwrap_or(String::from("<none>"))); + }, - _ => panic!("Invalid operation provided"), + _ => { + panic!("Invalid operation provided") + } } } + diff --git a/rust/fatcat-api/examples/server.rs b/rust/fatcat-api/examples/server.rs index f9b8617c..79d7367e 100644 --- a/rust/fatcat-api/examples/server.rs +++ b/rust/fatcat-api/examples/server.rs @@ -4,35 +4,32 @@ // Imports required by this file. // extern crate <name of this crate>; -extern crate clap; extern crate fatcat; -extern crate hyper; -extern crate native_tls; -extern crate openssl; extern crate swagger; -extern crate tokio_proto; -extern crate tokio_tls; +extern crate iron; +extern crate hyper_openssl; +extern crate clap; // Imports required by server library. // extern crate fatcat; // extern crate swagger; -extern crate chrono; extern crate futures; +extern crate chrono; #[macro_use] extern crate error_chain; +use hyper_openssl::OpensslServer; +use hyper_openssl::openssl::x509::X509_FILETYPE_PEM; +use hyper_openssl::openssl::ssl::{SslAcceptorBuilder, SslMethod}; +use hyper_openssl::openssl::error::ErrorStack; use clap::{App, Arg}; -use hyper::server::Http; -use openssl::error::ErrorStack; -use openssl::ssl::{SslAcceptorBuilder, SslMethod}; -use openssl::x509::X509_FILETYPE_PEM; -use swagger::auth::AllowAllAuthenticator; -use tokio_proto::TcpServer; +use iron::{Iron, Chain}; +use swagger::auth::AllowAllMiddleware; mod server_lib; -// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> { +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +fn ssl() -> Result<OpensslServer, ErrorStack> { let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?; // Server authentication @@ -40,39 +37,32 @@ fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> { ssl.set_certificate_chain_file("examples/server-chain.pem")?; ssl.check_private_key()?; - Ok(ssl) + Ok(OpensslServer::from(ssl.build())) } /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. fn main() { let matches = App::new("server") - .arg( - Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not"), - ) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) .get_matches(); - let service_fn = fatcat::server::auth::NewService::new(AllowAllAuthenticator::new( - server_lib::NewService, - "cosmo", - )); + let server = server_lib::server().unwrap(); + let router = fatcat::router(server); + + let mut chain = Chain::new(router); + chain.link_before(fatcat::server::ExtractAuthData); + // add authentication middlewares into the chain here + // for the purpose of this example, pretend we have authenticated a user + chain.link_before(AllowAllMiddleware::new("cosmo")); - let addr = "127.0.0.1:8080" - .parse() - .expect("Failed to parse bind address"); if matches.is_present("https") { - let ssl = ssl().expect("Failed to load SSL keys"); - let builder: native_tls::TlsAcceptorBuilder = - native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl); - let tls_acceptor = builder.build().expect("Failed to build TLS acceptor"); - TcpServer::new( - tokio_tls::proto::Server::new(Http::new(), tls_acceptor), - addr, - ).serve(service_fn); + // Using Simple HTTPS + Iron::new(chain).https("localhost:8080", ssl().expect("Failed to load SSL keys")).expect("Failed to start HTTPS server"); } else { // Using HTTP - TcpServer::new(Http::new(), addr).serve(service_fn); + Iron::new(chain).http("localhost:8080").expect("Failed to start HTTP server"); } } diff --git a/rust/fatcat-api/examples/server_lib/mod.rs b/rust/fatcat-api/examples/server_lib/mod.rs index a45fbe50..5291637e 100644 --- a/rust/fatcat-api/examples/server_lib/mod.rs +++ b/rust/fatcat-api/examples/server_lib/mod.rs @@ -7,20 +7,8 @@ mod errors { } pub use self::errors::*; -use fatcat; -use hyper; -use std::io; -pub struct NewService; - -impl hyper::server::NewService for NewService { - type Request = (hyper::Request, fatcat::Context); - type Response = hyper::Response; - type Error = hyper::Error; - type Instance = fatcat::server::Service<server::Server>; - - /// Instantiate a new server. - fn new_service(&self) -> io::Result<Self::Instance> { - Ok(fatcat::server::Service::new(server::Server)) - } +/// Instantiate a new server. +pub fn server() -> Result<server::Server> { + Ok(server::Server {}) } diff --git a/rust/fatcat-api/examples/server_lib/server.rs b/rust/fatcat-api/examples/server_lib/server.rs index 0dec7ed3..58414e31 100644 --- a/rust/fatcat-api/examples/server_lib/server.rs +++ b/rust/fatcat-api/examples/server_lib/server.rs @@ -2,286 +2,172 @@ #![allow(unused_imports)] -use chrono; use futures::{self, Future}; +use chrono; use std::collections::HashMap; use swagger; +use fatcat::{Api, ApiError, Context, + ContainerIdGetResponse, + ContainerLookupGetResponse, + ContainerPostResponse, + CreatorIdGetResponse, + CreatorLookupGetResponse, + CreatorPostResponse, + EditgroupIdAcceptPostResponse, + EditgroupIdGetResponse, + EditgroupPostResponse, + EditorUsernameChangelogGetResponse, + EditorUsernameGetResponse, + FileIdGetResponse, + FileLookupGetResponse, + FilePostResponse, + ReleaseIdGetResponse, + ReleaseLookupGetResponse, + ReleasePostResponse, + WorkIdGetResponse, + WorkPostResponse +}; use fatcat::models; -use fatcat::{Api, ApiError, ContainerIdGetResponse, ContainerLookupGetResponse, - ContainerPostResponse, Context, CreatorIdGetResponse, CreatorLookupGetResponse, - CreatorPostResponse, EditgroupIdAcceptPostResponse, EditgroupIdGetResponse, - EditgroupPostResponse, EditorUsernameChangelogGetResponse, EditorUsernameGetResponse, - FileIdGetResponse, FileLookupGetResponse, FilePostResponse, ReleaseIdGetResponse, - ReleaseLookupGetResponse, ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; #[derive(Copy, Clone)] pub struct Server; impl Api for Server { - fn container_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> { + + + fn container_id_get(&self, id: String, context: &Context) -> Box<Future<Item=ContainerIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "container_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("container_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn container_lookup_get( - &self, - issn: String, - context: &Context, - ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> { + + fn container_lookup_get(&self, issn: String, context: &Context) -> Box<Future<Item=ContainerLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "container_lookup_get(\"{}\") - X-Span-ID: {:?}", - issn, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("container_lookup_get(\"{}\") - X-Span-ID: {:?}", issn, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn container_post( - &self, - body: Option<models::ContainerEntity>, - context: &Context, - ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> { + + fn container_post(&self, body: Option<models::ContainerEntity>, context: &Context) -> Box<Future<Item=ContainerPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "container_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("container_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn creator_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> { + + fn creator_id_get(&self, id: String, context: &Context) -> Box<Future<Item=CreatorIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "creator_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("creator_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn creator_lookup_get( - &self, - orcid: String, - context: &Context, - ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> { + + fn creator_lookup_get(&self, orcid: String, context: &Context) -> Box<Future<Item=CreatorLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "creator_lookup_get(\"{}\") - X-Span-ID: {:?}", - orcid, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("creator_lookup_get(\"{}\") - X-Span-ID: {:?}", orcid, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn creator_post( - &self, - body: Option<models::CreatorEntity>, - context: &Context, - ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> { + + fn creator_post(&self, body: Option<models::CreatorEntity>, context: &Context) -> Box<Future<Item=CreatorPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "creator_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("creator_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editgroup_id_accept_post( - &self, - id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> { + + fn editgroup_id_accept_post(&self, id: i32, context: &Context) -> Box<Future<Item=EditgroupIdAcceptPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editgroup_id_accept_post({}) - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editgroup_id_accept_post({}) - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editgroup_id_get( - &self, - id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> { + + fn editgroup_id_get(&self, id: i32, context: &Context) -> Box<Future<Item=EditgroupIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editgroup_id_get({}) - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editgroup_id_get({}) - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editgroup_post( - &self, - context: &Context, - ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> { + + fn editgroup_post(&self, context: &Context) -> Box<Future<Item=EditgroupPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editgroup_post() - X-Span-ID: {:?}", - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editgroup_post() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editor_username_changelog_get( - &self, - username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> { + + fn editor_username_changelog_get(&self, username: String, context: &Context) -> Box<Future<Item=EditorUsernameChangelogGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editor_username_changelog_get(\"{}\") - X-Span-ID: {:?}", - username, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editor_username_changelog_get(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editor_username_get( - &self, - username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> { + + fn editor_username_get(&self, username: String, context: &Context) -> Box<Future<Item=EditorUsernameGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editor_username_get(\"{}\") - X-Span-ID: {:?}", - username, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editor_username_get(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn file_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> { + + fn file_id_get(&self, id: String, context: &Context) -> Box<Future<Item=FileIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "file_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("file_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn file_lookup_get( - &self, - sha1: String, - context: &Context, - ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> { + + fn file_lookup_get(&self, sha1: String, context: &Context) -> Box<Future<Item=FileLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "file_lookup_get(\"{}\") - X-Span-ID: {:?}", - sha1, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("file_lookup_get(\"{}\") - X-Span-ID: {:?}", sha1, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn file_post( - &self, - body: Option<models::FileEntity>, - context: &Context, - ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> { + + fn file_post(&self, body: Option<models::FileEntity>, context: &Context) -> Box<Future<Item=FilePostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "file_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("file_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn release_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> { + + fn release_id_get(&self, id: String, context: &Context) -> Box<Future<Item=ReleaseIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "release_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("release_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn release_lookup_get( - &self, - doi: String, - context: &Context, - ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> { + + fn release_lookup_get(&self, doi: String, context: &Context) -> Box<Future<Item=ReleaseLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "release_lookup_get(\"{}\") - X-Span-ID: {:?}", - doi, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("release_lookup_get(\"{}\") - X-Span-ID: {:?}", doi, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn release_post( - &self, - body: Option<models::ReleaseEntity>, - context: &Context, - ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> { + + fn release_post(&self, body: Option<models::ReleaseEntity>, context: &Context) -> Box<Future<Item=ReleasePostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "release_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("release_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn work_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> { + + fn work_id_get(&self, id: String, context: &Context) -> Box<Future<Item=WorkIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "work_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("work_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn work_post( - &self, - body: Option<models::WorkEntity>, - context: &Context, - ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> { + + fn work_post(&self, body: Option<models::WorkEntity>, context: &Context) -> Box<Future<Item=WorkPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "work_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("work_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } + } diff --git a/rust/fatcat-api/src/client.rs b/rust/fatcat-api/src/client.rs new file mode 100644 index 00000000..e8546f95 --- /dev/null +++ b/rust/fatcat-api/src/client.rs @@ -0,0 +1,1515 @@ +#![allow(unused_extern_crates)] +extern crate hyper_openssl; +extern crate chrono; +extern crate url; + + + +use hyper; +use hyper::client::IntoUrl; +use hyper::mime; +use hyper::header::{Headers, ContentType}; +use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value}; +use hyper::Url; +use self::hyper_openssl::openssl; +use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; +use futures; +use futures::{Future, Stream}; +use futures::{future, stream}; +use std::borrow::Cow; +use std::io::{Read, Error}; +use std::error; +use std::fmt; +use std::path::Path; +use std::sync::Arc; +use std::str; + +use mimetypes; + +use serde_json; + + +#[allow(unused_imports)] +use std::collections::{HashMap, BTreeMap}; +#[allow(unused_imports)] +use swagger; + +use swagger::{Context, ApiError, XSpanId}; + +use {Api, + ContainerIdGetResponse, + ContainerLookupGetResponse, + ContainerPostResponse, + CreatorIdGetResponse, + CreatorLookupGetResponse, + CreatorPostResponse, + EditgroupIdAcceptPostResponse, + EditgroupIdGetResponse, + EditgroupPostResponse, + EditorUsernameChangelogGetResponse, + EditorUsernameGetResponse, + FileIdGetResponse, + FileLookupGetResponse, + FilePostResponse, + ReleaseIdGetResponse, + ReleaseLookupGetResponse, + ReleasePostResponse, + WorkIdGetResponse, + WorkPostResponse + }; +use models; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path<T: IntoUrl>(input: T, correct_scheme: Option<&'static str>) -> Result<String, ClientInitError> { + // First convert to Url, since a base path is a subset of Url. + let url = input.into_url()?; + + let scheme = url.scheme(); + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = url.host().ok_or_else(|| ClientInitError::MissingHost)?; + let port = url.port().map(|x| format!(":{}", x)).unwrap_or_default(); + Ok(format!("{}://{}{}", scheme, host, port)) +} + +/// A client that implements the API by making HTTP calls out to a server. +#[derive(Clone)] +pub struct Client { + base_path: String, + hyper_client: Arc<Fn() -> hyper::client::Client + Sync + Send>, +} + +impl fmt::Debug for Client { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Client { + pub fn try_new_http<T>(base_path: T) -> Result<Client, ClientInitError> + where T: IntoUrl + { + Ok(Client { + base_path: into_base_path(base_path, Some("http"))?, + hyper_client: Arc::new(hyper::client::Client::new), + }) + } + + pub fn try_new_https<T, CA>(base_path: T, + ca_certificate: CA) + -> Result<Client, ClientInitError> + where T: IntoUrl, + CA: AsRef<Path> + { + let ca_certificate = ca_certificate.as_ref().to_owned(); + + let https_hyper_client = move || { + // SSL implementation + let mut ssl = openssl::ssl::SslConnectorBuilder::new(openssl::ssl::SslMethod::tls()).unwrap(); + + // Server authentication + ssl.set_ca_file(ca_certificate.clone()).unwrap(); + + let ssl = hyper_openssl::OpensslClient::from(ssl.build()); + let connector = hyper::net::HttpsConnector::new(ssl); + hyper::client::Client::with_connector(connector) + }; + + Ok(Client { + base_path: into_base_path(base_path, Some("https"))?, + hyper_client: Arc::new(https_hyper_client), + }) + } + + pub fn try_new_https_mutual<T, CA, K, C>(base_path: T, + ca_certificate: CA, + client_key: K, + client_certificate: C) + -> Result<Client, ClientInitError> + where T: IntoUrl, + CA: AsRef<Path>, + K: AsRef<Path>, + C: AsRef<Path> + { + let ca_certificate = ca_certificate.as_ref().to_owned(); + let client_key = client_key.as_ref().to_owned(); + let client_certificate = client_certificate.as_ref().to_owned(); + + let https_mutual_hyper_client = move || { + // SSL implementation + let mut ssl = openssl::ssl::SslConnectorBuilder::new(openssl::ssl::SslMethod::tls()).unwrap(); + + // Server authentication + ssl.set_ca_file(ca_certificate.clone()).unwrap(); + + // Client authentication + ssl.set_private_key_file(client_key.clone(), openssl::x509::X509_FILETYPE_PEM).unwrap(); + ssl.set_certificate_chain_file(client_certificate.clone()).unwrap(); + ssl.check_private_key().unwrap(); + + let ssl = hyper_openssl::OpensslClient::from(ssl.build()); + let connector = hyper::net::HttpsConnector::new(ssl); + hyper::client::Client::with_connector(connector) + }; + + Ok(Client { + base_path: into_base_path(base_path, Some("https"))?, + hyper_client: Arc::new(https_mutual_hyper_client) + }) + } + + /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. + /// + /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport + /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of + /// code generality, which may make it harder to move the application to a serverless environment, for example. + /// + /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. + /// This is not a recommended way to write new tests. If other reasons are found for using this function, they + /// should be mentioned here. + pub fn try_new_with_hyper_client<T>(base_path: T, + hyper_client: Arc<Fn() -> hyper::client::Client + Sync + Send>) + -> Result<Client, ClientInitError> + where T: IntoUrl + { + Ok(Client { + base_path: into_base_path(base_path, None)?, + hyper_client: hyper_client + }) + } +} + +impl Api for Client { + + fn container_id_get(&self, param_id: String, context: &Context) -> Box<Future<Item=ContainerIdGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/container/{id}", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<ContainerIdGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::ContainerEntity>(&buf)?; + + Ok(ContainerIdGetResponse::FetchASingleContainerById(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerIdGetResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerIdGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn container_lookup_get(&self, param_issn: String, context: &Context) -> Box<Future<Item=ContainerLookupGetResponse, Error=ApiError> + Send> { + + // Query parameters + let query_issn = format!("issn={issn}&", issn=param_issn.to_string()); + + + let url = format!( + "{}/v0/container/lookup?{issn}", + self.base_path, + issn=utf8_percent_encode(&query_issn, QUERY_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<ContainerLookupGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::ContainerEntity>(&buf)?; + + Ok(ContainerLookupGetResponse::FindASingleContainerByExternalIdentifer(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerLookupGetResponse::BadRequest(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerLookupGetResponse::NoSuchContainer(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerLookupGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn container_post(&self, param_body: Option<models::ContainerEntity>, context: &Context) -> Box<Future<Item=ContainerPostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/container", + self.base_path + ); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + let request = match body { + Some(ref body) => request.body(body), + None => request, + }; + + custom_headers.set(ContentType(mimetypes::requests::CONTAINER_POST.clone())); + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<ContainerPostResponse, ApiError> { + match response.status.to_u16() { + 201 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::EntityEdit>(&buf)?; + + Ok(ContainerPostResponse::Created(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerPostResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ContainerPostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn creator_id_get(&self, param_id: String, context: &Context) -> Box<Future<Item=CreatorIdGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/creator/{id}", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<CreatorIdGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::CreatorEntity>(&buf)?; + + Ok(CreatorIdGetResponse::FetchASingleCreatorById(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorIdGetResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorIdGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn creator_lookup_get(&self, param_orcid: String, context: &Context) -> Box<Future<Item=CreatorLookupGetResponse, Error=ApiError> + Send> { + + // Query parameters + let query_orcid = format!("orcid={orcid}&", orcid=param_orcid.to_string()); + + + let url = format!( + "{}/v0/creator/lookup?{orcid}", + self.base_path, + orcid=utf8_percent_encode(&query_orcid, QUERY_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<CreatorLookupGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::CreatorEntity>(&buf)?; + + Ok(CreatorLookupGetResponse::FindASingleCreatorByExternalIdentifer(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorLookupGetResponse::BadRequest(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorLookupGetResponse::NoSuchCreator(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorLookupGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn creator_post(&self, param_body: Option<models::CreatorEntity>, context: &Context) -> Box<Future<Item=CreatorPostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/creator", + self.base_path + ); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + let request = match body { + Some(ref body) => request.body(body), + None => request, + }; + + custom_headers.set(ContentType(mimetypes::requests::CREATOR_POST.clone())); + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<CreatorPostResponse, ApiError> { + match response.status.to_u16() { + 201 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::EntityEdit>(&buf)?; + + Ok(CreatorPostResponse::Created(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorPostResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(CreatorPostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn editgroup_id_accept_post(&self, param_id: i32, context: &Context) -> Box<Future<Item=EditgroupIdAcceptPostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/editgroup/{id}/accept", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<EditgroupIdAcceptPostResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Success>(&buf)?; + + Ok(EditgroupIdAcceptPostResponse::MergedEditgroupSuccessfully_(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupIdAcceptPostResponse::EditgroupIsInAnUnmergableState(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupIdAcceptPostResponse::NoSuchEditgroup(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupIdAcceptPostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn editgroup_id_get(&self, param_id: i32, context: &Context) -> Box<Future<Item=EditgroupIdGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/editgroup/{id}", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<EditgroupIdGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Editgroup>(&buf)?; + + Ok(EditgroupIdGetResponse::FetchEditgroupByIdentifier(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupIdGetResponse::NoSuchEditgroup(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupIdGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn editgroup_post(&self, context: &Context) -> Box<Future<Item=EditgroupPostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/editgroup", + self.base_path + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<EditgroupPostResponse, ApiError> { + match response.status.to_u16() { + 201 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Editgroup>(&buf)?; + + Ok(EditgroupPostResponse::SuccessfullyCreated(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupPostResponse::InvalidRequestParameters(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditgroupPostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn editor_username_changelog_get(&self, param_username: String, context: &Context) -> Box<Future<Item=EditorUsernameChangelogGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/editor/{username}/changelog", + self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<EditorUsernameChangelogGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Changelogentry>(&buf)?; + + Ok(EditorUsernameChangelogGetResponse::FindChanges_(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditorUsernameChangelogGetResponse::UsernameNotFound(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditorUsernameChangelogGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn editor_username_get(&self, param_username: String, context: &Context) -> Box<Future<Item=EditorUsernameGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/editor/{username}", + self.base_path, username=utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<EditorUsernameGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Editor>(&buf)?; + + Ok(EditorUsernameGetResponse::FetchGenericInformationAboutAnEditor(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditorUsernameGetResponse::UsernameNotFound(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(EditorUsernameGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn file_id_get(&self, param_id: String, context: &Context) -> Box<Future<Item=FileIdGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/file/{id}", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<FileIdGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::FileEntity>(&buf)?; + + Ok(FileIdGetResponse::FetchASingleFileById(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FileIdGetResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FileIdGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn file_lookup_get(&self, param_sha1: String, context: &Context) -> Box<Future<Item=FileLookupGetResponse, Error=ApiError> + Send> { + + // Query parameters + let query_sha1 = format!("sha1={sha1}&", sha1=param_sha1.to_string()); + + + let url = format!( + "{}/v0/file/lookup?{sha1}", + self.base_path, + sha1=utf8_percent_encode(&query_sha1, QUERY_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<FileLookupGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::FileEntity>(&buf)?; + + Ok(FileLookupGetResponse::FindASingleFileByExternalIdentifer(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FileLookupGetResponse::BadRequest(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FileLookupGetResponse::NoSuchFile(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FileLookupGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn file_post(&self, param_body: Option<models::FileEntity>, context: &Context) -> Box<Future<Item=FilePostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/file", + self.base_path + ); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + let request = match body { + Some(ref body) => request.body(body), + None => request, + }; + + custom_headers.set(ContentType(mimetypes::requests::FILE_POST.clone())); + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<FilePostResponse, ApiError> { + match response.status.to_u16() { + 201 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::EntityEdit>(&buf)?; + + Ok(FilePostResponse::Created(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FilePostResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(FilePostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn release_id_get(&self, param_id: String, context: &Context) -> Box<Future<Item=ReleaseIdGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/release/{id}", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<ReleaseIdGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::ReleaseEntity>(&buf)?; + + Ok(ReleaseIdGetResponse::FetchASingleReleaseById(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleaseIdGetResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleaseIdGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn release_lookup_get(&self, param_doi: String, context: &Context) -> Box<Future<Item=ReleaseLookupGetResponse, Error=ApiError> + Send> { + + // Query parameters + let query_doi = format!("doi={doi}&", doi=param_doi.to_string()); + + + let url = format!( + "{}/v0/release/lookup?{doi}", + self.base_path, + doi=utf8_percent_encode(&query_doi, QUERY_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<ReleaseLookupGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::ReleaseEntity>(&buf)?; + + Ok(ReleaseLookupGetResponse::FindASingleReleaseByExternalIdentifer(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleaseLookupGetResponse::BadRequest(body)) + }, + 404 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleaseLookupGetResponse::NoSuchRelease(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleaseLookupGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn release_post(&self, param_body: Option<models::ReleaseEntity>, context: &Context) -> Box<Future<Item=ReleasePostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/release", + self.base_path + ); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + let request = match body { + Some(ref body) => request.body(body), + None => request, + }; + + custom_headers.set(ContentType(mimetypes::requests::RELEASE_POST.clone())); + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<ReleasePostResponse, ApiError> { + match response.status.to_u16() { + 201 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::EntityEdit>(&buf)?; + + Ok(ReleasePostResponse::Created(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleasePostResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(ReleasePostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn work_id_get(&self, param_id: String, context: &Context) -> Box<Future<Item=WorkIdGetResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/work/{id}", + self.base_path, id=utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) + ); + + + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Get, &url); + let mut custom_headers = hyper::header::Headers::new(); + + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<WorkIdGetResponse, ApiError> { + match response.status.to_u16() { + 200 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::WorkEntity>(&buf)?; + + Ok(WorkIdGetResponse::FetchASingleWorkById(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(WorkIdGetResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(WorkIdGetResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + + fn work_post(&self, param_body: Option<models::WorkEntity>, context: &Context) -> Box<Future<Item=WorkPostResponse, Error=ApiError> + Send> { + + + let url = format!( + "{}/v0/work", + self.base_path + ); + + let body = param_body.map(|ref body| { + + serde_json::to_string(body).expect("impossible to fail to serialize") + }); + let hyper_client = (self.hyper_client)(); + let request = hyper_client.request(hyper::method::Method::Post, &url); + let mut custom_headers = hyper::header::Headers::new(); + + let request = match body { + Some(ref body) => request.body(body), + None => request, + }; + + custom_headers.set(ContentType(mimetypes::requests::WORK_POST.clone())); + context.x_span_id.as_ref().map(|header| custom_headers.set(XSpanId(header.clone()))); + + + let request = request.headers(custom_headers); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn parse_response(mut response: hyper::client::response::Response) -> Result<WorkPostResponse, ApiError> { + match response.status.to_u16() { + 201 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::EntityEdit>(&buf)?; + + Ok(WorkPostResponse::Created(body)) + }, + 400 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(WorkPostResponse::BadRequest(body)) + }, + 0 => { + let mut buf = String::new(); + response.read_to_string(&mut buf).map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + let body = serde_json::from_str::<models::Error>(&buf)?; + + Ok(WorkPostResponse::GenericErrorResponse(body)) + }, + code => { + let mut buf = [0; 100]; + let debug_body = match response.read(&mut buf) { + Ok(len) => match str::from_utf8(&buf[..len]) { + Ok(body) => Cow::from(body), + Err(_) => Cow::from(format!("<Body was not UTF8: {:?}>", &buf[..len].to_vec())), + }, + Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), + }; + Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + response.headers, + debug_body))) + } + } + } + + let result = request.send().map_err(|e| ApiError(format!("No response received: {}", e))).and_then(parse_response); + Box::new(futures::done(result)) + } + +} + +#[derive(Debug)] +pub enum ClientInitError { + InvalidScheme, + InvalidUrl(hyper::error::ParseError), + MissingHost, + SslError(openssl::error::ErrorStack) +} + +impl From<hyper::error::ParseError> for ClientInitError { + fn from(err: hyper::error::ParseError) -> ClientInitError { + ClientInitError::InvalidUrl(err) + } +} + +impl From<openssl::error::ErrorStack> for ClientInitError { + fn from(err: openssl::error::ErrorStack) -> ClientInitError { + ClientInitError::SslError(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (self as &fmt::Debug).fmt(f) + } +} + +impl error::Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} diff --git a/rust/fatcat-api/src/client/mod.rs b/rust/fatcat-api/src/client/mod.rs deleted file mode 100644 index 361fd390..00000000 --- a/rust/fatcat-api/src/client/mod.rs +++ /dev/null @@ -1,2573 +0,0 @@ -#![allow(unused_extern_crates)] -extern crate chrono; -extern crate hyper_tls; -extern crate mime; -extern crate native_tls; -extern crate openssl; -extern crate tokio_core; -extern crate url; - -use self::tokio_core::reactor::Handle; -use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; -use futures; -use futures::{Future, Stream}; -use futures::{future, stream}; -use hyper; -use hyper::Uri; -use hyper::header::{ContentType, Headers}; -use std::borrow::Cow; -use std::error; -use std::fmt; -use std::io::{Error, ErrorKind, Read}; -use std::path::Path; -use std::str; -use std::str::FromStr; -use std::sync::Arc; - -use mimetypes; - -use serde_json; - -#[allow(unused_imports)] -use std::collections::{BTreeMap, HashMap}; -#[allow(unused_imports)] -use swagger; - -use swagger::{ApiError, Context, XSpanId}; - -use models; -use {Api, ContainerIdGetResponse, ContainerLookupGetResponse, ContainerPostResponse, - CreatorIdGetResponse, CreatorLookupGetResponse, CreatorPostResponse, - EditgroupIdAcceptPostResponse, EditgroupIdGetResponse, EditgroupPostResponse, - EditorUsernameChangelogGetResponse, EditorUsernameGetResponse, FileIdGetResponse, - FileLookupGetResponse, FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse, - ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; - -/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. -fn into_base_path( - input: &str, - correct_scheme: Option<&'static str>, -) -> Result<String, ClientInitError> { - // First convert to Uri, since a base path is a subset of Uri. - let uri = Uri::from_str(input)?; - - let scheme = uri.scheme().ok_or(ClientInitError::InvalidScheme)?; - - // Check the scheme if necessary - if let Some(correct_scheme) = correct_scheme { - if scheme != correct_scheme { - return Err(ClientInitError::InvalidScheme); - } - } - - let host = uri.host().ok_or_else(|| ClientInitError::MissingHost)?; - let port = uri.port().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}", scheme, host, port)) -} - -/// A client that implements the API by making HTTP calls out to a server. -#[derive(Clone)] -pub struct Client { - hyper_client: Arc< - Fn( - &Handle - ) -> Box< - hyper::client::Service< - Request = hyper::Request<hyper::Body>, - Response = hyper::Response, - Error = hyper::Error, - Future = hyper::client::FutureResponse, - >, - > - + Sync - + Send, - >, - handle: Arc<Handle>, - base_path: String, -} - -impl fmt::Debug for Client { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Client {{ base_path: {} }}", self.base_path) - } -} - -impl Client { - /// Create an HTTP client. - /// - /// # Arguments - /// * `handle` - tokio reactor handle to use for execution - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" - pub fn try_new_http(handle: Handle, base_path: &str) -> Result<Client, ClientInitError> { - let http_connector = swagger::http_connector(); - Self::try_new_with_connector::<hyper::client::HttpConnector>( - handle, - base_path, - Some("http"), - http_connector, - ) - } - - /// Create a client with a TLS connection to the server. - /// - /// # Arguments - /// * `handle` - tokio reactor handle to use for execution - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" - /// * `ca_certificate` - Path to CA certificate used to authenticate the server - pub fn try_new_https<CA>( - handle: Handle, - base_path: &str, - ca_certificate: CA, - ) -> Result<Client, ClientInitError> - where - CA: AsRef<Path>, - { - let https_connector = swagger::https_connector(ca_certificate); - Self::try_new_with_connector::<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>( - handle, - base_path, - Some("https"), - https_connector, - ) - } - - /// Create a client with a mutually authenticated TLS connection to the server. - /// - /// # Arguments - /// * `handle` - tokio reactor handle to use for execution - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" - /// * `ca_certificate` - Path to CA certificate used to authenticate the server - /// * `client_key` - Path to the client private key - /// * `client_certificate` - Path to the client's public certificate associated with the private key - pub fn try_new_https_mutual<CA, K, C, T>( - handle: Handle, - base_path: &str, - ca_certificate: CA, - client_key: K, - client_certificate: C, - ) -> Result<Client, ClientInitError> - where - CA: AsRef<Path>, - K: AsRef<Path>, - C: AsRef<Path>, - { - let https_connector = - swagger::https_mutual_connector(ca_certificate, client_key, client_certificate); - Self::try_new_with_connector::<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>( - handle, - base_path, - Some("https"), - https_connector, - ) - } - - /// Create a client with a custom implementation of hyper::client::Connect. - /// - /// Intended for use with custom implementations of connect for e.g. protocol logging - /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, - /// this function should be used in conjunction with - /// `swagger::{http_connector, https_connector, https_mutual_connector}`. - /// - /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` - /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. - /// - /// # Arguments - /// - /// * `handle` - tokio reactor handle to use for execution - /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" - /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` - /// * `connector_fn` - Function which returns an implementation of `hyper::client::Connect` - pub fn try_new_with_connector<C>( - handle: Handle, - base_path: &str, - protocol: Option<&'static str>, - connector_fn: Box<Fn(&Handle) -> C + Send + Sync>, - ) -> Result<Client, ClientInitError> - where - C: hyper::client::Connect + hyper::client::Service, - { - let hyper_client = { - move |handle: &Handle| -> Box< - hyper::client::Service< - Request = hyper::Request<hyper::Body>, - Response = hyper::Response, - Error = hyper::Error, - Future = hyper::client::FutureResponse, - >, - > { - let connector = connector_fn(handle); - Box::new( - hyper::Client::configure() - .connector(connector) - .build(handle), - ) - } - }; - - Ok(Client { - hyper_client: Arc::new(hyper_client), - handle: Arc::new(handle), - base_path: into_base_path(base_path, protocol)?, - }) - } - - /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. - /// - /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport - /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of - /// code generality, which may make it harder to move the application to a serverless environment, for example. - /// - /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. - /// This is not a recommended way to write new tests. If other reasons are found for using this function, they - /// should be mentioned here. - pub fn try_new_with_hyper_client( - hyper_client: Arc< - Fn( - &Handle - ) -> Box< - hyper::client::Service< - Request = hyper::Request<hyper::Body>, - Response = hyper::Response, - Error = hyper::Error, - Future = hyper::client::FutureResponse, - >, - > - + Sync - + Send, - >, - handle: Handle, - base_path: &str, - ) -> Result<Client, ClientInitError> { - Ok(Client { - hyper_client: hyper_client, - handle: Arc::new(handle), - base_path: into_base_path(base_path, None)?, - }) - } -} - -impl Api for Client { - fn container_id_get( - &self, - param_id: String, - context: &Context, - ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/container/{id}", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::ContainerEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ContainerIdGetResponse::FetchASingleContainerById(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ContainerIdGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ContainerIdGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn container_lookup_get( - &self, - param_issn: String, - context: &Context, - ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> { - // Query parameters - let query_issn = format!("issn={issn}&", issn = param_issn.to_string()); - - let uri = format!( - "{}/v0/container/lookup?{issn}", - self.base_path, - issn = utf8_percent_encode(&query_issn, QUERY_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::ContainerEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ContainerLookupGetResponse::FindASingleContainerByExternalIdentifer(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ContainerLookupGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ContainerLookupGetResponse::NoSuchContainer(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ContainerLookupGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn container_post( - &self, - param_body: Option<models::ContainerEntity>, - context: &Context, - ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> { - let uri = format!("{}/v0/container", self.base_path); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - let body = param_body - .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); - - if let Some(body) = body { - request.set_body(body.into_bytes()); - } - - request - .headers_mut() - .set(ContentType(mimetypes::requests::CONTAINER_POST.clone())); - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 201 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::EntityEdit>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ContainerPostResponse::Created(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ContainerPostResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ContainerPostResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn creator_id_get( - &self, - param_id: String, - context: &Context, - ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/creator/{id}", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::CreatorEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - CreatorIdGetResponse::FetchASingleCreatorById(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorIdGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorIdGetResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn creator_lookup_get( - &self, - param_orcid: String, - context: &Context, - ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> { - // Query parameters - let query_orcid = format!("orcid={orcid}&", orcid = param_orcid.to_string()); - - let uri = format!( - "{}/v0/creator/lookup?{orcid}", - self.base_path, - orcid = utf8_percent_encode(&query_orcid, QUERY_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::CreatorEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - CreatorLookupGetResponse::FindASingleCreatorByExternalIdentifer( - body, - ) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorLookupGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorLookupGetResponse::NoSuchCreator(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - CreatorLookupGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn creator_post( - &self, - param_body: Option<models::CreatorEntity>, - context: &Context, - ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> { - let uri = format!("{}/v0/creator", self.base_path); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - let body = param_body - .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); - - if let Some(body) = body { - request.set_body(body.into_bytes()); - } - - request - .headers_mut() - .set(ContentType(mimetypes::requests::CREATOR_POST.clone())); - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 201 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::EntityEdit>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorPostResponse::Created(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorPostResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| CreatorPostResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn editgroup_id_accept_post( - &self, - param_id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/editgroup/{id}/accept", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Success>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupIdAcceptPostResponse::MergedEditgroupSuccessfully_( - body, - ) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupIdAcceptPostResponse::EditgroupIsInAnUnmergableState( - body, - ) - }), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupIdAcceptPostResponse::NoSuchEditgroup(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupIdAcceptPostResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn editgroup_id_get( - &self, - param_id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/editgroup/{id}", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Editgroup>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupIdGetResponse::FetchEditgroupByIdentifier(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| EditgroupIdGetResponse::NoSuchEditgroup(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupIdGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn editgroup_post( - &self, - context: &Context, - ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> { - let uri = format!("{}/v0/editgroup", self.base_path); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 201 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Editgroup>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| EditgroupPostResponse::SuccessfullyCreated(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditgroupPostResponse::InvalidRequestParameters(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| EditgroupPostResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn editor_username_changelog_get( - &self, - param_username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/editor/{username}/changelog", - self.base_path, - username = utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Changelogentry>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditorUsernameChangelogGetResponse::FindChanges_(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditorUsernameChangelogGetResponse::UsernameNotFound(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditorUsernameChangelogGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn editor_username_get( - &self, - param_username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/editor/{username}", - self.base_path, - username = utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Editor>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditorUsernameGetResponse::FetchGenericInformationAboutAnEditor( - body, - ) - }), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| EditorUsernameGetResponse::UsernameNotFound(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - EditorUsernameGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn file_id_get( - &self, - param_id: String, - context: &Context, - ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/file/{id}", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::FileEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FileIdGetResponse::FetchASingleFileById(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FileIdGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FileIdGetResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn file_lookup_get( - &self, - param_sha1: String, - context: &Context, - ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> { - // Query parameters - let query_sha1 = format!("sha1={sha1}&", sha1 = param_sha1.to_string()); - - let uri = format!( - "{}/v0/file/lookup?{sha1}", - self.base_path, - sha1 = utf8_percent_encode(&query_sha1, QUERY_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::FileEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - FileLookupGetResponse::FindASingleFileByExternalIdentifer(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FileLookupGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FileLookupGetResponse::NoSuchFile(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FileLookupGetResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn file_post( - &self, - param_body: Option<models::FileEntity>, - context: &Context, - ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> { - let uri = format!("{}/v0/file", self.base_path); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - let body = param_body - .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); - - if let Some(body) = body { - request.set_body(body.into_bytes()); - } - - request - .headers_mut() - .set(ContentType(mimetypes::requests::FILE_POST.clone())); - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 201 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::EntityEdit>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FilePostResponse::Created(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FilePostResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| FilePostResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn release_id_get( - &self, - param_id: String, - context: &Context, - ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/release/{id}", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::ReleaseEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ReleaseIdGetResponse::FetchASingleReleaseById(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleaseIdGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleaseIdGetResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn release_lookup_get( - &self, - param_doi: String, - context: &Context, - ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> { - // Query parameters - let query_doi = format!("doi={doi}&", doi = param_doi.to_string()); - - let uri = format!( - "{}/v0/release/lookup?{doi}", - self.base_path, - doi = utf8_percent_encode(&query_doi, QUERY_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::ReleaseEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ReleaseLookupGetResponse::FindASingleReleaseByExternalIdentifer( - body, - ) - }), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleaseLookupGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 404 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleaseLookupGetResponse::NoSuchRelease(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| { - ReleaseLookupGetResponse::GenericErrorResponse(body) - }), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn release_post( - &self, - param_body: Option<models::ReleaseEntity>, - context: &Context, - ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> { - let uri = format!("{}/v0/release", self.base_path); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - let body = param_body - .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); - - if let Some(body) = body { - request.set_body(body.into_bytes()); - } - - request - .headers_mut() - .set(ContentType(mimetypes::requests::RELEASE_POST.clone())); - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 201 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::EntityEdit>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleasePostResponse::Created(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleasePostResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| ReleasePostResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn work_id_get( - &self, - param_id: String, - context: &Context, - ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> { - let uri = format!( - "{}/v0/work/{id}", - self.base_path, - id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) - ); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Get, uri); - - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 200 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::WorkEntity>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| WorkIdGetResponse::FetchASingleWorkById(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| WorkIdGetResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| WorkIdGetResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } - - fn work_post( - &self, - param_body: Option<models::WorkEntity>, - context: &Context, - ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> { - let uri = format!("{}/v0/work", self.base_path); - - let uri = match Uri::from_str(&uri) { - Ok(uri) => uri, - Err(err) => { - return Box::new(futures::done(Err(ApiError(format!( - "Unable to build URI: {}", - err - ))))) - } - }; - - let mut request = hyper::Request::new(hyper::Method::Post, uri); - - let body = param_body - .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); - - if let Some(body) = body { - request.set_body(body.into_bytes()); - } - - request - .headers_mut() - .set(ContentType(mimetypes::requests::WORK_POST.clone())); - context - .x_span_id - .as_ref() - .map(|header| request.headers_mut().set(XSpanId(header.clone()))); - - let hyper_client = (self.hyper_client)(&*self.handle); - Box::new( - hyper_client - .call(request) - .map_err(|e| ApiError(format!("No response received: {}", e))) - .and_then(|mut response| match response.status().as_u16() { - 201 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::EntityEdit>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| WorkPostResponse::Created(body)), - ) as Box<Future<Item = _, Error = _>> - } - 400 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| WorkPostResponse::BadRequest(body)), - ) as Box<Future<Item = _, Error = _>> - } - 0 => { - let body = response.body(); - Box::new( - body.concat2() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))) - .and_then(|body| { - str::from_utf8(&body) - .map_err(|e| { - ApiError(format!("Response was not valid UTF8: {}", e)) - }) - .and_then(|body| { - serde_json::from_str::<models::Error>(body) - .map_err(|e| e.into()) - }) - }) - .map(move |body| WorkPostResponse::GenericErrorResponse(body)), - ) as Box<Future<Item = _, Error = _>> - } - code => { - let headers = response.headers().clone(); - Box::new(response.body().take(100).concat2().then(move |body| { - future::err(ApiError(format!( - "Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, - match body { - Ok(ref body) => match str::from_utf8(body) { - Ok(body) => Cow::from(body), - Err(e) => { - Cow::from(format!("<Body was not UTF8: {:?}>", e)) - } - }, - Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), - } - ))) - })) as Box<Future<Item = _, Error = _>> - } - }), - ) - } -} - -#[derive(Debug)] -pub enum ClientInitError { - InvalidScheme, - InvalidUri(hyper::error::UriError), - MissingHost, - SslError(openssl::error::ErrorStack), -} - -impl From<hyper::error::UriError> for ClientInitError { - fn from(err: hyper::error::UriError) -> ClientInitError { - ClientInitError::InvalidUri(err) - } -} - -impl From<openssl::error::ErrorStack> for ClientInitError { - fn from(err: openssl::error::ErrorStack) -> ClientInitError { - ClientInitError::SslError(err) - } -} - -impl fmt::Display for ClientInitError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - (self as &fmt::Debug).fmt(f) - } -} - -impl error::Error for ClientInitError { - fn description(&self) -> &str { - "Failed to produce a hyper client." - } -} diff --git a/rust/fatcat-api/src/lib.rs b/rust/fatcat-api/src/lib.rs index 36573537..e695daa7 100644 --- a/rust/fatcat-api/src/lib.rs +++ b/rust/fatcat-api/src/lib.rs @@ -1,12 +1,12 @@ -#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, - unused_extern_crates, non_camel_case_types)] +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)] extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; -extern crate chrono; extern crate futures; +extern crate chrono; + #[macro_use] extern crate lazy_static; #[macro_use] @@ -32,554 +32,441 @@ mod mimetypes; pub use swagger::{ApiError, Context, ContextWrapper}; -pub const BASE_PATH: &'static str = "/v0"; -pub const API_VERSION: &'static str = "0.1.0"; #[derive(Debug, PartialEq)] pub enum ContainerIdGetResponse { /// fetch a single container by id - FetchASingleContainerById(models::ContainerEntity), + FetchASingleContainerById ( models::ContainerEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum ContainerLookupGetResponse { /// find a single container by external identifer - FindASingleContainerByExternalIdentifer(models::ContainerEntity), + FindASingleContainerByExternalIdentifer ( models::ContainerEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// no such container - NoSuchContainer(models::Error), + NoSuchContainer ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum ContainerPostResponse { /// created - Created(models::EntityEdit), + Created ( models::EntityEdit ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum CreatorIdGetResponse { /// fetch a single creator by id - FetchASingleCreatorById(models::CreatorEntity), + FetchASingleCreatorById ( models::CreatorEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum CreatorLookupGetResponse { /// find a single creator by external identifer - FindASingleCreatorByExternalIdentifer(models::CreatorEntity), + FindASingleCreatorByExternalIdentifer ( models::CreatorEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// no such creator - NoSuchCreator(models::Error), + NoSuchCreator ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum CreatorPostResponse { /// created - Created(models::EntityEdit), + Created ( models::EntityEdit ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum EditgroupIdAcceptPostResponse { /// merged editgroup successfully (\"live\") - MergedEditgroupSuccessfully_(models::Success), + MergedEditgroupSuccessfully_ ( models::Success ) , /// editgroup is in an unmergable state - EditgroupIsInAnUnmergableState(models::Error), + EditgroupIsInAnUnmergableState ( models::Error ) , /// no such editgroup - NoSuchEditgroup(models::Error), + NoSuchEditgroup ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum EditgroupIdGetResponse { /// fetch editgroup by identifier - FetchEditgroupByIdentifier(models::Editgroup), + FetchEditgroupByIdentifier ( models::Editgroup ) , /// no such editgroup - NoSuchEditgroup(models::Error), + NoSuchEditgroup ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum EditgroupPostResponse { /// successfully created - SuccessfullyCreated(models::Editgroup), + SuccessfullyCreated ( models::Editgroup ) , /// invalid request parameters - InvalidRequestParameters(models::Error), + InvalidRequestParameters ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum EditorUsernameChangelogGetResponse { /// find changes (editgroups) by this editor which have been merged - FindChanges_(models::Changelogentry), + FindChanges_ ( models::Changelogentry ) , /// username not found - UsernameNotFound(models::Error), + UsernameNotFound ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum EditorUsernameGetResponse { /// fetch generic information about an editor - FetchGenericInformationAboutAnEditor(models::Editor), + FetchGenericInformationAboutAnEditor ( models::Editor ) , /// username not found - UsernameNotFound(models::Error), + UsernameNotFound ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum FileIdGetResponse { /// fetch a single file by id - FetchASingleFileById(models::FileEntity), + FetchASingleFileById ( models::FileEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum FileLookupGetResponse { /// find a single file by external identifer - FindASingleFileByExternalIdentifer(models::FileEntity), + FindASingleFileByExternalIdentifer ( models::FileEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// no such file - NoSuchFile(models::Error), + NoSuchFile ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum FilePostResponse { /// created - Created(models::EntityEdit), + Created ( models::EntityEdit ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum ReleaseIdGetResponse { /// fetch a single release by id - FetchASingleReleaseById(models::ReleaseEntity), + FetchASingleReleaseById ( models::ReleaseEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum ReleaseLookupGetResponse { /// find a single release by external identifer - FindASingleReleaseByExternalIdentifer(models::ReleaseEntity), + FindASingleReleaseByExternalIdentifer ( models::ReleaseEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// no such release - NoSuchRelease(models::Error), + NoSuchRelease ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum ReleasePostResponse { /// created - Created(models::EntityEdit), + Created ( models::EntityEdit ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum WorkIdGetResponse { /// fetch a single work by id - FetchASingleWorkById(models::WorkEntity), + FetchASingleWorkById ( models::WorkEntity ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } #[derive(Debug, PartialEq)] pub enum WorkPostResponse { /// created - Created(models::EntityEdit), + Created ( models::EntityEdit ) , /// bad request - BadRequest(models::Error), + BadRequest ( models::Error ) , /// generic error response - GenericErrorResponse(models::Error), + GenericErrorResponse ( models::Error ) , } + /// API pub trait Api { - fn container_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>>; - - fn container_lookup_get( - &self, - issn: String, - context: &Context, - ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>>; - - fn container_post( - &self, - body: Option<models::ContainerEntity>, - context: &Context, - ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>>; - - fn creator_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>>; - - fn creator_lookup_get( - &self, - orcid: String, - context: &Context, - ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>>; - - fn creator_post( - &self, - body: Option<models::CreatorEntity>, - context: &Context, - ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>>; - - fn editgroup_id_accept_post( - &self, - id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>>; - - fn editgroup_id_get( - &self, - id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>>; - - fn editgroup_post( - &self, - context: &Context, - ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>>; - - fn editor_username_changelog_get( - &self, - username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>>; - - fn editor_username_get( - &self, - username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>>; - - fn file_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>>; - - fn file_lookup_get( - &self, - sha1: String, - context: &Context, - ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>>; - - fn file_post( - &self, - body: Option<models::FileEntity>, - context: &Context, - ) -> Box<Future<Item = FilePostResponse, Error = ApiError>>; - - fn release_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>>; - - fn release_lookup_get( - &self, - doi: String, - context: &Context, - ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>>; - - fn release_post( - &self, - body: Option<models::ReleaseEntity>, - context: &Context, - ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>>; - - fn work_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>>; - - fn work_post( - &self, - body: Option<models::WorkEntity>, - context: &Context, - ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>>; + + + fn container_id_get(&self, id: String, context: &Context) -> Box<Future<Item=ContainerIdGetResponse, Error=ApiError> + Send>; + + + fn container_lookup_get(&self, issn: String, context: &Context) -> Box<Future<Item=ContainerLookupGetResponse, Error=ApiError> + Send>; + + + fn container_post(&self, body: Option<models::ContainerEntity>, context: &Context) -> Box<Future<Item=ContainerPostResponse, Error=ApiError> + Send>; + + + fn creator_id_get(&self, id: String, context: &Context) -> Box<Future<Item=CreatorIdGetResponse, Error=ApiError> + Send>; + + + fn creator_lookup_get(&self, orcid: String, context: &Context) -> Box<Future<Item=CreatorLookupGetResponse, Error=ApiError> + Send>; + + + fn creator_post(&self, body: Option<models::CreatorEntity>, context: &Context) -> Box<Future<Item=CreatorPostResponse, Error=ApiError> + Send>; + + + fn editgroup_id_accept_post(&self, id: i32, context: &Context) -> Box<Future<Item=EditgroupIdAcceptPostResponse, Error=ApiError> + Send>; + + + fn editgroup_id_get(&self, id: i32, context: &Context) -> Box<Future<Item=EditgroupIdGetResponse, Error=ApiError> + Send>; + + + fn editgroup_post(&self, context: &Context) -> Box<Future<Item=EditgroupPostResponse, Error=ApiError> + Send>; + + + fn editor_username_changelog_get(&self, username: String, context: &Context) -> Box<Future<Item=EditorUsernameChangelogGetResponse, Error=ApiError> + Send>; + + + fn editor_username_get(&self, username: String, context: &Context) -> Box<Future<Item=EditorUsernameGetResponse, Error=ApiError> + Send>; + + + fn file_id_get(&self, id: String, context: &Context) -> Box<Future<Item=FileIdGetResponse, Error=ApiError> + Send>; + + + fn file_lookup_get(&self, sha1: String, context: &Context) -> Box<Future<Item=FileLookupGetResponse, Error=ApiError> + Send>; + + + fn file_post(&self, body: Option<models::FileEntity>, context: &Context) -> Box<Future<Item=FilePostResponse, Error=ApiError> + Send>; + + + fn release_id_get(&self, id: String, context: &Context) -> Box<Future<Item=ReleaseIdGetResponse, Error=ApiError> + Send>; + + + fn release_lookup_get(&self, doi: String, context: &Context) -> Box<Future<Item=ReleaseLookupGetResponse, Error=ApiError> + Send>; + + + fn release_post(&self, body: Option<models::ReleaseEntity>, context: &Context) -> Box<Future<Item=ReleasePostResponse, Error=ApiError> + Send>; + + + fn work_id_get(&self, id: String, context: &Context) -> Box<Future<Item=WorkIdGetResponse, Error=ApiError> + Send>; + + + fn work_post(&self, body: Option<models::WorkEntity>, context: &Context) -> Box<Future<Item=WorkPostResponse, Error=ApiError> + Send>; + } /// API without a `Context` pub trait ApiNoContext { - fn container_id_get( - &self, - id: String, - ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>>; - - fn container_lookup_get( - &self, - issn: String, - ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>>; - - fn container_post( - &self, - body: Option<models::ContainerEntity>, - ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>>; - - fn creator_id_get( - &self, - id: String, - ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>>; - - fn creator_lookup_get( - &self, - orcid: String, - ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>>; - - fn creator_post( - &self, - body: Option<models::CreatorEntity>, - ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>>; - - fn editgroup_id_accept_post( - &self, - id: i32, - ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>>; - - fn editgroup_id_get( - &self, - id: i32, - ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>>; - - fn editgroup_post(&self) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>>; - - fn editor_username_changelog_get( - &self, - username: String, - ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>>; - - fn editor_username_get( - &self, - username: String, - ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>>; - - fn file_id_get(&self, id: String) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>>; - - fn file_lookup_get( - &self, - sha1: String, - ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>>; - - fn file_post( - &self, - body: Option<models::FileEntity>, - ) -> Box<Future<Item = FilePostResponse, Error = ApiError>>; - - fn release_id_get( - &self, - id: String, - ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>>; - - fn release_lookup_get( - &self, - doi: String, - ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>>; - - fn release_post( - &self, - body: Option<models::ReleaseEntity>, - ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>>; - - fn work_id_get(&self, id: String) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>>; - - fn work_post( - &self, - body: Option<models::WorkEntity>, - ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>>; + + + fn container_id_get(&self, id: String) -> Box<Future<Item=ContainerIdGetResponse, Error=ApiError> + Send>; + + + fn container_lookup_get(&self, issn: String) -> Box<Future<Item=ContainerLookupGetResponse, Error=ApiError> + Send>; + + + fn container_post(&self, body: Option<models::ContainerEntity>) -> Box<Future<Item=ContainerPostResponse, Error=ApiError> + Send>; + + + fn creator_id_get(&self, id: String) -> Box<Future<Item=CreatorIdGetResponse, Error=ApiError> + Send>; + + + fn creator_lookup_get(&self, orcid: String) -> Box<Future<Item=CreatorLookupGetResponse, Error=ApiError> + Send>; + + + fn creator_post(&self, body: Option<models::CreatorEntity>) -> Box<Future<Item=CreatorPostResponse, Error=ApiError> + Send>; + + + fn editgroup_id_accept_post(&self, id: i32) -> Box<Future<Item=EditgroupIdAcceptPostResponse, Error=ApiError> + Send>; + + + fn editgroup_id_get(&self, id: i32) -> Box<Future<Item=EditgroupIdGetResponse, Error=ApiError> + Send>; + + + fn editgroup_post(&self) -> Box<Future<Item=EditgroupPostResponse, Error=ApiError> + Send>; + + + fn editor_username_changelog_get(&self, username: String) -> Box<Future<Item=EditorUsernameChangelogGetResponse, Error=ApiError> + Send>; + + + fn editor_username_get(&self, username: String) -> Box<Future<Item=EditorUsernameGetResponse, Error=ApiError> + Send>; + + + fn file_id_get(&self, id: String) -> Box<Future<Item=FileIdGetResponse, Error=ApiError> + Send>; + + + fn file_lookup_get(&self, sha1: String) -> Box<Future<Item=FileLookupGetResponse, Error=ApiError> + Send>; + + + fn file_post(&self, body: Option<models::FileEntity>) -> Box<Future<Item=FilePostResponse, Error=ApiError> + Send>; + + + fn release_id_get(&self, id: String) -> Box<Future<Item=ReleaseIdGetResponse, Error=ApiError> + Send>; + + + fn release_lookup_get(&self, doi: String) -> Box<Future<Item=ReleaseLookupGetResponse, Error=ApiError> + Send>; + + + fn release_post(&self, body: Option<models::ReleaseEntity>) -> Box<Future<Item=ReleasePostResponse, Error=ApiError> + Send>; + + + fn work_id_get(&self, id: String) -> Box<Future<Item=WorkIdGetResponse, Error=ApiError> + Send>; + + + fn work_post(&self, body: Option<models::WorkEntity>) -> Box<Future<Item=WorkPostResponse, Error=ApiError> + Send>; + } /// Trait to extend an API to make it easy to bind it to a context. -pub trait ContextWrapperExt<'a> -where - Self: Sized, -{ +pub trait ContextWrapperExt<'a> where Self: Sized { /// Binds this API to a context. fn with_context(self: &'a Self, context: Context) -> ContextWrapper<'a, Self>; } impl<'a, T: Api + Sized> ContextWrapperExt<'a> for T { fn with_context(self: &'a T, context: Context) -> ContextWrapper<'a, T> { - ContextWrapper::<T>::new(self, context) + ContextWrapper::<T>::new(self, context) } } impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { - fn container_id_get( - &self, - id: String, - ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> { + + + fn container_id_get(&self, id: String) -> Box<Future<Item=ContainerIdGetResponse, Error=ApiError> + Send> { self.api().container_id_get(id, &self.context()) } - fn container_lookup_get( - &self, - issn: String, - ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> { + + fn container_lookup_get(&self, issn: String) -> Box<Future<Item=ContainerLookupGetResponse, Error=ApiError> + Send> { self.api().container_lookup_get(issn, &self.context()) } - fn container_post( - &self, - body: Option<models::ContainerEntity>, - ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> { + + fn container_post(&self, body: Option<models::ContainerEntity>) -> Box<Future<Item=ContainerPostResponse, Error=ApiError> + Send> { self.api().container_post(body, &self.context()) } - fn creator_id_get( - &self, - id: String, - ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> { + + fn creator_id_get(&self, id: String) -> Box<Future<Item=CreatorIdGetResponse, Error=ApiError> + Send> { self.api().creator_id_get(id, &self.context()) } - fn creator_lookup_get( - &self, - orcid: String, - ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> { + + fn creator_lookup_get(&self, orcid: String) -> Box<Future<Item=CreatorLookupGetResponse, Error=ApiError> + Send> { self.api().creator_lookup_get(orcid, &self.context()) } - fn creator_post( - &self, - body: Option<models::CreatorEntity>, - ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> { + + fn creator_post(&self, body: Option<models::CreatorEntity>) -> Box<Future<Item=CreatorPostResponse, Error=ApiError> + Send> { self.api().creator_post(body, &self.context()) } - fn editgroup_id_accept_post( - &self, - id: i32, - ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> { + + fn editgroup_id_accept_post(&self, id: i32) -> Box<Future<Item=EditgroupIdAcceptPostResponse, Error=ApiError> + Send> { self.api().editgroup_id_accept_post(id, &self.context()) } - fn editgroup_id_get( - &self, - id: i32, - ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> { + + fn editgroup_id_get(&self, id: i32) -> Box<Future<Item=EditgroupIdGetResponse, Error=ApiError> + Send> { self.api().editgroup_id_get(id, &self.context()) } - fn editgroup_post(&self) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> { + + fn editgroup_post(&self) -> Box<Future<Item=EditgroupPostResponse, Error=ApiError> + Send> { self.api().editgroup_post(&self.context()) } - fn editor_username_changelog_get( - &self, - username: String, - ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> { - self.api() - .editor_username_changelog_get(username, &self.context()) + + fn editor_username_changelog_get(&self, username: String) -> Box<Future<Item=EditorUsernameChangelogGetResponse, Error=ApiError> + Send> { + self.api().editor_username_changelog_get(username, &self.context()) } - fn editor_username_get( - &self, - username: String, - ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> { + + fn editor_username_get(&self, username: String) -> Box<Future<Item=EditorUsernameGetResponse, Error=ApiError> + Send> { self.api().editor_username_get(username, &self.context()) } - fn file_id_get(&self, id: String) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> { + + fn file_id_get(&self, id: String) -> Box<Future<Item=FileIdGetResponse, Error=ApiError> + Send> { self.api().file_id_get(id, &self.context()) } - fn file_lookup_get( - &self, - sha1: String, - ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> { + + fn file_lookup_get(&self, sha1: String) -> Box<Future<Item=FileLookupGetResponse, Error=ApiError> + Send> { self.api().file_lookup_get(sha1, &self.context()) } - fn file_post( - &self, - body: Option<models::FileEntity>, - ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> { + + fn file_post(&self, body: Option<models::FileEntity>) -> Box<Future<Item=FilePostResponse, Error=ApiError> + Send> { self.api().file_post(body, &self.context()) } - fn release_id_get( - &self, - id: String, - ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> { + + fn release_id_get(&self, id: String) -> Box<Future<Item=ReleaseIdGetResponse, Error=ApiError> + Send> { self.api().release_id_get(id, &self.context()) } - fn release_lookup_get( - &self, - doi: String, - ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> { + + fn release_lookup_get(&self, doi: String) -> Box<Future<Item=ReleaseLookupGetResponse, Error=ApiError> + Send> { self.api().release_lookup_get(doi, &self.context()) } - fn release_post( - &self, - body: Option<models::ReleaseEntity>, - ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> { + + fn release_post(&self, body: Option<models::ReleaseEntity>) -> Box<Future<Item=ReleasePostResponse, Error=ApiError> + Send> { self.api().release_post(body, &self.context()) } - fn work_id_get(&self, id: String) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> { + + fn work_id_get(&self, id: String) -> Box<Future<Item=WorkIdGetResponse, Error=ApiError> + Send> { self.api().work_id_get(id, &self.context()) } - fn work_post( - &self, - body: Option<models::WorkEntity>, - ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> { + + fn work_post(&self, body: Option<models::WorkEntity>) -> Box<Future<Item=WorkPostResponse, Error=ApiError> + Send> { self.api().work_post(body, &self.context()) } + } #[cfg(feature = "client")] @@ -594,6 +481,6 @@ pub mod server; // Re-export router() as a top-level name #[cfg(feature = "server")] -pub use self::server::Service; +pub use self::server::router; pub mod models; diff --git a/rust/fatcat-api/src/mimetypes.rs b/rust/fatcat-api/src/mimetypes.rs index dfbff890..c0b83a05 100644 --- a/rust/fatcat-api/src/mimetypes.rs +++ b/rust/fatcat-api/src/mimetypes.rs @@ -6,308 +6,276 @@ pub mod responses { // The macro is called per-operation to beat the recursion limit /// Create Mime objects for the response content types for ContainerIdGet lazy_static! { - pub static ref CONTAINER_ID_GET_FETCH_A_SINGLE_CONTAINER_BY_ID: Mime = - "application/json".parse().unwrap(); + pub static ref CONTAINER_ID_GET_FETCH_A_SINGLE_CONTAINER_BY_ID: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerIdGet lazy_static! { - pub static ref CONTAINER_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref CONTAINER_ID_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerIdGet lazy_static! { - pub static ref CONTAINER_ID_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref CONTAINER_ID_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerLookupGet lazy_static! { - pub static ref CONTAINER_LOOKUP_GET_FIND_A_SINGLE_CONTAINER_BY_EXTERNAL_IDENTIFER: Mime = - "application/json".parse().unwrap(); + pub static ref CONTAINER_LOOKUP_GET_FIND_A_SINGLE_CONTAINER_BY_EXTERNAL_IDENTIFER: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerLookupGet lazy_static! { - pub static ref CONTAINER_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref CONTAINER_LOOKUP_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerLookupGet lazy_static! { - pub static ref CONTAINER_LOOKUP_GET_NO_SUCH_CONTAINER: Mime = - "application/json".parse().unwrap(); + pub static ref CONTAINER_LOOKUP_GET_NO_SUCH_CONTAINER: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerLookupGet lazy_static! { - pub static ref CONTAINER_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref CONTAINER_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerPost lazy_static! { - pub static ref CONTAINER_POST_CREATED: Mime = "application/json".parse().unwrap(); + pub static ref CONTAINER_POST_CREATED: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerPost lazy_static! { - pub static ref CONTAINER_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref CONTAINER_POST_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ContainerPost lazy_static! { - pub static ref CONTAINER_POST_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref CONTAINER_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorIdGet lazy_static! { - pub static ref CREATOR_ID_GET_FETCH_A_SINGLE_CREATOR_BY_ID: Mime = - "application/json".parse().unwrap(); + pub static ref CREATOR_ID_GET_FETCH_A_SINGLE_CREATOR_BY_ID: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorIdGet lazy_static! { - pub static ref CREATOR_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_ID_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorIdGet lazy_static! { - pub static ref CREATOR_ID_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref CREATOR_ID_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorLookupGet lazy_static! { - pub static ref CREATOR_LOOKUP_GET_FIND_A_SINGLE_CREATOR_BY_EXTERNAL_IDENTIFER: Mime = - "application/json".parse().unwrap(); + pub static ref CREATOR_LOOKUP_GET_FIND_A_SINGLE_CREATOR_BY_EXTERNAL_IDENTIFER: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorLookupGet lazy_static! { - pub static ref CREATOR_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_LOOKUP_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorLookupGet lazy_static! { - pub static ref CREATOR_LOOKUP_GET_NO_SUCH_CREATOR: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_LOOKUP_GET_NO_SUCH_CREATOR: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorLookupGet lazy_static! { - pub static ref CREATOR_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref CREATOR_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorPost lazy_static! { - pub static ref CREATOR_POST_CREATED: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_POST_CREATED: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorPost lazy_static! { - pub static ref CREATOR_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_POST_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for CreatorPost lazy_static! { - pub static ref CREATOR_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdAcceptPost lazy_static! { - pub static ref EDITGROUP_ID_ACCEPT_POST_MERGED_EDITGROUP_SUCCESSFULLY_: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_ACCEPT_POST_MERGED_EDITGROUP_SUCCESSFULLY_: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdAcceptPost lazy_static! { - pub static ref EDITGROUP_ID_ACCEPT_POST_EDITGROUP_IS_IN_AN_UNMERGABLE_STATE: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_ACCEPT_POST_EDITGROUP_IS_IN_AN_UNMERGABLE_STATE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdAcceptPost lazy_static! { - pub static ref EDITGROUP_ID_ACCEPT_POST_NO_SUCH_EDITGROUP: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_ACCEPT_POST_NO_SUCH_EDITGROUP: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdAcceptPost lazy_static! { - pub static ref EDITGROUP_ID_ACCEPT_POST_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_ACCEPT_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdGet lazy_static! { - pub static ref EDITGROUP_ID_GET_FETCH_EDITGROUP_BY_IDENTIFIER: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_GET_FETCH_EDITGROUP_BY_IDENTIFIER: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdGet lazy_static! { - pub static ref EDITGROUP_ID_GET_NO_SUCH_EDITGROUP: Mime = "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_GET_NO_SUCH_EDITGROUP: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupIdGet lazy_static! { - pub static ref EDITGROUP_ID_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_ID_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupPost lazy_static! { - pub static ref EDITGROUP_POST_SUCCESSFULLY_CREATED: Mime = "application/json".parse().unwrap(); + pub static ref EDITGROUP_POST_SUCCESSFULLY_CREATED: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupPost lazy_static! { - pub static ref EDITGROUP_POST_INVALID_REQUEST_PARAMETERS: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_POST_INVALID_REQUEST_PARAMETERS: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditgroupPost lazy_static! { - pub static ref EDITGROUP_POST_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref EDITGROUP_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditorUsernameChangelogGet lazy_static! { - pub static ref EDITOR_USERNAME_CHANGELOG_GET_FIND_CHANGES_: Mime = - "application/json".parse().unwrap(); + pub static ref EDITOR_USERNAME_CHANGELOG_GET_FIND_CHANGES_: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditorUsernameChangelogGet lazy_static! { - pub static ref EDITOR_USERNAME_CHANGELOG_GET_USERNAME_NOT_FOUND: Mime = - "application/json".parse().unwrap(); + pub static ref EDITOR_USERNAME_CHANGELOG_GET_USERNAME_NOT_FOUND: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditorUsernameChangelogGet lazy_static! { - pub static ref EDITOR_USERNAME_CHANGELOG_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref EDITOR_USERNAME_CHANGELOG_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditorUsernameGet lazy_static! { - pub static ref EDITOR_USERNAME_GET_FETCH_GENERIC_INFORMATION_ABOUT_AN_EDITOR: Mime = - "application/json".parse().unwrap(); + pub static ref EDITOR_USERNAME_GET_FETCH_GENERIC_INFORMATION_ABOUT_AN_EDITOR: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditorUsernameGet lazy_static! { - pub static ref EDITOR_USERNAME_GET_USERNAME_NOT_FOUND: Mime = - "application/json".parse().unwrap(); + pub static ref EDITOR_USERNAME_GET_USERNAME_NOT_FOUND: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for EditorUsernameGet lazy_static! { - pub static ref EDITOR_USERNAME_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref EDITOR_USERNAME_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileIdGet lazy_static! { - pub static ref FILE_ID_GET_FETCH_A_SINGLE_FILE_BY_ID: Mime = - "application/json".parse().unwrap(); + pub static ref FILE_ID_GET_FETCH_A_SINGLE_FILE_BY_ID: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileIdGet lazy_static! { - pub static ref FILE_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref FILE_ID_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileIdGet lazy_static! { - pub static ref FILE_ID_GET_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); + pub static ref FILE_ID_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileLookupGet lazy_static! { - pub static ref FILE_LOOKUP_GET_FIND_A_SINGLE_FILE_BY_EXTERNAL_IDENTIFER: Mime = - "application/json".parse().unwrap(); + pub static ref FILE_LOOKUP_GET_FIND_A_SINGLE_FILE_BY_EXTERNAL_IDENTIFER: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileLookupGet lazy_static! { - pub static ref FILE_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref FILE_LOOKUP_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileLookupGet lazy_static! { - pub static ref FILE_LOOKUP_GET_NO_SUCH_FILE: Mime = "application/json".parse().unwrap(); + pub static ref FILE_LOOKUP_GET_NO_SUCH_FILE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FileLookupGet lazy_static! { - pub static ref FILE_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref FILE_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FilePost lazy_static! { - pub static ref FILE_POST_CREATED: Mime = "application/json".parse().unwrap(); + pub static ref FILE_POST_CREATED: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FilePost lazy_static! { - pub static ref FILE_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref FILE_POST_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for FilePost lazy_static! { - pub static ref FILE_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); + pub static ref FILE_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseIdGet lazy_static! { - pub static ref RELEASE_ID_GET_FETCH_A_SINGLE_RELEASE_BY_ID: Mime = - "application/json".parse().unwrap(); + pub static ref RELEASE_ID_GET_FETCH_A_SINGLE_RELEASE_BY_ID: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseIdGet lazy_static! { - pub static ref RELEASE_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_ID_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseIdGet lazy_static! { - pub static ref RELEASE_ID_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref RELEASE_ID_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseLookupGet lazy_static! { - pub static ref RELEASE_LOOKUP_GET_FIND_A_SINGLE_RELEASE_BY_EXTERNAL_IDENTIFER: Mime = - "application/json".parse().unwrap(); + pub static ref RELEASE_LOOKUP_GET_FIND_A_SINGLE_RELEASE_BY_EXTERNAL_IDENTIFER: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseLookupGet lazy_static! { - pub static ref RELEASE_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_LOOKUP_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseLookupGet lazy_static! { - pub static ref RELEASE_LOOKUP_GET_NO_SUCH_RELEASE: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_LOOKUP_GET_NO_SUCH_RELEASE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleaseLookupGet lazy_static! { - pub static ref RELEASE_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = - "application/json".parse().unwrap(); + pub static ref RELEASE_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleasePost lazy_static! { - pub static ref RELEASE_POST_CREATED: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_POST_CREATED: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleasePost lazy_static! { - pub static ref RELEASE_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_POST_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for ReleasePost lazy_static! { - pub static ref RELEASE_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for WorkIdGet lazy_static! { - pub static ref WORK_ID_GET_FETCH_A_SINGLE_WORK_BY_ID: Mime = - "application/json".parse().unwrap(); + pub static ref WORK_ID_GET_FETCH_A_SINGLE_WORK_BY_ID: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for WorkIdGet lazy_static! { - pub static ref WORK_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref WORK_ID_GET_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for WorkIdGet lazy_static! { - pub static ref WORK_ID_GET_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); + pub static ref WORK_ID_GET_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for WorkPost lazy_static! { - pub static ref WORK_POST_CREATED: Mime = "application/json".parse().unwrap(); + pub static ref WORK_POST_CREATED: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for WorkPost lazy_static! { - pub static ref WORK_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); + pub static ref WORK_POST_BAD_REQUEST: Mime = mime!(Application/Json); } /// Create Mime objects for the response content types for WorkPost lazy_static! { - pub static ref WORK_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); + pub static ref WORK_POST_GENERIC_ERROR_RESPONSE: Mime = mime!(Application/Json); } } pub mod requests { use hyper::mime::*; - /// Create Mime objects for the request content types for ContainerPost + /// Create Mime objects for the request content types for ContainerPost lazy_static! { - pub static ref CONTAINER_POST: Mime = "application/json".parse().unwrap(); + pub static ref CONTAINER_POST: Mime = mime!(Application/Json); } - /// Create Mime objects for the request content types for CreatorPost + /// Create Mime objects for the request content types for CreatorPost lazy_static! { - pub static ref CREATOR_POST: Mime = "application/json".parse().unwrap(); + pub static ref CREATOR_POST: Mime = mime!(Application/Json); } - /// Create Mime objects for the request content types for FilePost + /// Create Mime objects for the request content types for FilePost lazy_static! { - pub static ref FILE_POST: Mime = "application/json".parse().unwrap(); + pub static ref FILE_POST: Mime = mime!(Application/Json); } - /// Create Mime objects for the request content types for ReleasePost + /// Create Mime objects for the request content types for ReleasePost lazy_static! { - pub static ref RELEASE_POST: Mime = "application/json".parse().unwrap(); + pub static ref RELEASE_POST: Mime = mime!(Application/Json); } - /// Create Mime objects for the request content types for WorkPost + /// Create Mime objects for the request content types for WorkPost lazy_static! { - pub static ref WORK_POST: Mime = "application/json".parse().unwrap(); + pub static ref WORK_POST: Mime = mime!(Application/Json); } } diff --git a/rust/fatcat-api/src/models.rs b/rust/fatcat-api/src/models.rs index 3d104b78..1d7ed56a 100644 --- a/rust/fatcat-api/src/models.rs +++ b/rust/fatcat-api/src/models.rs @@ -2,28 +2,31 @@ extern crate chrono; extern crate uuid; + use serde::ser::Serializer; -use models; use std::collections::HashMap; +use models; use swagger; + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Changelogentry { #[serde(rename = "index")] pub index: isize, #[serde(rename = "editgroup_id")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup_id: Option<isize>, #[serde(rename = "timestamp")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub timestamp: Option<chrono::DateTime<chrono::Utc>>, + } impl Changelogentry { - pub fn new(index: isize) -> Changelogentry { + pub fn new(index: isize, ) -> Changelogentry { Changelogentry { index: index, editgroup_id: None, @@ -35,41 +38,42 @@ impl Changelogentry { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ContainerEntity { #[serde(rename = "issn")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub issn: Option<String>, #[serde(rename = "publisher")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub publisher: Option<String>, #[serde(rename = "parent")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub parent: Option<String>, #[serde(rename = "name")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub name: Option<String>, // Note: inline enums are not fully supported by swagger-codegen #[serde(rename = "state")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub state: Option<String>, #[serde(rename = "ident")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub ident: Option<String>, #[serde(rename = "revision")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub revision: Option<isize>, #[serde(rename = "redirect")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub redirect: Option<String>, #[serde(rename = "editgroup")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup: Option<isize>, + } impl ContainerEntity { @@ -91,33 +95,34 @@ impl ContainerEntity { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct CreatorEntity { #[serde(rename = "orcid")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub orcid: Option<String>, #[serde(rename = "name")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub name: Option<String>, #[serde(rename = "editgroup")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup: Option<isize>, #[serde(rename = "redirect")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub redirect: Option<String>, #[serde(rename = "revision")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub revision: Option<isize>, #[serde(rename = "ident")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub ident: Option<String>, // Note: inline enums are not fully supported by swagger-codegen #[serde(rename = "state")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub state: Option<String>, + } impl CreatorEntity { @@ -141,10 +146,11 @@ pub struct Editgroup { #[serde(rename = "editor_id")] pub editor_id: isize, + } impl Editgroup { - pub fn new(id: isize, editor_id: isize) -> Editgroup { + pub fn new(id: isize, editor_id: isize, ) -> Editgroup { Editgroup { id: id, editor_id: editor_id, @@ -156,31 +162,35 @@ impl Editgroup { pub struct Editor { #[serde(rename = "username")] pub username: String, + } impl Editor { - pub fn new(username: String) -> Editor { - Editor { username: username } + pub fn new(username: String, ) -> Editor { + Editor { + username: username, + } } } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct EntityEdit { #[serde(rename = "editgroup_id")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup_id: Option<isize>, #[serde(rename = "revision")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub revision: Option<isize>, #[serde(rename = "ident")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub ident: Option<String>, #[serde(rename = "id")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub id: Option<isize>, + } impl EntityEdit { @@ -198,48 +208,52 @@ impl EntityEdit { pub struct Error { #[serde(rename = "message")] pub message: String, + } impl Error { - pub fn new(message: String) -> Error { - Error { message: message } + pub fn new(message: String, ) -> Error { + Error { + message: message, + } } } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct FileEntity { #[serde(rename = "url")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub url: Option<String>, #[serde(rename = "sha1")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub sha1: Option<String>, #[serde(rename = "size")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub size: Option<isize>, #[serde(rename = "editgroup")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup: Option<isize>, #[serde(rename = "redirect")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub redirect: Option<String>, #[serde(rename = "revision")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub revision: Option<isize>, #[serde(rename = "ident")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub ident: Option<String>, // Note: inline enums are not fully supported by swagger-codegen #[serde(rename = "state")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub state: Option<String>, + } impl FileEntity { @@ -260,57 +274,58 @@ impl FileEntity { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct ReleaseEntity { #[serde(rename = "issue")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub issue: Option<String>, #[serde(rename = "pages")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub pages: Option<String>, #[serde(rename = "volume")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub volume: Option<String>, #[serde(rename = "doi")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub doi: Option<String>, #[serde(rename = "release_type")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub release_type: Option<String>, #[serde(rename = "license")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub license: Option<String>, #[serde(rename = "container")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub container: Option<String>, #[serde(rename = "work")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub work: Option<String>, // Note: inline enums are not fully supported by swagger-codegen #[serde(rename = "state")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub state: Option<String>, #[serde(rename = "ident")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub ident: Option<String>, #[serde(rename = "revision")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub revision: Option<isize>, #[serde(rename = "redirect")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub redirect: Option<String>, #[serde(rename = "editgroup")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup: Option<isize>, + } impl ReleaseEntity { @@ -337,44 +352,48 @@ impl ReleaseEntity { pub struct Success { #[serde(rename = "message")] pub message: String, + } impl Success { - pub fn new(message: String) -> Success { - Success { message: message } + pub fn new(message: String, ) -> Success { + Success { + message: message, + } } } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct WorkEntity { #[serde(rename = "work_type")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub work_type: Option<String>, #[serde(rename = "title")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub title: Option<String>, #[serde(rename = "editgroup")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub editgroup: Option<isize>, #[serde(rename = "redirect")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub redirect: Option<String>, #[serde(rename = "revision")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub revision: Option<isize>, #[serde(rename = "ident")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub ident: Option<String>, // Note: inline enums are not fully supported by swagger-codegen #[serde(rename = "state")] - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")] pub state: Option<String>, + } impl WorkEntity { diff --git a/rust/fatcat-api/src/server.rs b/rust/fatcat-api/src/server.rs new file mode 100644 index 00000000..cb307ad4 --- /dev/null +++ b/rust/fatcat-api/src/server.rs @@ -0,0 +1,1702 @@ +#![allow(unused_extern_crates)] +extern crate serde_ignored; +extern crate iron; +extern crate router; +extern crate bodyparser; +extern crate urlencoded; +extern crate uuid; +extern crate chrono; + + +use futures::Future; +use futures::future; +use futures::{stream, Stream}; +use hyper; +use hyper::header::{Headers, ContentType}; +use self::iron::prelude::*; +use self::iron::{status, modifiers, BeforeMiddleware}; +use self::iron::url::percent_encoding::percent_decode; +use self::router::Router; +use self::urlencoded::UrlEncodedQuery; +use mimetypes; + + +use serde_json; + + +#[allow(unused_imports)] +use std::collections::{HashMap, BTreeMap}; +#[allow(unused_imports)] +use swagger; +use std::io::Error; + +#[allow(unused_imports)] +use std::collections::BTreeSet; + +pub use swagger::auth::Authorization; +use swagger::auth::{AuthData, Scopes}; +use swagger::{ApiError, Context, XSpanId}; + +use {Api, + ContainerIdGetResponse, + ContainerLookupGetResponse, + ContainerPostResponse, + CreatorIdGetResponse, + CreatorLookupGetResponse, + CreatorPostResponse, + EditgroupIdAcceptPostResponse, + EditgroupIdGetResponse, + EditgroupPostResponse, + EditorUsernameChangelogGetResponse, + EditorUsernameGetResponse, + FileIdGetResponse, + FileLookupGetResponse, + FilePostResponse, + ReleaseIdGetResponse, + ReleaseLookupGetResponse, + ReleasePostResponse, + WorkIdGetResponse, + WorkPostResponse + }; +#[allow(unused_imports)] +use models; + +header! { (Warning, "Warning") => [String] } + +/// Create a new router for `Api` +pub fn router<T>(api: T) -> Router where T: Api + Send + Sync + Clone + 'static { + let mut router = Router::new(); + add_routes(&mut router, api); + router +} + +/// Add routes for `Api` to a provided router. +/// +/// Note that these routes are added straight onto the router. This means that if the router +/// already has a route for an endpoint which clashes with those provided by this API, then the +/// old route will be lost. +/// +/// It is generally a bad idea to add routes in this way to an existing router, which may have +/// routes on it for other APIs. Distinct APIs should be behind distinct paths to encourage +/// separation of interfaces, which this function does not enforce. APIs should not overlap. +/// +/// Alternative approaches include: +/// +/// - generate an `iron::middleware::Handler` (usually a `router::Router` or +/// `iron::middleware::chain`) for each interface, and add those handlers inside an existing +/// router, mounted at different paths - so the interfaces are separated by path +/// - use a different instance of `iron::Iron` for each interface - so the interfaces are +/// separated by the address/port they listen on +/// +/// This function exists to allow legacy code, which doesn't separate its APIs properly, to make +/// use of this crate. +#[deprecated(note="APIs should not overlap - only for use in legacy code.")] +pub fn route<T>(router: &mut Router, api: T) where T: Api + Send + Sync + Clone + 'static { + add_routes(router, api) +} + +/// Add routes for `Api` to a provided router +fn add_routes<T>(router: &mut Router, api: T) where T: Api + Send + Sync + Clone + 'static { + + let api_clone = api.clone(); + router.get( + "/v0/container/:id", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.container_id_get(param_id, context).wait() { + Ok(rsp) => match rsp { + ContainerIdGetResponse::FetchASingleContainerById(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_ID_GET_FETCH_A_SINGLE_CONTAINER_BY_ID.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ContainerIdGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_ID_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ContainerIdGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "ContainerIdGet"); + + let api_clone = api.clone(); + router.get( + "/v0/container/lookup", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = req.get::<UrlEncodedQuery>().unwrap_or_default(); + let param_issn = query_params.get("issn") + .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter issn".to_string())))? + .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter issn was empty".to_string())))? + .parse::<String>().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter issn - doesn't match schema: {}", e))))?; + + + match api.container_lookup_get(param_issn, context).wait() { + Ok(rsp) => match rsp { + ContainerLookupGetResponse::FindASingleContainerByExternalIdentifer(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_FIND_A_SINGLE_CONTAINER_BY_EXTERNAL_IDENTIFER.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ContainerLookupGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ContainerLookupGetResponse::NoSuchContainer(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_NO_SUCH_CONTAINER.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ContainerLookupGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "ContainerLookupGet"); + + let api_clone = api.clone(); + router.post( + "/v0/container", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + + let param_body = req.get::<bodyparser::Raw>().unwrap_or(None); + + let mut unused_elements = Vec::new(); + + let param_body = if let Some(param_body_raw) = param_body { + let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); + + let param_body: Option<models::ContainerEntity> = serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }).unwrap_or(None); + + param_body + } else { + None + };; + + + match api.container_post(param_body, context).wait() { + Ok(rsp) => match rsp { + ContainerPostResponse::Created(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(201), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_POST_CREATED.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + ContainerPostResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_POST_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + ContainerPostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::CONTAINER_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "ContainerPost"); + + let api_clone = api.clone(); + router.get( + "/v0/creator/:id", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.creator_id_get(param_id, context).wait() { + Ok(rsp) => match rsp { + CreatorIdGetResponse::FetchASingleCreatorById(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_ID_GET_FETCH_A_SINGLE_CREATOR_BY_ID.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + CreatorIdGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_ID_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + CreatorIdGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "CreatorIdGet"); + + let api_clone = api.clone(); + router.get( + "/v0/creator/lookup", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = req.get::<UrlEncodedQuery>().unwrap_or_default(); + let param_orcid = query_params.get("orcid") + .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter orcid".to_string())))? + .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter orcid was empty".to_string())))? + .parse::<String>().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter orcid - doesn't match schema: {}", e))))?; + + + match api.creator_lookup_get(param_orcid, context).wait() { + Ok(rsp) => match rsp { + CreatorLookupGetResponse::FindASingleCreatorByExternalIdentifer(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_FIND_A_SINGLE_CREATOR_BY_EXTERNAL_IDENTIFER.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + CreatorLookupGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + CreatorLookupGetResponse::NoSuchCreator(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_NO_SUCH_CREATOR.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + CreatorLookupGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "CreatorLookupGet"); + + let api_clone = api.clone(); + router.post( + "/v0/creator", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + + let param_body = req.get::<bodyparser::Raw>().unwrap_or(None); + + let mut unused_elements = Vec::new(); + + let param_body = if let Some(param_body_raw) = param_body { + let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); + + let param_body: Option<models::CreatorEntity> = serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }).unwrap_or(None); + + param_body + } else { + None + };; + + + match api.creator_post(param_body, context).wait() { + Ok(rsp) => match rsp { + CreatorPostResponse::Created(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(201), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_POST_CREATED.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + CreatorPostResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_POST_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + CreatorPostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::CREATOR_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "CreatorPost"); + + let api_clone = api.clone(); + router.post( + "/v0/editgroup/:id/accept", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.editgroup_id_accept_post(param_id, context).wait() { + Ok(rsp) => match rsp { + EditgroupIdAcceptPostResponse::MergedEditgroupSuccessfully_(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_MERGED_EDITGROUP_SUCCESSFULLY_.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupIdAcceptPostResponse::EditgroupIsInAnUnmergableState(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_EDITGROUP_IS_IN_AN_UNMERGABLE_STATE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupIdAcceptPostResponse::NoSuchEditgroup(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_NO_SUCH_EDITGROUP.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupIdAcceptPostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "EditgroupIdAcceptPost"); + + let api_clone = api.clone(); + router.get( + "/v0/editgroup/:id", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.editgroup_id_get(param_id, context).wait() { + Ok(rsp) => match rsp { + EditgroupIdGetResponse::FetchEditgroupByIdentifier(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_FETCH_EDITGROUP_BY_IDENTIFIER.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupIdGetResponse::NoSuchEditgroup(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_NO_SUCH_EDITGROUP.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupIdGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "EditgroupIdGet"); + + let api_clone = api.clone(); + router.post( + "/v0/editgroup", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + + match api.editgroup_post(context).wait() { + Ok(rsp) => match rsp { + EditgroupPostResponse::SuccessfullyCreated(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(201), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_POST_SUCCESSFULLY_CREATED.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupPostResponse::InvalidRequestParameters(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_POST_INVALID_REQUEST_PARAMETERS.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditgroupPostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITGROUP_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "EditgroupPost"); + + let api_clone = api.clone(); + router.get( + "/v0/editor/:username/changelog", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_username = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("username").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter username".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter username: {}", e))))? + }; + + + + match api.editor_username_changelog_get(param_username, context).wait() { + Ok(rsp) => match rsp { + EditorUsernameChangelogGetResponse::FindChanges_(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_FIND_CHANGES_.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditorUsernameChangelogGetResponse::UsernameNotFound(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_USERNAME_NOT_FOUND.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditorUsernameChangelogGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "EditorUsernameChangelogGet"); + + let api_clone = api.clone(); + router.get( + "/v0/editor/:username", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_username = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("username").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter username".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter username: {}", e))))? + }; + + + + match api.editor_username_get(param_username, context).wait() { + Ok(rsp) => match rsp { + EditorUsernameGetResponse::FetchGenericInformationAboutAnEditor(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_FETCH_GENERIC_INFORMATION_ABOUT_AN_EDITOR.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditorUsernameGetResponse::UsernameNotFound(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_USERNAME_NOT_FOUND.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + EditorUsernameGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "EditorUsernameGet"); + + let api_clone = api.clone(); + router.get( + "/v0/file/:id", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.file_id_get(param_id, context).wait() { + Ok(rsp) => match rsp { + FileIdGetResponse::FetchASingleFileById(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_ID_GET_FETCH_A_SINGLE_FILE_BY_ID.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + FileIdGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_ID_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + FileIdGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "FileIdGet"); + + let api_clone = api.clone(); + router.get( + "/v0/file/lookup", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = req.get::<UrlEncodedQuery>().unwrap_or_default(); + let param_sha1 = query_params.get("sha1") + .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter sha1".to_string())))? + .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter sha1 was empty".to_string())))? + .parse::<String>().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter sha1 - doesn't match schema: {}", e))))?; + + + match api.file_lookup_get(param_sha1, context).wait() { + Ok(rsp) => match rsp { + FileLookupGetResponse::FindASingleFileByExternalIdentifer(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_FIND_A_SINGLE_FILE_BY_EXTERNAL_IDENTIFER.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + FileLookupGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + FileLookupGetResponse::NoSuchFile(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_NO_SUCH_FILE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + FileLookupGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "FileLookupGet"); + + let api_clone = api.clone(); + router.post( + "/v0/file", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + + let param_body = req.get::<bodyparser::Raw>().unwrap_or(None); + + let mut unused_elements = Vec::new(); + + let param_body = if let Some(param_body_raw) = param_body { + let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); + + let param_body: Option<models::FileEntity> = serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }).unwrap_or(None); + + param_body + } else { + None + };; + + + match api.file_post(param_body, context).wait() { + Ok(rsp) => match rsp { + FilePostResponse::Created(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(201), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_POST_CREATED.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + FilePostResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_POST_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + FilePostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::FILE_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "FilePost"); + + let api_clone = api.clone(); + router.get( + "/v0/release/:id", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.release_id_get(param_id, context).wait() { + Ok(rsp) => match rsp { + ReleaseIdGetResponse::FetchASingleReleaseById(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_ID_GET_FETCH_A_SINGLE_RELEASE_BY_ID.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ReleaseIdGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_ID_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ReleaseIdGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "ReleaseIdGet"); + + let api_clone = api.clone(); + router.get( + "/v0/release/lookup", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = req.get::<UrlEncodedQuery>().unwrap_or_default(); + let param_doi = query_params.get("doi") + .ok_or_else(|| Response::with((status::BadRequest, "Missing required query parameter doi".to_string())))? + .first().ok_or_else(|| Response::with((status::BadRequest, "Required query parameter doi was empty".to_string())))? + .parse::<String>().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse query parameter doi - doesn't match schema: {}", e))))?; + + + match api.release_lookup_get(param_doi, context).wait() { + Ok(rsp) => match rsp { + ReleaseLookupGetResponse::FindASingleReleaseByExternalIdentifer(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_FIND_A_SINGLE_RELEASE_BY_EXTERNAL_IDENTIFER.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ReleaseLookupGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ReleaseLookupGetResponse::NoSuchRelease(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(404), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_NO_SUCH_RELEASE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + ReleaseLookupGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "ReleaseLookupGet"); + + let api_clone = api.clone(); + router.post( + "/v0/release", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + + let param_body = req.get::<bodyparser::Raw>().unwrap_or(None); + + let mut unused_elements = Vec::new(); + + let param_body = if let Some(param_body_raw) = param_body { + let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); + + let param_body: Option<models::ReleaseEntity> = serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }).unwrap_or(None); + + param_body + } else { + None + };; + + + match api.release_post(param_body, context).wait() { + Ok(rsp) => match rsp { + ReleasePostResponse::Created(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(201), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_POST_CREATED.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + ReleasePostResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_POST_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + ReleasePostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::RELEASE_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "ReleasePost"); + + let api_clone = api.clone(); + router.get( + "/v0/work/:id", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + // Path parameters + let param_id = { + let param = req.extensions.get::<Router>().ok_or_else(|| Response::with((status::InternalServerError, "An internal error occurred".to_string())))? + .find("id").ok_or_else(|| Response::with((status::BadRequest, "Missing path parameter id".to_string())))?; + percent_decode(param.as_bytes()).decode_utf8() + .map_err(|_| Response::with((status::BadRequest, format!("Couldn't percent-decode path parameter as UTF-8: {}", param))))? + .parse().map_err(|e| Response::with((status::BadRequest, format!("Couldn't parse path parameter id: {}", e))))? + }; + + + + match api.work_id_get(param_id, context).wait() { + Ok(rsp) => match rsp { + WorkIdGetResponse::FetchASingleWorkById(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(200), body_string)); + response.headers.set(ContentType(mimetypes::responses::WORK_ID_GET_FETCH_A_SINGLE_WORK_BY_ID.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + WorkIdGetResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::WORK_ID_GET_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + WorkIdGetResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::WORK_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "WorkIdGet"); + + let api_clone = api.clone(); + router.post( + "/v0/work", + move |req: &mut Request| { + let mut context = Context::default(); + + // Helper function to provide a code block to use `?` in (to be replaced by the `catch` block when it exists). + fn handle_request<T>(req: &mut Request, api: &T, context: &mut Context) -> Result<Response, Response> where T: Api { + + context.x_span_id = Some(req.headers.get::<XSpanId>().map(XSpanId::to_string).unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string())); + context.auth_data = req.extensions.remove::<AuthData>(); + context.authorization = req.extensions.remove::<Authorization>(); + + + + + // Body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + + let param_body = req.get::<bodyparser::Raw>().unwrap_or(None); + + let mut unused_elements = Vec::new(); + + let param_body = if let Some(param_body_raw) = param_body { + let deserializer = &mut serde_json::Deserializer::from_str(¶m_body_raw); + + let param_body: Option<models::WorkEntity> = serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {}", path); + unused_elements.push(path.to_string()); + }).unwrap_or(None); + + param_body + } else { + None + };; + + + match api.work_post(param_body, context).wait() { + Ok(rsp) => match rsp { + WorkPostResponse::Created(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(201), body_string)); + response.headers.set(ContentType(mimetypes::responses::WORK_POST_CREATED.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + WorkPostResponse::BadRequest(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(400), body_string)); + response.headers.set(ContentType(mimetypes::responses::WORK_POST_BAD_REQUEST.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + WorkPostResponse::GenericErrorResponse(body) => { + + let body_string = serde_json::to_string(&body).expect("impossible to fail to serialize"); + + let mut response = Response::with((status::Status::from_u16(0), body_string)); + response.headers.set(ContentType(mimetypes::responses::WORK_POST_GENERIC_ERROR_RESPONSE.clone())); + + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + if !unused_elements.is_empty() { + response.headers.set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements))); + } + Ok(response) + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + Err(Response::with((status::InternalServerError, "An internal error occurred".to_string()))) + } + } + } + + handle_request(req, &api_clone, &mut context).or_else(|mut response| { + context.x_span_id.as_ref().map(|header| response.headers.set(XSpanId(header.clone()))); + Ok(response) + }) + }, + "WorkPost"); + +} + +/// Middleware to extract authentication data from request +pub struct ExtractAuthData; + +impl BeforeMiddleware for ExtractAuthData { + fn before(&self, req: &mut Request) -> IronResult<()> { + + Ok(()) + } +} diff --git a/rust/fatcat-api/src/server/auth.rs b/rust/fatcat-api/src/server/auth.rs deleted file mode 100644 index 48dfd7d6..00000000 --- a/rust/fatcat-api/src/server/auth.rs +++ /dev/null @@ -1,93 +0,0 @@ -use Api; -use hyper; -use hyper::{Error, Request, Response, StatusCode}; -use server::url::form_urlencoded; -use std::io; -use swagger::auth::{AuthData, Authorization, Scopes}; - -pub struct NewService<T> -where - T: hyper::server::NewService< - Request = (Request, Option<AuthData>), - Response = Response, - Error = Error, - >, -{ - inner: T, -} - -impl<T> NewService<T> -where - T: hyper::server::NewService< - Request = (Request, Option<AuthData>), - Response = Response, - Error = Error, - > - + 'static, -{ - pub fn new(inner: T) -> NewService<T> { - NewService { inner } - } -} - -impl<T> hyper::server::NewService for NewService<T> -where - T: hyper::server::NewService< - Request = (Request, Option<AuthData>), - Response = Response, - Error = Error, - > - + 'static, -{ - type Request = Request; - type Response = Response; - type Error = Error; - type Instance = Service<T::Instance>; - - fn new_service(&self) -> Result<Self::Instance, io::Error> { - self.inner.new_service().map(|s| Service::new(s)) - } -} - -/// Middleware to extract authentication data from request -pub struct Service<T> -where - T: hyper::server::Service< - Request = (Request, Option<AuthData>), - Response = Response, - Error = Error, - >, -{ - inner: T, -} - -impl<T> Service<T> -where - T: hyper::server::Service< - Request = (Request, Option<AuthData>), - Response = Response, - Error = Error, - >, -{ - pub fn new(inner: T) -> Service<T> { - Service { inner } - } -} - -impl<T> hyper::server::Service for Service<T> -where - T: hyper::server::Service< - Request = (Request, Option<AuthData>), - Response = Response, - Error = Error, - >, -{ - type Request = Request; - type Response = Response; - type Error = Error; - type Future = T::Future; - - fn call(&self, req: Self::Request) -> Self::Future { - return self.inner.call((req, None)); - } -} diff --git a/rust/fatcat-api/src/server/mod.rs b/rust/fatcat-api/src/server/mod.rs deleted file mode 100644 index 186f8272..00000000 --- a/rust/fatcat-api/src/server/mod.rs +++ /dev/null @@ -1,2485 +0,0 @@ -#![allow(unused_extern_crates)] -extern crate chrono; -extern crate hyper_tls; -extern crate mime; -extern crate native_tls; -extern crate openssl; -extern crate serde_ignored; -extern crate tokio_core; -extern crate uuid; - -extern crate percent_encoding; -extern crate url; - -use self::url::form_urlencoded; -use futures::{future, stream, Future, Stream}; -use hyper; -use hyper::header::{ContentType, Headers}; -use hyper::{Error, Request, Response, StatusCode}; -use mimetypes; -use std::sync::Arc; - -use serde_json; - -#[allow(unused_imports)] -use std::collections::{BTreeMap, HashMap}; -use std::io; -#[allow(unused_imports)] -use swagger; - -#[allow(unused_imports)] -use std::collections::BTreeSet; - -pub use swagger::auth::Authorization; -use swagger::auth::Scopes; -use swagger::{ApiError, Context, XSpanId}; - -#[allow(unused_imports)] -use models; -use {Api, ContainerIdGetResponse, ContainerLookupGetResponse, ContainerPostResponse, - CreatorIdGetResponse, CreatorLookupGetResponse, CreatorPostResponse, - EditgroupIdAcceptPostResponse, EditgroupIdGetResponse, EditgroupPostResponse, - EditorUsernameChangelogGetResponse, EditorUsernameGetResponse, FileIdGetResponse, - FileLookupGetResponse, FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse, - ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; - -pub mod auth; - -header! { (Warning, "Warning") => [String] } - -mod paths { - extern crate regex; - - lazy_static! { - pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[ - r"^/v0/container$", - r"^/v0/container/lookup$", - r"^/v0/container/(?P<id>[^/?#]*)$", - r"^/v0/creator$", - r"^/v0/creator/lookup$", - r"^/v0/creator/(?P<id>[^/?#]*)$", - r"^/v0/editgroup$", - r"^/v0/editgroup/(?P<id>[^/?#]*)$", - r"^/v0/editgroup/(?P<id>[^/?#]*)/accept$", - r"^/v0/editor/(?P<username>[^/?#]*)$", - r"^/v0/editor/(?P<username>[^/?#]*)/changelog$", - r"^/v0/file$", - r"^/v0/file/lookup$", - r"^/v0/file/(?P<id>[^/?#]*)$", - r"^/v0/release$", - r"^/v0/release/lookup$", - r"^/v0/release/(?P<id>[^/?#]*)$", - r"^/v0/work$", - r"^/v0/work/(?P<id>[^/?#]*)$" - ]).unwrap(); - } - pub static ID_CONTAINER: usize = 0; - pub static ID_CONTAINER_LOOKUP: usize = 1; - pub static ID_CONTAINER_ID: usize = 2; - lazy_static! { - pub static ref REGEX_CONTAINER_ID: regex::Regex = - regex::Regex::new(r"^/v0/container/(?P<id>[^/?#]*)$").unwrap(); - } - pub static ID_CREATOR: usize = 3; - pub static ID_CREATOR_LOOKUP: usize = 4; - pub static ID_CREATOR_ID: usize = 5; - lazy_static! { - pub static ref REGEX_CREATOR_ID: regex::Regex = - regex::Regex::new(r"^/v0/creator/(?P<id>[^/?#]*)$").unwrap(); - } - pub static ID_EDITGROUP: usize = 6; - pub static ID_EDITGROUP_ID: usize = 7; - lazy_static! { - pub static ref REGEX_EDITGROUP_ID: regex::Regex = - regex::Regex::new(r"^/v0/editgroup/(?P<id>[^/?#]*)$").unwrap(); - } - pub static ID_EDITGROUP_ID_ACCEPT: usize = 8; - lazy_static! { - pub static ref REGEX_EDITGROUP_ID_ACCEPT: regex::Regex = - regex::Regex::new(r"^/v0/editgroup/(?P<id>[^/?#]*)/accept$").unwrap(); - } - pub static ID_EDITOR_USERNAME: usize = 9; - lazy_static! { - pub static ref REGEX_EDITOR_USERNAME: regex::Regex = - regex::Regex::new(r"^/v0/editor/(?P<username>[^/?#]*)$").unwrap(); - } - pub static ID_EDITOR_USERNAME_CHANGELOG: usize = 10; - lazy_static! { - pub static ref REGEX_EDITOR_USERNAME_CHANGELOG: regex::Regex = - regex::Regex::new(r"^/v0/editor/(?P<username>[^/?#]*)/changelog$").unwrap(); - } - pub static ID_FILE: usize = 11; - pub static ID_FILE_LOOKUP: usize = 12; - pub static ID_FILE_ID: usize = 13; - lazy_static! { - pub static ref REGEX_FILE_ID: regex::Regex = - regex::Regex::new(r"^/v0/file/(?P<id>[^/?#]*)$").unwrap(); - } - pub static ID_RELEASE: usize = 14; - pub static ID_RELEASE_LOOKUP: usize = 15; - pub static ID_RELEASE_ID: usize = 16; - lazy_static! { - pub static ref REGEX_RELEASE_ID: regex::Regex = - regex::Regex::new(r"^/v0/release/(?P<id>[^/?#]*)$").unwrap(); - } - pub static ID_WORK: usize = 17; - pub static ID_WORK_ID: usize = 18; - lazy_static! { - pub static ref REGEX_WORK_ID: regex::Regex = - regex::Regex::new(r"^/v0/work/(?P<id>[^/?#]*)$").unwrap(); - } -} - -pub struct NewService<T> { - api_impl: Arc<T>, -} - -impl<T> NewService<T> -where - T: Api + Clone + 'static, -{ - pub fn new<U: Into<Arc<T>>>(api_impl: U) -> NewService<T> { - NewService { - api_impl: api_impl.into(), - } - } -} - -impl<T> hyper::server::NewService for NewService<T> -where - T: Api + Clone + 'static, -{ - type Request = (Request, Context); - type Response = Response; - type Error = Error; - type Instance = Service<T>; - - fn new_service(&self) -> Result<Self::Instance, io::Error> { - Ok(Service::new(self.api_impl.clone())) - } -} - -pub struct Service<T> { - api_impl: Arc<T>, -} - -impl<T> Service<T> -where - T: Api + Clone + 'static, -{ - pub fn new<U: Into<Arc<T>>>(api_impl: U) -> Service<T> { - Service { - api_impl: api_impl.into(), - } - } -} - -impl<T> hyper::server::Service for Service<T> -where - T: Api + Clone + 'static, -{ - type Request = (Request, Context); - type Response = Response; - type Error = Error; - type Future = Box<Future<Item = Response, Error = Error>>; - - fn call(&self, (req, mut context): Self::Request) -> Self::Future { - let api_impl = self.api_impl.clone(); - let (method, uri, _, headers, body) = req.deconstruct(); - let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); - match &method { - // ContainerIdGet - GET /container/{id} - &hyper::Method::Get if path.matched(paths::ID_CONTAINER_ID) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_CONTAINER_ID - .captures(&path) - .unwrap_or_else(|| { - panic!("Path {} matched RE CONTAINER_ID in set but failed match against \"{}\"", path, paths::REGEX_CONTAINER_ID.as_str()) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<String>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.container_id_get(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - ContainerIdGetResponse::FetchASingleContainerById - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_ID_GET_FETCH_A_SINGLE_CONTAINER_BY_ID.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ContainerIdGetResponse::BadRequest - - (body) - - - => { - response.set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_ID_GET_BAD_REQUEST.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ContainerIdGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_ID_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // ContainerLookupGet - GET /container/lookup - &hyper::Method::Get if path.matched(paths::ID_CONTAINER_LOOKUP) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = form_urlencoded::parse( - uri.query().unwrap_or_default().as_bytes(), - ).collect::<Vec<_>>(); - let param_issn = query_params - .iter() - .filter(|e| e.0 == "issn") - .map(|e| e.1.to_owned()) - .nth(0); - let param_issn = match param_issn { - Some(param_issn) => match param_issn.parse::<String>() { - Ok(param_issn) => param_issn, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't parse query parameter issn - doesn't match schema: {}", - e - )), - )) - } - }, - None => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body("Missing required query parameter issn"), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.container_lookup_get(param_issn, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - ContainerLookupGetResponse::FindASingleContainerByExternalIdentifer - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_FIND_A_SINGLE_CONTAINER_BY_EXTERNAL_IDENTIFER.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ContainerLookupGetResponse::BadRequest - - (body) - - - => { - response.set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_BAD_REQUEST.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ContainerLookupGetResponse::NoSuchContainer - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_NO_SUCH_CONTAINER.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ContainerLookupGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // ContainerPost - POST /container - &hyper::Method::Post if path.matched(paths::ID_CONTAINER) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - Box::new(body.concat2().then( - move |result| -> Box<Future<Item = Response, Error = Error>> { - match result { - Ok(body) => { - let mut unused_elements = Vec::new(); - let param_body: Option< - models::ContainerEntity, - > = if !body.is_empty() { - let deserializer = - &mut serde_json::Deserializer::from_slice(&*body); - - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - - Err(_) => None, - } - } else { - None - }; - - Box::new(api_impl.container_post(param_body, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - if !unused_elements.is_empty() { - response.headers_mut().set(Warning(format!( - "Ignoring unknown fields in body: {:?}", - unused_elements - ))); - } - - match result { - Ok(rsp) => match rsp { - ContainerPostResponse::Created(body) => { - response.set_status( - StatusCode::try_from(201).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_POST_CREATED.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - ContainerPostResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_POST_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - ContainerPostResponse::GenericErrorResponse( - body, - ) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_POST_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - Err(e) => Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't read body parameter body: {}", e)), - )), - } - }, - )) as Box<Future<Item = Response, Error = Error>> - } - - // CreatorIdGet - GET /creator/{id} - &hyper::Method::Get if path.matched(paths::ID_CREATOR_ID) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_CREATOR_ID.captures(&path).unwrap_or_else(|| { - panic!( - "Path {} matched RE CREATOR_ID in set but failed match against \"{}\"", - path, - paths::REGEX_CREATOR_ID.as_str() - ) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<String>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.creator_id_get(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - CreatorIdGetResponse::FetchASingleCreatorById( - body, - ) => { - response.set_status( - StatusCode::try_from(200).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_ID_GET_FETCH_A_SINGLE_CREATOR_BY_ID.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - CreatorIdGetResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_ID_GET_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - CreatorIdGetResponse::GenericErrorResponse( - body, - ) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_ID_GET_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // CreatorLookupGet - GET /creator/lookup - &hyper::Method::Get if path.matched(paths::ID_CREATOR_LOOKUP) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = form_urlencoded::parse( - uri.query().unwrap_or_default().as_bytes(), - ).collect::<Vec<_>>(); - let param_orcid = query_params - .iter() - .filter(|e| e.0 == "orcid") - .map(|e| e.1.to_owned()) - .nth(0); - let param_orcid = match param_orcid { - Some(param_orcid) => match param_orcid.parse::<String>() { - Ok(param_orcid) => param_orcid, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't parse query parameter orcid - doesn't match schema: {}", - e - )), - )) - } - }, - None => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body("Missing required query parameter orcid"), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.creator_lookup_get(param_orcid, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - CreatorLookupGetResponse::FindASingleCreatorByExternalIdentifer - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_FIND_A_SINGLE_CREATOR_BY_EXTERNAL_IDENTIFER.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - CreatorLookupGetResponse::BadRequest - - (body) - - - => { - response.set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_BAD_REQUEST.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - CreatorLookupGetResponse::NoSuchCreator - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_NO_SUCH_CREATOR.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - CreatorLookupGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // CreatorPost - POST /creator - &hyper::Method::Post if path.matched(paths::ID_CREATOR) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - Box::new(body.concat2().then( - move |result| -> Box<Future<Item = Response, Error = Error>> { - match result { - Ok(body) => { - let mut unused_elements = Vec::new(); - let param_body: Option< - models::CreatorEntity, - > = if !body.is_empty() { - let deserializer = - &mut serde_json::Deserializer::from_slice(&*body); - - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - - Err(_) => None, - } - } else { - None - }; - - Box::new(api_impl.creator_post(param_body, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - if !unused_elements.is_empty() { - response.headers_mut().set(Warning(format!( - "Ignoring unknown fields in body: {:?}", - unused_elements - ))); - } - - match result { - Ok(rsp) => match rsp { - CreatorPostResponse::Created(body) => { - response.set_status( - StatusCode::try_from(201).unwrap(), - ); - - response.headers_mut().set(ContentType( - mimetypes::responses::CREATOR_POST_CREATED - .clone(), - )); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - CreatorPostResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_POST_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - CreatorPostResponse::GenericErrorResponse(body) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_POST_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - Err(e) => Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't read body parameter body: {}", e)), - )), - } - }, - )) as Box<Future<Item = Response, Error = Error>> - } - - // EditgroupIdAcceptPost - POST /editgroup/{id}/accept - &hyper::Method::Post if path.matched(paths::ID_EDITGROUP_ID_ACCEPT) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_EDITGROUP_ID_ACCEPT - .captures(&path) - .unwrap_or_else(|| { - panic!("Path {} matched RE EDITGROUP_ID_ACCEPT in set but failed match against \"{}\"", path, paths::REGEX_EDITGROUP_ID_ACCEPT.as_str()) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<i32>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new( - api_impl.editgroup_id_accept_post(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - EditgroupIdAcceptPostResponse::MergedEditgroupSuccessfully_ - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_MERGED_EDITGROUP_SUCCESSFULLY_.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditgroupIdAcceptPostResponse::EditgroupIsInAnUnmergableState - - (body) - - - => { - response.set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_EDITGROUP_IS_IN_AN_UNMERGABLE_STATE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditgroupIdAcceptPostResponse::NoSuchEditgroup - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_NO_SUCH_EDITGROUP.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditgroupIdAcceptPostResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - ), - ) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // EditgroupIdGet - GET /editgroup/{id} - &hyper::Method::Get if path.matched(paths::ID_EDITGROUP_ID) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_EDITGROUP_ID - .captures(&path) - .unwrap_or_else(|| { - panic!("Path {} matched RE EDITGROUP_ID in set but failed match against \"{}\"", path, paths::REGEX_EDITGROUP_ID.as_str()) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<i32>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.editgroup_id_get(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - EditgroupIdGetResponse::FetchEditgroupByIdentifier - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_FETCH_EDITGROUP_BY_IDENTIFIER.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditgroupIdGetResponse::NoSuchEditgroup - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_NO_SUCH_EDITGROUP.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditgroupIdGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // EditgroupPost - POST /editgroup - &hyper::Method::Post if path.matched(paths::ID_EDITGROUP) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - Box::new( - ({ - { - { - Box::new(api_impl.editgroup_post(&context).then(move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - EditgroupPostResponse::SuccessfullyCreated(body) => { - response - .set_status(StatusCode::try_from(201).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_POST_SUCCESSFULLY_CREATED.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - EditgroupPostResponse::InvalidRequestParameters( - body, - ) => { - response - .set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_POST_INVALID_REQUEST_PARAMETERS.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - EditgroupPostResponse::GenericErrorResponse(body) => { - response - .set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_POST_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - })) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // EditorUsernameChangelogGet - GET /editor/{username}/changelog - &hyper::Method::Get if path.matched(paths::ID_EDITOR_USERNAME_CHANGELOG) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_EDITOR_USERNAME_CHANGELOG - .captures(&path) - .unwrap_or_else(|| { - panic!("Path {} matched RE EDITOR_USERNAME_CHANGELOG in set but failed match against \"{}\"", path, paths::REGEX_EDITOR_USERNAME_CHANGELOG.as_str()) - }); - - let param_username = match percent_encoding::percent_decode( - path_params["username"].as_bytes(), - ).decode_utf8() - { - Ok(param_username) => match param_username.parse::<String>() { - Ok(param_username) => param_username, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't parse path parameter username: {}", - e - )), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["username"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new( - api_impl - .editor_username_changelog_get(param_username, &context) - .then(move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - EditorUsernameChangelogGetResponse::FindChanges_ - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_FIND_CHANGES_.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditorUsernameChangelogGetResponse::UsernameNotFound - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_USERNAME_NOT_FOUND.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditorUsernameChangelogGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }), - ) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // EditorUsernameGet - GET /editor/{username} - &hyper::Method::Get if path.matched(paths::ID_EDITOR_USERNAME) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_EDITOR_USERNAME.captures(&path).unwrap_or_else( - || { - panic!("Path {} matched RE EDITOR_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_EDITOR_USERNAME.as_str()) - }, - ); - - let param_username = match percent_encoding::percent_decode( - path_params["username"].as_bytes(), - ).decode_utf8() - { - Ok(param_username) => match param_username.parse::<String>() { - Ok(param_username) => param_username, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't parse path parameter username: {}", - e - )), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["username"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new( - api_impl.editor_username_get(param_username, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - EditorUsernameGetResponse::FetchGenericInformationAboutAnEditor - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_FETCH_GENERIC_INFORMATION_ABOUT_AN_EDITOR.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditorUsernameGetResponse::UsernameNotFound - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_USERNAME_NOT_FOUND.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - EditorUsernameGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - ), - ) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // FileIdGet - GET /file/{id} - &hyper::Method::Get if path.matched(paths::ID_FILE_ID) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_FILE_ID.captures(&path).unwrap_or_else(|| { - panic!( - "Path {} matched RE FILE_ID in set but failed match against \"{}\"", - path, - paths::REGEX_FILE_ID.as_str() - ) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<String>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.file_id_get(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - FileIdGetResponse::FetchASingleFileById(body) => { - response.set_status( - StatusCode::try_from(200).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_ID_GET_FETCH_A_SINGLE_FILE_BY_ID.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - FileIdGetResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_ID_GET_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - FileIdGetResponse::GenericErrorResponse(body) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_ID_GET_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // FileLookupGet - GET /file/lookup - &hyper::Method::Get if path.matched(paths::ID_FILE_LOOKUP) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = form_urlencoded::parse( - uri.query().unwrap_or_default().as_bytes(), - ).collect::<Vec<_>>(); - let param_sha1 = query_params - .iter() - .filter(|e| e.0 == "sha1") - .map(|e| e.1.to_owned()) - .nth(0); - let param_sha1 = match param_sha1 { - Some(param_sha1) => match param_sha1.parse::<String>() { - Ok(param_sha1) => param_sha1, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't parse query parameter sha1 - doesn't match schema: {}", - e - )), - )) - } - }, - None => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body("Missing required query parameter sha1"), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.file_lookup_get(param_sha1, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - FileLookupGetResponse::FindASingleFileByExternalIdentifer - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_FIND_A_SINGLE_FILE_BY_EXTERNAL_IDENTIFER.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - FileLookupGetResponse::BadRequest - - (body) - - - => { - response.set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_BAD_REQUEST.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - FileLookupGetResponse::NoSuchFile - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_NO_SUCH_FILE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - FileLookupGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // FilePost - POST /file - &hyper::Method::Post if path.matched(paths::ID_FILE) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - Box::new(body.concat2().then( - move |result| -> Box<Future<Item = Response, Error = Error>> { - match result { - Ok(body) => { - let mut unused_elements = Vec::new(); - let param_body: Option< - models::FileEntity, - > = if !body.is_empty() { - let deserializer = - &mut serde_json::Deserializer::from_slice(&*body); - - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - - Err(_) => None, - } - } else { - None - }; - - Box::new(api_impl.file_post(param_body, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - if !unused_elements.is_empty() { - response.headers_mut().set(Warning(format!( - "Ignoring unknown fields in body: {:?}", - unused_elements - ))); - } - - match result { - Ok(rsp) => match rsp { - FilePostResponse::Created(body) => { - response.set_status( - StatusCode::try_from(201).unwrap(), - ); - - response.headers_mut().set(ContentType( - mimetypes::responses::FILE_POST_CREATED - .clone(), - )); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - FilePostResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType( - mimetypes::responses::FILE_POST_BAD_REQUEST - .clone(), - )); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - FilePostResponse::GenericErrorResponse(body) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::FILE_POST_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - Err(e) => Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't read body parameter body: {}", e)), - )), - } - }, - )) as Box<Future<Item = Response, Error = Error>> - } - - // ReleaseIdGet - GET /release/{id} - &hyper::Method::Get if path.matched(paths::ID_RELEASE_ID) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_RELEASE_ID.captures(&path).unwrap_or_else(|| { - panic!( - "Path {} matched RE RELEASE_ID in set but failed match against \"{}\"", - path, - paths::REGEX_RELEASE_ID.as_str() - ) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<String>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.release_id_get(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - ReleaseIdGetResponse::FetchASingleReleaseById( - body, - ) => { - response.set_status( - StatusCode::try_from(200).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_ID_GET_FETCH_A_SINGLE_RELEASE_BY_ID.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - ReleaseIdGetResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_ID_GET_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - ReleaseIdGetResponse::GenericErrorResponse( - body, - ) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_ID_GET_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // ReleaseLookupGet - GET /release/lookup - &hyper::Method::Get if path.matched(paths::ID_RELEASE_LOOKUP) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) - let query_params = form_urlencoded::parse( - uri.query().unwrap_or_default().as_bytes(), - ).collect::<Vec<_>>(); - let param_doi = query_params - .iter() - .filter(|e| e.0 == "doi") - .map(|e| e.1.to_owned()) - .nth(0); - let param_doi = match param_doi { - Some(param_doi) => match param_doi.parse::<String>() { - Ok(param_doi) => param_doi, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't parse query parameter doi - doesn't match schema: {}", - e - )), - )) - } - }, - None => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body("Missing required query parameter doi"), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.release_lookup_get(param_doi, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - ReleaseLookupGetResponse::FindASingleReleaseByExternalIdentifer - - (body) - - - => { - response.set_status(StatusCode::try_from(200).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_FIND_A_SINGLE_RELEASE_BY_EXTERNAL_IDENTIFER.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ReleaseLookupGetResponse::BadRequest - - (body) - - - => { - response.set_status(StatusCode::try_from(400).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_BAD_REQUEST.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ReleaseLookupGetResponse::NoSuchRelease - - (body) - - - => { - response.set_status(StatusCode::try_from(404).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_NO_SUCH_RELEASE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - ReleaseLookupGetResponse::GenericErrorResponse - - (body) - - - => { - response.set_status(StatusCode::try_from(0).unwrap()); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); - - - let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - - response.set_body(body); - }, - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response.set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - }, - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // ReleasePost - POST /release - &hyper::Method::Post if path.matched(paths::ID_RELEASE) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - Box::new(body.concat2().then( - move |result| -> Box<Future<Item = Response, Error = Error>> { - match result { - Ok(body) => { - let mut unused_elements = Vec::new(); - let param_body: Option< - models::ReleaseEntity, - > = if !body.is_empty() { - let deserializer = - &mut serde_json::Deserializer::from_slice(&*body); - - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - - Err(_) => None, - } - } else { - None - }; - - Box::new(api_impl.release_post(param_body, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - if !unused_elements.is_empty() { - response.headers_mut().set(Warning(format!( - "Ignoring unknown fields in body: {:?}", - unused_elements - ))); - } - - match result { - Ok(rsp) => match rsp { - ReleasePostResponse::Created(body) => { - response.set_status( - StatusCode::try_from(201).unwrap(), - ); - - response.headers_mut().set(ContentType( - mimetypes::responses::RELEASE_POST_CREATED - .clone(), - )); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - ReleasePostResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_POST_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - ReleasePostResponse::GenericErrorResponse(body) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_POST_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - Err(e) => Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't read body parameter body: {}", e)), - )), - } - }, - )) as Box<Future<Item = Response, Error = Error>> - } - - // WorkIdGet - GET /work/{id} - &hyper::Method::Get if path.matched(paths::ID_WORK_ID) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Path parameters - let path = uri.path().to_string(); - let path_params = paths::REGEX_WORK_ID.captures(&path).unwrap_or_else(|| { - panic!( - "Path {} matched RE WORK_ID in set but failed match against \"{}\"", - path, - paths::REGEX_WORK_ID.as_str() - ) - }); - - let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) - .decode_utf8() - { - Ok(param_id) => match param_id.parse::<String>() { - Ok(param_id) => param_id, - Err(e) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't parse path parameter id: {}", e)), - )) - } - }, - Err(_) => { - return Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!( - "Couldn't percent-decode path parameter as UTF-8: {}", - &path_params["id"] - )), - )) - } - }; - - Box::new( - ({ - { - { - Box::new(api_impl.work_id_get(param_id, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - match result { - Ok(rsp) => match rsp { - WorkIdGetResponse::FetchASingleWorkById(body) => { - response.set_status( - StatusCode::try_from(200).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::WORK_ID_GET_FETCH_A_SINGLE_WORK_BY_ID.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - WorkIdGetResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::WORK_ID_GET_BAD_REQUEST.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - WorkIdGetResponse::GenericErrorResponse(body) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::WORK_ID_GET_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - } - }), - ) as Box<Future<Item = Response, Error = Error>> - } - - // WorkPost - POST /work - &hyper::Method::Post if path.matched(paths::ID_WORK) => { - if context.x_span_id.is_none() { - context.x_span_id = Some( - headers - .get::<XSpanId>() - .map(XSpanId::to_string) - .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), - ); - } - - // Body parameters (note that non-required body parameters will ignore garbage - // values, rather than causing a 400 response). Produce warning header and logs for - // any unused fields. - Box::new(body.concat2().then( - move |result| -> Box<Future<Item = Response, Error = Error>> { - match result { - Ok(body) => { - let mut unused_elements = Vec::new(); - let param_body: Option< - models::WorkEntity, - > = if !body.is_empty() { - let deserializer = - &mut serde_json::Deserializer::from_slice(&*body); - - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - - Err(_) => None, - } - } else { - None - }; - - Box::new(api_impl.work_post(param_body, &context).then( - move |result| { - let mut response = Response::new(); - context.x_span_id.as_ref().map(|header| { - response.headers_mut().set(XSpanId(header.clone())) - }); - - if !unused_elements.is_empty() { - response.headers_mut().set(Warning(format!( - "Ignoring unknown fields in body: {:?}", - unused_elements - ))); - } - - match result { - Ok(rsp) => match rsp { - WorkPostResponse::Created(body) => { - response.set_status( - StatusCode::try_from(201).unwrap(), - ); - - response.headers_mut().set(ContentType( - mimetypes::responses::WORK_POST_CREATED - .clone(), - )); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - WorkPostResponse::BadRequest(body) => { - response.set_status( - StatusCode::try_from(400).unwrap(), - ); - - response.headers_mut().set(ContentType( - mimetypes::responses::WORK_POST_BAD_REQUEST - .clone(), - )); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - WorkPostResponse::GenericErrorResponse(body) => { - response.set_status( - StatusCode::try_from(0).unwrap(), - ); - - response.headers_mut().set(ContentType(mimetypes::responses::WORK_POST_GENERIC_ERROR_RESPONSE.clone())); - - let body = serde_json::to_string(&body) - .expect("impossible to fail to serialize"); - - response.set_body(body); - } - }, - Err(_) => { - // Application code returned an error. This should not happen, as the implementation should - // return a valid response. - response - .set_status(StatusCode::InternalServerError); - response.set_body("An internal error occurred"); - } - } - - future::ok(response) - }, - )) - } - Err(e) => Box::new(future::ok( - Response::new() - .with_status(StatusCode::BadRequest) - .with_body(format!("Couldn't read body parameter body: {}", e)), - )), - } - }, - )) as Box<Future<Item = Response, Error = Error>> - } - - _ => Box::new(future::ok( - Response::new().with_status(StatusCode::NotFound), - )) as Box<Future<Item = Response, Error = Error>>, - } - } -} diff --git a/rust/src/api_lib.rs b/rust/src/api_lib.rs deleted file mode 100644 index cc8c2313..00000000 --- a/rust/src/api_lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Main library entry point for fatcat implementation. - -// Imports required by server library. -// extern crate fatcat; -// extern crate swagger; -extern crate futures; -extern crate chrono; -#[macro_use] -extern crate error_chain; - -mod server; - -mod errors { - error_chain!{} -} - -pub use self::errors::*; -use std::io; -use hyper; -use fatcat; - -pub struct NewService; - -impl hyper::server::NewService for NewService { - type Request = (hyper::Request, fatcat::Context); - type Response = hyper::Response; - type Error = hyper::Error; - type Instance = fatcat::server::Service<server::Server>; - - /// Instantiate a new server. - fn new_service(&self) -> io::Result<Self::Instance> { - Ok(fatcat::server::Service::new(server::Server)) - } -} diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index 16701b27..fa3b3958 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -2,287 +2,172 @@ #![allow(unused_imports)] -use chrono; use futures::{self, Future}; +use chrono; use std::collections::HashMap; use swagger; +use fatcat_api::{Api, ApiError, Context, + ContainerIdGetResponse, + ContainerLookupGetResponse, + ContainerPostResponse, + CreatorIdGetResponse, + CreatorLookupGetResponse, + CreatorPostResponse, + EditgroupIdAcceptPostResponse, + EditgroupIdGetResponse, + EditgroupPostResponse, + EditorUsernameChangelogGetResponse, + EditorUsernameGetResponse, + FileIdGetResponse, + FileLookupGetResponse, + FilePostResponse, + ReleaseIdGetResponse, + ReleaseLookupGetResponse, + ReleasePostResponse, + WorkIdGetResponse, + WorkPostResponse +}; use fatcat_api::models; -use fatcat_api::{Api, ApiError, ContainerIdGetResponse, ContainerLookupGetResponse, - ContainerPostResponse, Context, CreatorIdGetResponse, CreatorLookupGetResponse, - CreatorPostResponse, EditgroupIdAcceptPostResponse, EditgroupIdGetResponse, - EditgroupPostResponse, EditorUsernameChangelogGetResponse, - EditorUsernameGetResponse, FileIdGetResponse, FileLookupGetResponse, - FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse, - ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; #[derive(Copy, Clone)] pub struct Server; impl Api for Server { - fn container_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> { + + + fn container_id_get(&self, id: String, context: &Context) -> Box<Future<Item=ContainerIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "container_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("container_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn container_lookup_get( - &self, - issn: String, - context: &Context, - ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> { + + fn container_lookup_get(&self, issn: String, context: &Context) -> Box<Future<Item=ContainerLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "container_lookup_get(\"{}\") - X-Span-ID: {:?}", - issn, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("container_lookup_get(\"{}\") - X-Span-ID: {:?}", issn, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn container_post( - &self, - body: Option<models::ContainerEntity>, - context: &Context, - ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> { + + fn container_post(&self, body: Option<models::ContainerEntity>, context: &Context) -> Box<Future<Item=ContainerPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "container_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("container_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn creator_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> { + + fn creator_id_get(&self, id: String, context: &Context) -> Box<Future<Item=CreatorIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "creator_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("creator_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn creator_lookup_get( - &self, - orcid: String, - context: &Context, - ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> { + + fn creator_lookup_get(&self, orcid: String, context: &Context) -> Box<Future<Item=CreatorLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "creator_lookup_get(\"{}\") - X-Span-ID: {:?}", - orcid, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("creator_lookup_get(\"{}\") - X-Span-ID: {:?}", orcid, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn creator_post( - &self, - body: Option<models::CreatorEntity>, - context: &Context, - ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> { + + fn creator_post(&self, body: Option<models::CreatorEntity>, context: &Context) -> Box<Future<Item=CreatorPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "creator_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("creator_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editgroup_id_accept_post( - &self, - id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> { + + fn editgroup_id_accept_post(&self, id: i32, context: &Context) -> Box<Future<Item=EditgroupIdAcceptPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editgroup_id_accept_post({}) - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editgroup_id_accept_post({}) - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editgroup_id_get( - &self, - id: i32, - context: &Context, - ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> { + + fn editgroup_id_get(&self, id: i32, context: &Context) -> Box<Future<Item=EditgroupIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editgroup_id_get({}) - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editgroup_id_get({}) - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editgroup_post( - &self, - context: &Context, - ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> { + + fn editgroup_post(&self, context: &Context) -> Box<Future<Item=EditgroupPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editgroup_post() - X-Span-ID: {:?}", - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editgroup_post() - X-Span-ID: {:?}", context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editor_username_changelog_get( - &self, - username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> { + + fn editor_username_changelog_get(&self, username: String, context: &Context) -> Box<Future<Item=EditorUsernameChangelogGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editor_username_changelog_get(\"{}\") - X-Span-ID: {:?}", - username, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editor_username_changelog_get(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn editor_username_get( - &self, - username: String, - context: &Context, - ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> { + + fn editor_username_get(&self, username: String, context: &Context) -> Box<Future<Item=EditorUsernameGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "editor_username_get(\"{}\") - X-Span-ID: {:?}", - username, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("editor_username_get(\"{}\") - X-Span-ID: {:?}", username, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn file_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> { + + fn file_id_get(&self, id: String, context: &Context) -> Box<Future<Item=FileIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "file_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("file_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn file_lookup_get( - &self, - sha1: String, - context: &Context, - ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> { + + fn file_lookup_get(&self, sha1: String, context: &Context) -> Box<Future<Item=FileLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "file_lookup_get(\"{}\") - X-Span-ID: {:?}", - sha1, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("file_lookup_get(\"{}\") - X-Span-ID: {:?}", sha1, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn file_post( - &self, - body: Option<models::FileEntity>, - context: &Context, - ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> { + + fn file_post(&self, body: Option<models::FileEntity>, context: &Context) -> Box<Future<Item=FilePostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "file_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("file_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn release_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> { + + fn release_id_get(&self, id: String, context: &Context) -> Box<Future<Item=ReleaseIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "release_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("release_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn release_lookup_get( - &self, - doi: String, - context: &Context, - ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> { + + fn release_lookup_get(&self, doi: String, context: &Context) -> Box<Future<Item=ReleaseLookupGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "release_lookup_get(\"{}\") - X-Span-ID: {:?}", - doi, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("release_lookup_get(\"{}\") - X-Span-ID: {:?}", doi, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn release_post( - &self, - body: Option<models::ReleaseEntity>, - context: &Context, - ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> { + + fn release_post(&self, body: Option<models::ReleaseEntity>, context: &Context) -> Box<Future<Item=ReleasePostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "release_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("release_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn work_id_get( - &self, - id: String, - context: &Context, - ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> { + + fn work_id_get(&self, id: String, context: &Context) -> Box<Future<Item=WorkIdGetResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "work_id_get(\"{}\") - X-Span-ID: {:?}", - id, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("work_id_get(\"{}\") - X-Span-ID: {:?}", id, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } - fn work_post( - &self, - body: Option<models::WorkEntity>, - context: &Context, - ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> { + + fn work_post(&self, body: Option<models::WorkEntity>, context: &Context) -> Box<Future<Item=WorkPostResponse, Error=ApiError> + Send> { let context = context.clone(); - println!( - "work_post({:?}) - X-Span-ID: {:?}", - body, - context.x_span_id.unwrap_or(String::from("<none>")).clone() - ); + println!("work_post({:?}) - X-Span-ID: {:?}", body, context.x_span_id.unwrap_or(String::from("<none>")).clone()); Box::new(futures::failed("Generic failure".into())) } + } diff --git a/rust/src/bin/fatcat-iron.rs b/rust/src/bin/fatcat-iron.rs new file mode 100644 index 00000000..8c87f55f --- /dev/null +++ b/rust/src/bin/fatcat-iron.rs @@ -0,0 +1,69 @@ +//! Main binary entry point for fatcat implementation. + +#![allow(missing_docs)] + +// Imports required by this file. +extern crate fatcat; +extern crate fatcat_api; +extern crate swagger; +extern crate iron; +//extern crate hyper_openssl; +extern crate clap; + +// Imports required by server library. +// extern crate fatcat; +// extern crate swagger; +extern crate futures; +extern crate chrono; +#[macro_use] +extern crate error_chain; + +//use hyper_openssl::OpensslServer; +//use hyper_openssl::openssl::x509::X509_FILETYPE_PEM; +//use hyper_openssl::openssl::ssl::{SslAcceptorBuilder, SslMethod}; +//use hyper_openssl::openssl::error::ErrorStack; +use clap::{App, Arg}; +use iron::{Iron, Chain}; +use swagger::auth::AllowAllMiddleware; + +/* +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +fn ssl() -> Result<OpensslServer, ErrorStack> { + let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?; + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?; + ssl.set_certificate_chain_file("examples/server-chain.pem")?; + ssl.check_private_key()?; + + Ok(OpensslServer::from(ssl.build())) +} +*/ + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +fn main() { + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let server = fatcat::server().unwrap(); + let router = fatcat_api::router(server); + + let mut chain = Chain::new(router); + chain.link_before(fatcat_api::server::ExtractAuthData); + // add authentication middlewares into the chain here + // for the purpose of this example, pretend we have authenticated a user + chain.link_before(AllowAllMiddleware::new("cosmo")); + + if matches.is_present("https") { + unimplemented!() + // Using Simple HTTPS + //Iron::new(chain).https("localhost:8080", ssl().expect("Failed to load SSL keys")).expect("Failed to start HTTPS server"); + } else { + // Using HTTP + Iron::new(chain).http("localhost:8080").expect("Failed to start HTTP server"); + } +} diff --git a/rust/src/bin/fatcat-tokio.rs b/rust/src/bin/fatcat-tokio.rs deleted file mode 100644 index cc603908..00000000 --- a/rust/src/bin/fatcat-tokio.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! Main binary entry point for fatcat implementation. - -#![allow(missing_docs)] - -// Imports required by this file. -extern crate fatcat; -extern crate fatcat_api; -extern crate hyper; -extern crate swagger; -//extern crate openssl; -//extern crate native_tls; -extern crate tokio_proto; -//extern crate tokio_tls; -extern crate clap; - -//use openssl::x509::X509_FILETYPE_PEM; -//use openssl::ssl::{SslAcceptorBuilder, SslMethod}; -//use openssl::error::ErrorStack; -use clap::{App, Arg}; -use hyper::server::Http; -use swagger::auth::AllowAllAuthenticator; -use tokio_proto::TcpServer; - -// Builds an SSL implementation for Simple HTTPS from some hard-coded file names -/* -fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> { - let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?; - - // Server authentication - ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?; - ssl.set_certificate_chain_file("examples/server-chain.pem")?; - ssl.check_private_key()?; - - Ok(ssl) -} -*/ - -/// Create custom server, wire it to the autogenerated router, -/// and pass it to the web server. -fn main() { - let matches = App::new("server") - .arg( - Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not"), - ) - .get_matches(); - - let service_fn = fatcat_api::server::auth::NewService::new(AllowAllAuthenticator::new( - fatcat::NewService, - "cosmo", - )); - - let addr = "127.0.0.1:8080" - .parse() - .expect("Failed to parse bind address"); - if matches.is_present("https") { - unimplemented!() - //let ssl = ssl().expect("Failed to load SSL keys"); - //let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl); - //let tls_acceptor = builder.build().expect("Failed to build TLS acceptor"); - //TcpServer::new(tokio_tls::proto::Server::new(Http::new(), tls_acceptor), addr).serve(service_fn); - } else { - // Using HTTP - TcpServer::new(Http::new(), addr).serve(service_fn); - } -} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index ec7193e6..fbff6ab2 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -20,9 +20,6 @@ use diesel::pg::PgConnection; use diesel::prelude::*; use dotenv::dotenv; use std::env; -use std::io; -//use hyper; -//use fatcat_api; pub fn establish_connection() -> PgConnection { dotenv().ok(); @@ -31,16 +28,7 @@ pub fn establish_connection() -> PgConnection { PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url)) } -pub struct NewService; - -impl hyper::server::NewService for NewService { - type Request = (hyper::Request, fatcat_api::Context); - type Response = hyper::Response; - type Error = hyper::Error; - type Instance = fatcat_api::server::Service<api_server::Server>; - - /// Instantiate a new server. - fn new_service(&self) -> io::Result<Self::Instance> { - Ok(fatcat_api::server::Service::new(api_server::Server)) - } +/// Instantiate a new server. +pub fn server() -> Result<api_server::Server> { + Ok(api_server::Server {}) } |