├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── client ├── client.py └── test_image_3.png ├── requirements.txt ├── saved_model └── model.pt ├── server ├── Cargo.lock ├── Cargo.toml └── src │ ├── main.rs │ └── mnist_model.rs └── training └── train.py /.dockerignore: -------------------------------------------------------------------------------- 1 | **/target -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS cache 2 | .DS_Store 3 | 4 | # Python cache 5 | __pycache__ 6 | 7 | # Editor settings 8 | .vscode 9 | .ipynb_checkpoints 10 | 11 | # Rust compilation targets 12 | server/target 13 | 14 | # Downloaded data 15 | data/ 16 | 17 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:latest AS build 2 | 3 | WORKDIR /app 4 | COPY server/Cargo.toml server/Cargo.lock ./ 5 | COPY server/src/ src/ 6 | RUN cargo build --release 7 | RUN find . -type d | grep "libtorch/lib$" | xargs -I{} mv {} libtorch 8 | 9 | FROM debian:buster-slim 10 | 11 | RUN apt-get update \ 12 | && apt-get install -y \ 13 | ca-certificates \ 14 | libgomp1 \ 15 | && apt-get autoremove \ 16 | && apt-get clean \ 17 | && rm -rf /var/lib/apt/lists/* 18 | 19 | WORKDIR /app 20 | COPY --from=build /app/target/release/actix-torch-server /usr/local/bin/actix-torch-server 21 | copy --from=build /app/libtorch/* /usr/lib/ 22 | COPY saved_model/ /app/saved_model/ 23 | 24 | RUN useradd -mU -s /bin/bash actix 25 | USER actix 26 | 27 | EXPOSE 8080 28 | ENTRYPOINT ["actix-torch-server", "--model-path=/app/saved_model/model.pt"] 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serving PyTorch with Actix-Web 2 | 3 | This repository gives an example of training a machine learning model using PyTorch, exporting that model, then serving inference over a RESTful API using Actix-Web in rust. 4 | 5 | Implemented by request based on the original [TensorFlow example](https://github.com/kykosic/actix-tensorflow-example). 6 | 7 | 8 | For more information on the tools used, check out the following repositories: 9 | * [PyTorch](https://pytorch.org/) 10 | * [Torch Rust (tch-rs)](https://github.com/LaurentMazare/tch-rs) 11 | * [Actix Web](https://github.com/actix/actix-web) 12 | 13 | 14 | ## Overview 15 | The repository has 3 sections: 16 | * `./training` – Contains the script which trains a neural network to recognize digits. 17 | * `./server` – Contains the RESTful API webserver rust code. 18 | * `./client` – Contains a sample script that demonstrates making a request to the server. 19 | 20 | The training script will output a saved neural network model in compiled TorchScript format. The server then loads this into memory on startup. The server accepts a JSON payload at the `/mnist` endpoint with a single key "image" that is a base64 encoded image (PNG or JPG). This image is decoded, rescaled to the correct input dimensions, converted to grayscale, normalized (matching the training data normalization), and finally submitted to the model for inference. Predictions are returned with a "label" integer value and a "confidence" float between 0 and 1. 21 | 22 | ## Setup 23 | This example assumes you have [rust installed](https://www.rust-lang.org/tools/install) and python 3.6+ setup. To install the needed python dependencies: 24 | ``` 25 | pip install -r requirements.txt 26 | ``` 27 | 28 | ## Training 29 | The model used is a simple convolutional neural network trained on the [MNIST dataset](http://yann.lecun.com/exdb/mnist/). The data is automatically downloaded using the `torchvision` library. To train the model: 30 | ``` 31 | python training/train.py 32 | ``` 33 | This will output a saved model to `./saved_model/model.pt`. A pre-trained model is included in this repository. The model isn't too large and can be trained without any GPU. 34 | 35 | ## Serving 36 | The server code is a rust crate located in `./server`. In order to run, the server requires the saved model directory location specified with the `--model-path` command line argument. you can try running the server with: 37 | ``` 38 | cd server 39 | cargo run -- --model-dir ../saved_model/model.pt 40 | ``` 41 | 42 | ## Serving in Docker 43 | For actual deployments, you probably would want to build a release in a container to serve the API. To build the docker image: 44 | ``` 45 | docker build -t actix-torch . 46 | ``` 47 | Then to run the image locally for testing: 48 | ``` 49 | docker run --rm -it -p 8080:8080 actix-torch 50 | ``` 51 | 52 | ## Client Testing 53 | With the server running locally, you can test inference using `./client/client.py`. Included is a PNG file with a handwritten "3" that is base64-encoded and submitted to the server. 54 | 55 | To test: 56 | ``` 57 | python client/client.py 58 | ``` 59 | 60 | Input: 61 | 62 | 63 | 64 | Expected output: 65 | ``` 66 | POST to http://127.0.0.1:8080/mnist 67 | Response (200) 68 | Content: { 69 | "label": 3, 70 | "confidence": 0.9999999 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /client/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Example python client for testing the prediction server 4 | """ 5 | import base64 6 | import json 7 | import os 8 | 9 | import requests 10 | 11 | 12 | if __name__ == '__main__': 13 | url = "http://127.0.0.1:8080/mnist" 14 | this_dir = os.path.dirname(os.path.abspath(__file__)) 15 | image_path = os.path.join(this_dir, 'test_image_3.png') 16 | 17 | print(f"Reading image from {image_path}") 18 | with open(image_path, 'rb') as f: 19 | image = f.read() 20 | 21 | data = { 22 | 'image': base64.b64encode(image).decode() 23 | } 24 | print(f"POST to {url}") 25 | res = requests.post(url, 26 | json=data, 27 | headers={'content-type': 'application/json'}) 28 | print(f"Response ({res.status_code})") 29 | if res.status_code == 200: 30 | print(f"Content: {json.dumps(res.json(), indent=4)}") 31 | else: 32 | print(f"Body: {res.text}") 33 | -------------------------------------------------------------------------------- /client/test_image_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kykosic/actix-pytorch-example/c7565edda0158d3eccf1c3d7d4862f0c1eaf5a03/client/test_image_3.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests~=2.26.0 2 | torch~=1.9.0 3 | torchvision~=0.10.0 4 | -------------------------------------------------------------------------------- /saved_model/model.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kykosic/actix-pytorch-example/c7565edda0158d3eccf1c3d7d4862f0c1eaf5a03/saved_model/model.pt -------------------------------------------------------------------------------- /server/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "actix-codec" 7 | version = "0.2.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" 10 | dependencies = [ 11 | "bitflags", 12 | "bytes", 13 | "futures-core", 14 | "futures-sink", 15 | "log", 16 | "tokio", 17 | "tokio-util 0.2.0", 18 | ] 19 | 20 | [[package]] 21 | name = "actix-codec" 22 | version = "0.3.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" 25 | dependencies = [ 26 | "bitflags", 27 | "bytes", 28 | "futures-core", 29 | "futures-sink", 30 | "log", 31 | "pin-project", 32 | "tokio", 33 | "tokio-util 0.3.1", 34 | ] 35 | 36 | [[package]] 37 | name = "actix-connect" 38 | version = "2.0.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" 41 | dependencies = [ 42 | "actix-codec 0.3.0", 43 | "actix-rt", 44 | "actix-service", 45 | "actix-utils 2.0.0", 46 | "derive_more", 47 | "either", 48 | "futures-util", 49 | "http", 50 | "log", 51 | "openssl", 52 | "tokio-openssl", 53 | "trust-dns-proto", 54 | "trust-dns-resolver", 55 | ] 56 | 57 | [[package]] 58 | name = "actix-http" 59 | version = "2.0.0" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "05dd80ba8f27c4a34357c07e338c8f5c38f8520e6d626ca1727d8fecc41b0cab" 62 | dependencies = [ 63 | "actix-codec 0.3.0", 64 | "actix-connect", 65 | "actix-rt", 66 | "actix-service", 67 | "actix-threadpool", 68 | "actix-tls", 69 | "actix-utils 2.0.0", 70 | "base64", 71 | "bitflags", 72 | "brotli2", 73 | "bytes", 74 | "cookie", 75 | "copyless", 76 | "derive_more", 77 | "either", 78 | "encoding_rs", 79 | "flate2", 80 | "futures-channel", 81 | "futures-core", 82 | "futures-util", 83 | "fxhash", 84 | "h2", 85 | "http", 86 | "httparse", 87 | "indexmap", 88 | "itoa", 89 | "language-tags", 90 | "lazy_static", 91 | "log", 92 | "mime", 93 | "percent-encoding", 94 | "pin-project", 95 | "rand 0.7.3", 96 | "regex", 97 | "serde", 98 | "serde_json", 99 | "serde_urlencoded", 100 | "sha-1", 101 | "slab", 102 | "time 0.2.19", 103 | ] 104 | 105 | [[package]] 106 | name = "actix-macros" 107 | version = "0.1.2" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2" 110 | dependencies = [ 111 | "quote", 112 | "syn", 113 | ] 114 | 115 | [[package]] 116 | name = "actix-router" 117 | version = "0.2.4" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8" 120 | dependencies = [ 121 | "bytestring", 122 | "http", 123 | "log", 124 | "regex", 125 | "serde", 126 | ] 127 | 128 | [[package]] 129 | name = "actix-rt" 130 | version = "1.1.1" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" 133 | dependencies = [ 134 | "actix-macros", 135 | "actix-threadpool", 136 | "copyless", 137 | "futures-channel", 138 | "futures-util", 139 | "smallvec", 140 | "tokio", 141 | ] 142 | 143 | [[package]] 144 | name = "actix-server" 145 | version = "1.0.3" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "e6d74b464215a473c973a2d7d03a69cc10f4ce1f4b38a7659c5193dc5c675630" 148 | dependencies = [ 149 | "actix-codec 0.2.0", 150 | "actix-rt", 151 | "actix-service", 152 | "actix-utils 1.0.6", 153 | "futures-channel", 154 | "futures-util", 155 | "log", 156 | "mio", 157 | "mio-uds", 158 | "num_cpus", 159 | "slab", 160 | "socket2", 161 | ] 162 | 163 | [[package]] 164 | name = "actix-service" 165 | version = "1.0.6" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" 168 | dependencies = [ 169 | "futures-util", 170 | "pin-project", 171 | ] 172 | 173 | [[package]] 174 | name = "actix-testing" 175 | version = "1.0.1" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" 178 | dependencies = [ 179 | "actix-macros", 180 | "actix-rt", 181 | "actix-server", 182 | "actix-service", 183 | "log", 184 | "socket2", 185 | ] 186 | 187 | [[package]] 188 | name = "actix-threadpool" 189 | version = "0.3.2" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "91164716d956745c79dcea5e66d2aa04506549958accefcede5368c70f2fd4ff" 192 | dependencies = [ 193 | "derive_more", 194 | "futures-channel", 195 | "lazy_static", 196 | "log", 197 | "num_cpus", 198 | "parking_lot", 199 | "threadpool", 200 | ] 201 | 202 | [[package]] 203 | name = "actix-tls" 204 | version = "2.0.0" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" 207 | dependencies = [ 208 | "actix-codec 0.3.0", 209 | "actix-service", 210 | "actix-utils 2.0.0", 211 | "futures-util", 212 | "openssl", 213 | "tokio-openssl", 214 | ] 215 | 216 | [[package]] 217 | name = "actix-torch-server" 218 | version = "0.1.0" 219 | dependencies = [ 220 | "actix-web", 221 | "anyhow", 222 | "base64", 223 | "env_logger", 224 | "image", 225 | "serde", 226 | "structopt", 227 | "tch", 228 | ] 229 | 230 | [[package]] 231 | name = "actix-utils" 232 | version = "1.0.6" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e" 235 | dependencies = [ 236 | "actix-codec 0.2.0", 237 | "actix-rt", 238 | "actix-service", 239 | "bitflags", 240 | "bytes", 241 | "either", 242 | "futures", 243 | "log", 244 | "pin-project", 245 | "slab", 246 | ] 247 | 248 | [[package]] 249 | name = "actix-utils" 250 | version = "2.0.0" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" 253 | dependencies = [ 254 | "actix-codec 0.3.0", 255 | "actix-rt", 256 | "actix-service", 257 | "bitflags", 258 | "bytes", 259 | "either", 260 | "futures-channel", 261 | "futures-sink", 262 | "futures-util", 263 | "log", 264 | "pin-project", 265 | "slab", 266 | ] 267 | 268 | [[package]] 269 | name = "actix-web" 270 | version = "3.0.1" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "cd7fc56022da91a4dc00ccae7d7bb82e539749ca36df181695f4efdf5d413b2e" 273 | dependencies = [ 274 | "actix-codec 0.3.0", 275 | "actix-http", 276 | "actix-macros", 277 | "actix-router", 278 | "actix-rt", 279 | "actix-server", 280 | "actix-service", 281 | "actix-testing", 282 | "actix-threadpool", 283 | "actix-tls", 284 | "actix-utils 2.0.0", 285 | "actix-web-codegen", 286 | "awc", 287 | "bytes", 288 | "derive_more", 289 | "encoding_rs", 290 | "futures-channel", 291 | "futures-core", 292 | "futures-util", 293 | "fxhash", 294 | "log", 295 | "mime", 296 | "openssl", 297 | "pin-project", 298 | "regex", 299 | "serde", 300 | "serde_json", 301 | "serde_urlencoded", 302 | "socket2", 303 | "time 0.2.19", 304 | "tinyvec", 305 | "url", 306 | ] 307 | 308 | [[package]] 309 | name = "actix-web-codegen" 310 | version = "0.3.0" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "750ca8fb60bbdc79491991650ba5d2ae7cd75f3fc00ead51390cfe9efda0d4d8" 313 | dependencies = [ 314 | "proc-macro2", 315 | "quote", 316 | "syn", 317 | ] 318 | 319 | [[package]] 320 | name = "addr2line" 321 | version = "0.12.1" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543" 324 | dependencies = [ 325 | "gimli", 326 | ] 327 | 328 | [[package]] 329 | name = "adler32" 330 | version = "1.0.4" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" 333 | 334 | [[package]] 335 | name = "aho-corasick" 336 | version = "0.7.10" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" 339 | dependencies = [ 340 | "memchr", 341 | ] 342 | 343 | [[package]] 344 | name = "ansi_term" 345 | version = "0.11.0" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 348 | dependencies = [ 349 | "winapi 0.3.8", 350 | ] 351 | 352 | [[package]] 353 | name = "anyhow" 354 | version = "1.0.31" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" 357 | 358 | [[package]] 359 | name = "arc-swap" 360 | version = "0.4.7" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" 363 | 364 | [[package]] 365 | name = "async-trait" 366 | version = "0.1.33" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "8f1c13101a3224fb178860ae372a031ce350bbd92d39968518f016744dde0bf7" 369 | dependencies = [ 370 | "proc-macro2", 371 | "quote", 372 | "syn", 373 | ] 374 | 375 | [[package]] 376 | name = "atty" 377 | version = "0.2.14" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 380 | dependencies = [ 381 | "hermit-abi", 382 | "libc", 383 | "winapi 0.3.8", 384 | ] 385 | 386 | [[package]] 387 | name = "autocfg" 388 | version = "1.0.0" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 391 | 392 | [[package]] 393 | name = "awc" 394 | version = "2.0.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "150e00c06683ab44c5f97d033950e5d87a7a042d06d77f5eecb443cbd23d0575" 397 | dependencies = [ 398 | "actix-codec 0.3.0", 399 | "actix-http", 400 | "actix-rt", 401 | "actix-service", 402 | "base64", 403 | "bytes", 404 | "derive_more", 405 | "futures-core", 406 | "log", 407 | "mime", 408 | "openssl", 409 | "percent-encoding", 410 | "rand 0.7.3", 411 | "serde", 412 | "serde_json", 413 | "serde_urlencoded", 414 | ] 415 | 416 | [[package]] 417 | name = "backtrace" 418 | version = "0.3.48" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130" 421 | dependencies = [ 422 | "addr2line", 423 | "cfg-if 0.1.10", 424 | "libc", 425 | "object", 426 | "rustc-demangle", 427 | ] 428 | 429 | [[package]] 430 | name = "base-x" 431 | version = "0.2.6" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1" 434 | 435 | [[package]] 436 | name = "base64" 437 | version = "0.12.1" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42" 440 | 441 | [[package]] 442 | name = "bitflags" 443 | version = "1.2.1" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 446 | 447 | [[package]] 448 | name = "block-buffer" 449 | version = "0.9.0" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 452 | dependencies = [ 453 | "generic-array", 454 | ] 455 | 456 | [[package]] 457 | name = "brotli-sys" 458 | version = "0.3.2" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" 461 | dependencies = [ 462 | "cc", 463 | "libc", 464 | ] 465 | 466 | [[package]] 467 | name = "brotli2" 468 | version = "0.3.2" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" 471 | dependencies = [ 472 | "brotli-sys", 473 | "libc", 474 | ] 475 | 476 | [[package]] 477 | name = "bumpalo" 478 | version = "3.4.0" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" 481 | 482 | [[package]] 483 | name = "bytemuck" 484 | version = "1.2.0" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431" 487 | 488 | [[package]] 489 | name = "byteorder" 490 | version = "1.3.4" 491 | source = "registry+https://github.com/rust-lang/crates.io-index" 492 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 493 | 494 | [[package]] 495 | name = "bytes" 496 | version = "0.5.4" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" 499 | 500 | [[package]] 501 | name = "bytestring" 502 | version = "0.1.5" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "fc7c05fa5172da78a62d9949d662d2ac89d4cc7355d7b49adee5163f1fb3f363" 505 | dependencies = [ 506 | "bytes", 507 | ] 508 | 509 | [[package]] 510 | name = "bzip2" 511 | version = "0.3.3" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" 514 | dependencies = [ 515 | "bzip2-sys", 516 | "libc", 517 | ] 518 | 519 | [[package]] 520 | name = "bzip2-sys" 521 | version = "0.1.9+1.0.8" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | checksum = "ad3b39a260062fca31f7b0b12f207e8f2590a67d32ec7d59c20484b07ea7285e" 524 | dependencies = [ 525 | "cc", 526 | "libc", 527 | "pkg-config", 528 | ] 529 | 530 | [[package]] 531 | name = "cc" 532 | version = "1.0.54" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" 535 | 536 | [[package]] 537 | name = "cfg-if" 538 | version = "0.1.10" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 541 | 542 | [[package]] 543 | name = "cfg-if" 544 | version = "1.0.0" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 547 | 548 | [[package]] 549 | name = "clap" 550 | version = "2.33.1" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" 553 | dependencies = [ 554 | "ansi_term", 555 | "atty", 556 | "bitflags", 557 | "strsim", 558 | "textwrap", 559 | "unicode-width", 560 | "vec_map", 561 | ] 562 | 563 | [[package]] 564 | name = "cloudabi" 565 | version = "0.0.3" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 568 | dependencies = [ 569 | "bitflags", 570 | ] 571 | 572 | [[package]] 573 | name = "color_quant" 574 | version = "1.0.1" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" 577 | 578 | [[package]] 579 | name = "const_fn" 580 | version = "0.4.2" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2" 583 | 584 | [[package]] 585 | name = "cookie" 586 | version = "0.14.2" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "1373a16a4937bc34efec7b391f9c1500c30b8478a701a4f44c9165cc0475a6e0" 589 | dependencies = [ 590 | "percent-encoding", 591 | "time 0.2.19", 592 | "version_check", 593 | ] 594 | 595 | [[package]] 596 | name = "copyless" 597 | version = "0.1.5" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" 600 | 601 | [[package]] 602 | name = "cpuid-bool" 603 | version = "0.1.2" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" 606 | 607 | [[package]] 608 | name = "crc32fast" 609 | version = "1.2.0" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 612 | dependencies = [ 613 | "cfg-if 0.1.10", 614 | ] 615 | 616 | [[package]] 617 | name = "crossbeam-deque" 618 | version = "0.7.3" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 621 | dependencies = [ 622 | "crossbeam-epoch", 623 | "crossbeam-utils", 624 | "maybe-uninit", 625 | ] 626 | 627 | [[package]] 628 | name = "crossbeam-epoch" 629 | version = "0.8.2" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 632 | dependencies = [ 633 | "autocfg", 634 | "cfg-if 0.1.10", 635 | "crossbeam-utils", 636 | "lazy_static", 637 | "maybe-uninit", 638 | "memoffset", 639 | "scopeguard", 640 | ] 641 | 642 | [[package]] 643 | name = "crossbeam-queue" 644 | version = "0.2.3" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" 647 | dependencies = [ 648 | "cfg-if 0.1.10", 649 | "crossbeam-utils", 650 | "maybe-uninit", 651 | ] 652 | 653 | [[package]] 654 | name = "crossbeam-utils" 655 | version = "0.7.2" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 658 | dependencies = [ 659 | "autocfg", 660 | "cfg-if 0.1.10", 661 | "lazy_static", 662 | ] 663 | 664 | [[package]] 665 | name = "curl" 666 | version = "0.4.29" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "762e34611d2d5233a506a79072be944fddd057db2f18e04c0d6fa79e3fd466fd" 669 | dependencies = [ 670 | "curl-sys", 671 | "libc", 672 | "openssl-probe", 673 | "openssl-sys", 674 | "schannel", 675 | "socket2", 676 | "winapi 0.3.8", 677 | ] 678 | 679 | [[package]] 680 | name = "curl-sys" 681 | version = "0.4.31+curl-7.70.0" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "dcd62757cc4f5ab9404bc6ca9f0ae447e729a1403948ce5106bd588ceac6a3b0" 684 | dependencies = [ 685 | "cc", 686 | "libc", 687 | "libz-sys", 688 | "openssl-sys", 689 | "pkg-config", 690 | "vcpkg", 691 | "winapi 0.3.8", 692 | ] 693 | 694 | [[package]] 695 | name = "deflate" 696 | version = "0.8.4" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7" 699 | dependencies = [ 700 | "adler32", 701 | "byteorder", 702 | ] 703 | 704 | [[package]] 705 | name = "derive_more" 706 | version = "0.99.7" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d" 709 | dependencies = [ 710 | "proc-macro2", 711 | "quote", 712 | "syn", 713 | ] 714 | 715 | [[package]] 716 | name = "digest" 717 | version = "0.9.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 720 | dependencies = [ 721 | "generic-array", 722 | ] 723 | 724 | [[package]] 725 | name = "discard" 726 | version = "1.0.4" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" 729 | 730 | [[package]] 731 | name = "dtoa" 732 | version = "0.4.5" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" 735 | 736 | [[package]] 737 | name = "either" 738 | version = "1.5.3" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" 741 | 742 | [[package]] 743 | name = "encoding_rs" 744 | version = "0.8.23" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171" 747 | dependencies = [ 748 | "cfg-if 0.1.10", 749 | ] 750 | 751 | [[package]] 752 | name = "enum-as-inner" 753 | version = "0.3.2" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "bc4bfcfacb61d231109d1d55202c1f33263319668b168843e02ad4652725ec9c" 756 | dependencies = [ 757 | "heck", 758 | "proc-macro2", 759 | "quote", 760 | "syn", 761 | ] 762 | 763 | [[package]] 764 | name = "env_logger" 765 | version = "0.7.1" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" 768 | dependencies = [ 769 | "atty", 770 | "humantime", 771 | "log", 772 | "regex", 773 | "termcolor", 774 | ] 775 | 776 | [[package]] 777 | name = "flate2" 778 | version = "1.0.14" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 781 | dependencies = [ 782 | "cfg-if 0.1.10", 783 | "crc32fast", 784 | "libc", 785 | "miniz_oxide", 786 | ] 787 | 788 | [[package]] 789 | name = "fnv" 790 | version = "1.0.7" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 793 | 794 | [[package]] 795 | name = "foreign-types" 796 | version = "0.3.2" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 799 | dependencies = [ 800 | "foreign-types-shared", 801 | ] 802 | 803 | [[package]] 804 | name = "foreign-types-shared" 805 | version = "0.1.1" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 808 | 809 | [[package]] 810 | name = "fuchsia-zircon" 811 | version = "0.3.3" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 814 | dependencies = [ 815 | "bitflags", 816 | "fuchsia-zircon-sys", 817 | ] 818 | 819 | [[package]] 820 | name = "fuchsia-zircon-sys" 821 | version = "0.3.3" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 824 | 825 | [[package]] 826 | name = "futures" 827 | version = "0.3.5" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" 830 | dependencies = [ 831 | "futures-channel", 832 | "futures-core", 833 | "futures-executor", 834 | "futures-io", 835 | "futures-sink", 836 | "futures-task", 837 | "futures-util", 838 | ] 839 | 840 | [[package]] 841 | name = "futures-channel" 842 | version = "0.3.5" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" 845 | dependencies = [ 846 | "futures-core", 847 | "futures-sink", 848 | ] 849 | 850 | [[package]] 851 | name = "futures-core" 852 | version = "0.3.5" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" 855 | 856 | [[package]] 857 | name = "futures-executor" 858 | version = "0.3.5" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" 861 | dependencies = [ 862 | "futures-core", 863 | "futures-task", 864 | "futures-util", 865 | ] 866 | 867 | [[package]] 868 | name = "futures-io" 869 | version = "0.3.5" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" 872 | 873 | [[package]] 874 | name = "futures-macro" 875 | version = "0.3.5" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" 878 | dependencies = [ 879 | "proc-macro-hack", 880 | "proc-macro2", 881 | "quote", 882 | "syn", 883 | ] 884 | 885 | [[package]] 886 | name = "futures-sink" 887 | version = "0.3.5" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" 890 | 891 | [[package]] 892 | name = "futures-task" 893 | version = "0.3.5" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" 896 | dependencies = [ 897 | "once_cell", 898 | ] 899 | 900 | [[package]] 901 | name = "futures-util" 902 | version = "0.3.5" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" 905 | dependencies = [ 906 | "futures-channel", 907 | "futures-core", 908 | "futures-io", 909 | "futures-macro", 910 | "futures-sink", 911 | "futures-task", 912 | "memchr", 913 | "pin-project", 914 | "pin-utils", 915 | "proc-macro-hack", 916 | "proc-macro-nested", 917 | "slab", 918 | ] 919 | 920 | [[package]] 921 | name = "fxhash" 922 | version = "0.2.1" 923 | source = "registry+https://github.com/rust-lang/crates.io-index" 924 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 925 | dependencies = [ 926 | "byteorder", 927 | ] 928 | 929 | [[package]] 930 | name = "generic-array" 931 | version = "0.14.4" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" 934 | dependencies = [ 935 | "typenum", 936 | "version_check", 937 | ] 938 | 939 | [[package]] 940 | name = "getrandom" 941 | version = "0.1.14" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 944 | dependencies = [ 945 | "cfg-if 0.1.10", 946 | "libc", 947 | "wasi 0.9.0+wasi-snapshot-preview1", 948 | ] 949 | 950 | [[package]] 951 | name = "getrandom" 952 | version = "0.2.3" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 955 | dependencies = [ 956 | "cfg-if 1.0.0", 957 | "libc", 958 | "wasi 0.10.2+wasi-snapshot-preview1", 959 | ] 960 | 961 | [[package]] 962 | name = "gif" 963 | version = "0.10.3" 964 | source = "registry+https://github.com/rust-lang/crates.io-index" 965 | checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" 966 | dependencies = [ 967 | "color_quant", 968 | "lzw", 969 | ] 970 | 971 | [[package]] 972 | name = "gimli" 973 | version = "0.21.0" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" 976 | 977 | [[package]] 978 | name = "h2" 979 | version = "0.2.5" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" 982 | dependencies = [ 983 | "bytes", 984 | "fnv", 985 | "futures-core", 986 | "futures-sink", 987 | "futures-util", 988 | "http", 989 | "indexmap", 990 | "log", 991 | "slab", 992 | "tokio", 993 | "tokio-util 0.3.1", 994 | ] 995 | 996 | [[package]] 997 | name = "half" 998 | version = "1.6.0" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177" 1001 | 1002 | [[package]] 1003 | name = "heck" 1004 | version = "0.3.1" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 1007 | dependencies = [ 1008 | "unicode-segmentation", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "hermit-abi" 1013 | version = "0.1.13" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" 1016 | dependencies = [ 1017 | "libc", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "hostname" 1022 | version = "0.3.1" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" 1025 | dependencies = [ 1026 | "libc", 1027 | "match_cfg", 1028 | "winapi 0.3.8", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "http" 1033 | version = "0.2.1" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" 1036 | dependencies = [ 1037 | "bytes", 1038 | "fnv", 1039 | "itoa", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "httparse" 1044 | version = "1.3.4" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 1047 | 1048 | [[package]] 1049 | name = "humantime" 1050 | version = "1.3.0" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 1053 | dependencies = [ 1054 | "quick-error", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "idna" 1059 | version = "0.2.0" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1062 | dependencies = [ 1063 | "matches", 1064 | "unicode-bidi", 1065 | "unicode-normalization", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "image" 1070 | version = "0.23.6" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "b5b0553fec6407d63fe2975b794dfb099f3f790bdc958823851af37b26404ab4" 1073 | dependencies = [ 1074 | "bytemuck", 1075 | "byteorder", 1076 | "gif", 1077 | "jpeg-decoder", 1078 | "num-iter", 1079 | "num-rational", 1080 | "num-traits", 1081 | "png", 1082 | "scoped_threadpool", 1083 | "tiff", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "indexmap" 1088 | version = "1.4.0" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" 1091 | dependencies = [ 1092 | "autocfg", 1093 | ] 1094 | 1095 | [[package]] 1096 | name = "iovec" 1097 | version = "0.1.4" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 1100 | dependencies = [ 1101 | "libc", 1102 | ] 1103 | 1104 | [[package]] 1105 | name = "ipconfig" 1106 | version = "0.2.2" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" 1109 | dependencies = [ 1110 | "socket2", 1111 | "widestring", 1112 | "winapi 0.3.8", 1113 | "winreg", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "itoa" 1118 | version = "0.4.5" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 1121 | 1122 | [[package]] 1123 | name = "jpeg-decoder" 1124 | version = "0.1.19" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704" 1127 | dependencies = [ 1128 | "byteorder", 1129 | "rayon", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "kernel32-sys" 1134 | version = "0.2.2" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1137 | dependencies = [ 1138 | "winapi 0.2.8", 1139 | "winapi-build", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "language-tags" 1144 | version = "0.2.2" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" 1147 | 1148 | [[package]] 1149 | name = "lazy_static" 1150 | version = "1.4.0" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1153 | 1154 | [[package]] 1155 | name = "libc" 1156 | version = "0.2.71" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" 1159 | 1160 | [[package]] 1161 | name = "libz-sys" 1162 | version = "1.0.25" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" 1165 | dependencies = [ 1166 | "cc", 1167 | "libc", 1168 | "pkg-config", 1169 | "vcpkg", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "linked-hash-map" 1174 | version = "0.5.3" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" 1177 | 1178 | [[package]] 1179 | name = "lock_api" 1180 | version = "0.3.4" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 1183 | dependencies = [ 1184 | "scopeguard", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "log" 1189 | version = "0.4.8" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1192 | dependencies = [ 1193 | "cfg-if 0.1.10", 1194 | ] 1195 | 1196 | [[package]] 1197 | name = "lru-cache" 1198 | version = "0.1.2" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 1201 | dependencies = [ 1202 | "linked-hash-map", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "lzw" 1207 | version = "0.10.0" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" 1210 | 1211 | [[package]] 1212 | name = "match_cfg" 1213 | version = "0.1.0" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" 1216 | 1217 | [[package]] 1218 | name = "matches" 1219 | version = "0.1.8" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1222 | 1223 | [[package]] 1224 | name = "matrixmultiply" 1225 | version = "0.3.1" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "5a8a15b776d9dfaecd44b03c5828c2199cddff5247215858aac14624f8d6b741" 1228 | dependencies = [ 1229 | "rawpointer", 1230 | ] 1231 | 1232 | [[package]] 1233 | name = "maybe-uninit" 1234 | version = "2.0.0" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 1237 | 1238 | [[package]] 1239 | name = "memchr" 1240 | version = "2.3.3" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 1243 | 1244 | [[package]] 1245 | name = "memoffset" 1246 | version = "0.5.4" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" 1249 | dependencies = [ 1250 | "autocfg", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "mime" 1255 | version = "0.3.16" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 1258 | 1259 | [[package]] 1260 | name = "miniz_oxide" 1261 | version = "0.3.6" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" 1264 | dependencies = [ 1265 | "adler32", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "mio" 1270 | version = "0.6.22" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" 1273 | dependencies = [ 1274 | "cfg-if 0.1.10", 1275 | "fuchsia-zircon", 1276 | "fuchsia-zircon-sys", 1277 | "iovec", 1278 | "kernel32-sys", 1279 | "libc", 1280 | "log", 1281 | "miow", 1282 | "net2", 1283 | "slab", 1284 | "winapi 0.2.8", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "mio-uds" 1289 | version = "0.6.8" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" 1292 | dependencies = [ 1293 | "iovec", 1294 | "libc", 1295 | "mio", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "miow" 1300 | version = "0.2.1" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1303 | dependencies = [ 1304 | "kernel32-sys", 1305 | "net2", 1306 | "winapi 0.2.8", 1307 | "ws2_32-sys", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "ndarray" 1312 | version = "0.15.3" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "08e854964160a323e65baa19a0b1a027f76d590faba01f05c0cbc3187221a8c9" 1315 | dependencies = [ 1316 | "matrixmultiply", 1317 | "num-complex", 1318 | "num-integer", 1319 | "num-traits", 1320 | "rawpointer", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "net2" 1325 | version = "0.2.34" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" 1328 | dependencies = [ 1329 | "cfg-if 0.1.10", 1330 | "libc", 1331 | "winapi 0.3.8", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "num-complex" 1336 | version = "0.4.0" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" 1339 | dependencies = [ 1340 | "num-traits", 1341 | ] 1342 | 1343 | [[package]] 1344 | name = "num-integer" 1345 | version = "0.1.42" 1346 | source = "registry+https://github.com/rust-lang/crates.io-index" 1347 | checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" 1348 | dependencies = [ 1349 | "autocfg", 1350 | "num-traits", 1351 | ] 1352 | 1353 | [[package]] 1354 | name = "num-iter" 1355 | version = "0.1.41" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" 1358 | dependencies = [ 1359 | "autocfg", 1360 | "num-integer", 1361 | "num-traits", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "num-rational" 1366 | version = "0.3.0" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138" 1369 | dependencies = [ 1370 | "autocfg", 1371 | "num-integer", 1372 | "num-traits", 1373 | ] 1374 | 1375 | [[package]] 1376 | name = "num-traits" 1377 | version = "0.2.11" 1378 | source = "registry+https://github.com/rust-lang/crates.io-index" 1379 | checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" 1380 | dependencies = [ 1381 | "autocfg", 1382 | ] 1383 | 1384 | [[package]] 1385 | name = "num_cpus" 1386 | version = "1.13.0" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 1389 | dependencies = [ 1390 | "hermit-abi", 1391 | "libc", 1392 | ] 1393 | 1394 | [[package]] 1395 | name = "object" 1396 | version = "0.19.0" 1397 | source = "registry+https://github.com/rust-lang/crates.io-index" 1398 | checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" 1399 | 1400 | [[package]] 1401 | name = "once_cell" 1402 | version = "1.4.0" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" 1405 | 1406 | [[package]] 1407 | name = "opaque-debug" 1408 | version = "0.3.0" 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" 1410 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 1411 | 1412 | [[package]] 1413 | name = "openssl" 1414 | version = "0.10.29" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd" 1417 | dependencies = [ 1418 | "bitflags", 1419 | "cfg-if 0.1.10", 1420 | "foreign-types", 1421 | "lazy_static", 1422 | "libc", 1423 | "openssl-sys", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "openssl-probe" 1428 | version = "0.1.2" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1431 | 1432 | [[package]] 1433 | name = "openssl-sys" 1434 | version = "0.9.58" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" 1437 | dependencies = [ 1438 | "autocfg", 1439 | "cc", 1440 | "libc", 1441 | "pkg-config", 1442 | "vcpkg", 1443 | ] 1444 | 1445 | [[package]] 1446 | name = "parking_lot" 1447 | version = "0.10.2" 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" 1449 | checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" 1450 | dependencies = [ 1451 | "lock_api", 1452 | "parking_lot_core", 1453 | ] 1454 | 1455 | [[package]] 1456 | name = "parking_lot_core" 1457 | version = "0.7.2" 1458 | source = "registry+https://github.com/rust-lang/crates.io-index" 1459 | checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" 1460 | dependencies = [ 1461 | "cfg-if 0.1.10", 1462 | "cloudabi", 1463 | "libc", 1464 | "redox_syscall", 1465 | "smallvec", 1466 | "winapi 0.3.8", 1467 | ] 1468 | 1469 | [[package]] 1470 | name = "percent-encoding" 1471 | version = "2.1.0" 1472 | source = "registry+https://github.com/rust-lang/crates.io-index" 1473 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1474 | 1475 | [[package]] 1476 | name = "pin-project" 1477 | version = "0.4.20" 1478 | source = "registry+https://github.com/rust-lang/crates.io-index" 1479 | checksum = "e75373ff9037d112bb19bc61333a06a159eaeb217660dcfbea7d88e1db823919" 1480 | dependencies = [ 1481 | "pin-project-internal", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "pin-project-internal" 1486 | version = "0.4.20" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "10b4b44893d3c370407a1d6a5cfde7c41ae0478e31c516c85f67eb3adc51be6d" 1489 | dependencies = [ 1490 | "proc-macro2", 1491 | "quote", 1492 | "syn", 1493 | ] 1494 | 1495 | [[package]] 1496 | name = "pin-project-lite" 1497 | version = "0.1.7" 1498 | source = "registry+https://github.com/rust-lang/crates.io-index" 1499 | checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" 1500 | 1501 | [[package]] 1502 | name = "pin-utils" 1503 | version = "0.1.0" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1506 | 1507 | [[package]] 1508 | name = "pkg-config" 1509 | version = "0.3.17" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 1512 | 1513 | [[package]] 1514 | name = "png" 1515 | version = "0.16.6" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "c150bf7479fafe3dd8740dbe48cc33b2a3efb7b0fe3483aced8bbc39f6d0238d" 1518 | dependencies = [ 1519 | "bitflags", 1520 | "crc32fast", 1521 | "deflate", 1522 | "miniz_oxide", 1523 | ] 1524 | 1525 | [[package]] 1526 | name = "podio" 1527 | version = "0.1.7" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | checksum = "b18befed8bc2b61abc79a457295e7e838417326da1586050b919414073977f19" 1530 | 1531 | [[package]] 1532 | name = "ppv-lite86" 1533 | version = "0.2.8" 1534 | source = "registry+https://github.com/rust-lang/crates.io-index" 1535 | checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" 1536 | 1537 | [[package]] 1538 | name = "proc-macro-error" 1539 | version = "1.0.3" 1540 | source = "registry+https://github.com/rust-lang/crates.io-index" 1541 | checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" 1542 | dependencies = [ 1543 | "proc-macro-error-attr", 1544 | "proc-macro2", 1545 | "quote", 1546 | "syn", 1547 | "version_check", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "proc-macro-error-attr" 1552 | version = "1.0.3" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" 1555 | dependencies = [ 1556 | "proc-macro2", 1557 | "quote", 1558 | "syn", 1559 | "syn-mid", 1560 | "version_check", 1561 | ] 1562 | 1563 | [[package]] 1564 | name = "proc-macro-hack" 1565 | version = "0.5.16" 1566 | source = "registry+https://github.com/rust-lang/crates.io-index" 1567 | checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" 1568 | 1569 | [[package]] 1570 | name = "proc-macro-nested" 1571 | version = "0.1.4" 1572 | source = "registry+https://github.com/rust-lang/crates.io-index" 1573 | checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" 1574 | 1575 | [[package]] 1576 | name = "proc-macro2" 1577 | version = "1.0.18" 1578 | source = "registry+https://github.com/rust-lang/crates.io-index" 1579 | checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" 1580 | dependencies = [ 1581 | "unicode-xid", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "quick-error" 1586 | version = "1.2.3" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 1589 | 1590 | [[package]] 1591 | name = "quote" 1592 | version = "1.0.7" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 1595 | dependencies = [ 1596 | "proc-macro2", 1597 | ] 1598 | 1599 | [[package]] 1600 | name = "rand" 1601 | version = "0.7.3" 1602 | source = "registry+https://github.com/rust-lang/crates.io-index" 1603 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1604 | dependencies = [ 1605 | "getrandom 0.1.14", 1606 | "libc", 1607 | "rand_chacha 0.2.2", 1608 | "rand_core 0.5.1", 1609 | "rand_hc 0.2.0", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "rand" 1614 | version = "0.8.4" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" 1617 | dependencies = [ 1618 | "libc", 1619 | "rand_chacha 0.3.1", 1620 | "rand_core 0.6.3", 1621 | "rand_hc 0.3.1", 1622 | ] 1623 | 1624 | [[package]] 1625 | name = "rand_chacha" 1626 | version = "0.2.2" 1627 | source = "registry+https://github.com/rust-lang/crates.io-index" 1628 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1629 | dependencies = [ 1630 | "ppv-lite86", 1631 | "rand_core 0.5.1", 1632 | ] 1633 | 1634 | [[package]] 1635 | name = "rand_chacha" 1636 | version = "0.3.1" 1637 | source = "registry+https://github.com/rust-lang/crates.io-index" 1638 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1639 | dependencies = [ 1640 | "ppv-lite86", 1641 | "rand_core 0.6.3", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "rand_core" 1646 | version = "0.5.1" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1649 | dependencies = [ 1650 | "getrandom 0.1.14", 1651 | ] 1652 | 1653 | [[package]] 1654 | name = "rand_core" 1655 | version = "0.6.3" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 1658 | dependencies = [ 1659 | "getrandom 0.2.3", 1660 | ] 1661 | 1662 | [[package]] 1663 | name = "rand_hc" 1664 | version = "0.2.0" 1665 | source = "registry+https://github.com/rust-lang/crates.io-index" 1666 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1667 | dependencies = [ 1668 | "rand_core 0.5.1", 1669 | ] 1670 | 1671 | [[package]] 1672 | name = "rand_hc" 1673 | version = "0.3.1" 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" 1675 | checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" 1676 | dependencies = [ 1677 | "rand_core 0.6.3", 1678 | ] 1679 | 1680 | [[package]] 1681 | name = "rawpointer" 1682 | version = "0.2.1" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 1685 | 1686 | [[package]] 1687 | name = "rayon" 1688 | version = "1.3.1" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" 1691 | dependencies = [ 1692 | "autocfg", 1693 | "crossbeam-deque", 1694 | "either", 1695 | "rayon-core", 1696 | ] 1697 | 1698 | [[package]] 1699 | name = "rayon-core" 1700 | version = "1.7.1" 1701 | source = "registry+https://github.com/rust-lang/crates.io-index" 1702 | checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" 1703 | dependencies = [ 1704 | "crossbeam-deque", 1705 | "crossbeam-queue", 1706 | "crossbeam-utils", 1707 | "lazy_static", 1708 | "num_cpus", 1709 | ] 1710 | 1711 | [[package]] 1712 | name = "redox_syscall" 1713 | version = "0.1.56" 1714 | source = "registry+https://github.com/rust-lang/crates.io-index" 1715 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1716 | 1717 | [[package]] 1718 | name = "regex" 1719 | version = "1.3.9" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" 1722 | dependencies = [ 1723 | "aho-corasick", 1724 | "memchr", 1725 | "regex-syntax", 1726 | "thread_local", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "regex-syntax" 1731 | version = "0.6.18" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" 1734 | 1735 | [[package]] 1736 | name = "resolv-conf" 1737 | version = "0.6.3" 1738 | source = "registry+https://github.com/rust-lang/crates.io-index" 1739 | checksum = "11834e137f3b14e309437a8276714eed3a80d1ef894869e510f2c0c0b98b9f4a" 1740 | dependencies = [ 1741 | "hostname", 1742 | "quick-error", 1743 | ] 1744 | 1745 | [[package]] 1746 | name = "rustc-demangle" 1747 | version = "0.1.16" 1748 | source = "registry+https://github.com/rust-lang/crates.io-index" 1749 | checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1750 | 1751 | [[package]] 1752 | name = "rustc_version" 1753 | version = "0.2.3" 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" 1755 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1756 | dependencies = [ 1757 | "semver", 1758 | ] 1759 | 1760 | [[package]] 1761 | name = "ryu" 1762 | version = "1.0.5" 1763 | source = "registry+https://github.com/rust-lang/crates.io-index" 1764 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 1765 | 1766 | [[package]] 1767 | name = "schannel" 1768 | version = "0.1.19" 1769 | source = "registry+https://github.com/rust-lang/crates.io-index" 1770 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 1771 | dependencies = [ 1772 | "lazy_static", 1773 | "winapi 0.3.8", 1774 | ] 1775 | 1776 | [[package]] 1777 | name = "scoped_threadpool" 1778 | version = "0.1.9" 1779 | source = "registry+https://github.com/rust-lang/crates.io-index" 1780 | checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" 1781 | 1782 | [[package]] 1783 | name = "scopeguard" 1784 | version = "1.1.0" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1787 | 1788 | [[package]] 1789 | name = "semver" 1790 | version = "0.9.0" 1791 | source = "registry+https://github.com/rust-lang/crates.io-index" 1792 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1793 | dependencies = [ 1794 | "semver-parser", 1795 | ] 1796 | 1797 | [[package]] 1798 | name = "semver-parser" 1799 | version = "0.7.0" 1800 | source = "registry+https://github.com/rust-lang/crates.io-index" 1801 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1802 | 1803 | [[package]] 1804 | name = "serde" 1805 | version = "1.0.111" 1806 | source = "registry+https://github.com/rust-lang/crates.io-index" 1807 | checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" 1808 | dependencies = [ 1809 | "serde_derive", 1810 | ] 1811 | 1812 | [[package]] 1813 | name = "serde_derive" 1814 | version = "1.0.111" 1815 | source = "registry+https://github.com/rust-lang/crates.io-index" 1816 | checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250" 1817 | dependencies = [ 1818 | "proc-macro2", 1819 | "quote", 1820 | "syn", 1821 | ] 1822 | 1823 | [[package]] 1824 | name = "serde_json" 1825 | version = "1.0.53" 1826 | source = "registry+https://github.com/rust-lang/crates.io-index" 1827 | checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" 1828 | dependencies = [ 1829 | "itoa", 1830 | "ryu", 1831 | "serde", 1832 | ] 1833 | 1834 | [[package]] 1835 | name = "serde_urlencoded" 1836 | version = "0.6.1" 1837 | source = "registry+https://github.com/rust-lang/crates.io-index" 1838 | checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" 1839 | dependencies = [ 1840 | "dtoa", 1841 | "itoa", 1842 | "serde", 1843 | "url", 1844 | ] 1845 | 1846 | [[package]] 1847 | name = "sha-1" 1848 | version = "0.9.1" 1849 | source = "registry+https://github.com/rust-lang/crates.io-index" 1850 | checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770" 1851 | dependencies = [ 1852 | "block-buffer", 1853 | "cfg-if 0.1.10", 1854 | "cpuid-bool", 1855 | "digest", 1856 | "opaque-debug", 1857 | ] 1858 | 1859 | [[package]] 1860 | name = "sha1" 1861 | version = "0.6.0" 1862 | source = "registry+https://github.com/rust-lang/crates.io-index" 1863 | checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" 1864 | 1865 | [[package]] 1866 | name = "signal-hook-registry" 1867 | version = "1.2.0" 1868 | source = "registry+https://github.com/rust-lang/crates.io-index" 1869 | checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" 1870 | dependencies = [ 1871 | "arc-swap", 1872 | "libc", 1873 | ] 1874 | 1875 | [[package]] 1876 | name = "slab" 1877 | version = "0.4.2" 1878 | source = "registry+https://github.com/rust-lang/crates.io-index" 1879 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1880 | 1881 | [[package]] 1882 | name = "smallvec" 1883 | version = "1.4.0" 1884 | source = "registry+https://github.com/rust-lang/crates.io-index" 1885 | checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" 1886 | 1887 | [[package]] 1888 | name = "socket2" 1889 | version = "0.3.12" 1890 | source = "registry+https://github.com/rust-lang/crates.io-index" 1891 | checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" 1892 | dependencies = [ 1893 | "cfg-if 0.1.10", 1894 | "libc", 1895 | "redox_syscall", 1896 | "winapi 0.3.8", 1897 | ] 1898 | 1899 | [[package]] 1900 | name = "standback" 1901 | version = "0.2.10" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "33a71ea1ea5f8747d1af1979bfb7e65c3a025a70609f04ceb78425bc5adad8e6" 1904 | dependencies = [ 1905 | "version_check", 1906 | ] 1907 | 1908 | [[package]] 1909 | name = "stdweb" 1910 | version = "0.4.20" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" 1913 | dependencies = [ 1914 | "discard", 1915 | "rustc_version", 1916 | "stdweb-derive", 1917 | "stdweb-internal-macros", 1918 | "stdweb-internal-runtime", 1919 | "wasm-bindgen", 1920 | ] 1921 | 1922 | [[package]] 1923 | name = "stdweb-derive" 1924 | version = "0.5.3" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" 1927 | dependencies = [ 1928 | "proc-macro2", 1929 | "quote", 1930 | "serde", 1931 | "serde_derive", 1932 | "syn", 1933 | ] 1934 | 1935 | [[package]] 1936 | name = "stdweb-internal-macros" 1937 | version = "0.2.9" 1938 | source = "registry+https://github.com/rust-lang/crates.io-index" 1939 | checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" 1940 | dependencies = [ 1941 | "base-x", 1942 | "proc-macro2", 1943 | "quote", 1944 | "serde", 1945 | "serde_derive", 1946 | "serde_json", 1947 | "sha1", 1948 | "syn", 1949 | ] 1950 | 1951 | [[package]] 1952 | name = "stdweb-internal-runtime" 1953 | version = "0.1.5" 1954 | source = "registry+https://github.com/rust-lang/crates.io-index" 1955 | checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" 1956 | 1957 | [[package]] 1958 | name = "strsim" 1959 | version = "0.8.0" 1960 | source = "registry+https://github.com/rust-lang/crates.io-index" 1961 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1962 | 1963 | [[package]] 1964 | name = "structopt" 1965 | version = "0.3.15" 1966 | source = "registry+https://github.com/rust-lang/crates.io-index" 1967 | checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" 1968 | dependencies = [ 1969 | "clap", 1970 | "lazy_static", 1971 | "structopt-derive", 1972 | ] 1973 | 1974 | [[package]] 1975 | name = "structopt-derive" 1976 | version = "0.4.8" 1977 | source = "registry+https://github.com/rust-lang/crates.io-index" 1978 | checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" 1979 | dependencies = [ 1980 | "heck", 1981 | "proc-macro-error", 1982 | "proc-macro2", 1983 | "quote", 1984 | "syn", 1985 | ] 1986 | 1987 | [[package]] 1988 | name = "syn" 1989 | version = "1.0.30" 1990 | source = "registry+https://github.com/rust-lang/crates.io-index" 1991 | checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2" 1992 | dependencies = [ 1993 | "proc-macro2", 1994 | "quote", 1995 | "unicode-xid", 1996 | ] 1997 | 1998 | [[package]] 1999 | name = "syn-mid" 2000 | version = "0.5.0" 2001 | source = "registry+https://github.com/rust-lang/crates.io-index" 2002 | checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" 2003 | dependencies = [ 2004 | "proc-macro2", 2005 | "quote", 2006 | "syn", 2007 | ] 2008 | 2009 | [[package]] 2010 | name = "tch" 2011 | version = "0.5.0" 2012 | source = "registry+https://github.com/rust-lang/crates.io-index" 2013 | checksum = "f26115a35496899782cc16c8e5a51c9375e7f3c0e7dcafa9f1883338e938a04f" 2014 | dependencies = [ 2015 | "half", 2016 | "lazy_static", 2017 | "libc", 2018 | "ndarray", 2019 | "rand 0.8.4", 2020 | "thiserror", 2021 | "torch-sys", 2022 | "zip", 2023 | ] 2024 | 2025 | [[package]] 2026 | name = "termcolor" 2027 | version = "1.1.0" 2028 | source = "registry+https://github.com/rust-lang/crates.io-index" 2029 | checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" 2030 | dependencies = [ 2031 | "winapi-util", 2032 | ] 2033 | 2034 | [[package]] 2035 | name = "textwrap" 2036 | version = "0.11.0" 2037 | source = "registry+https://github.com/rust-lang/crates.io-index" 2038 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 2039 | dependencies = [ 2040 | "unicode-width", 2041 | ] 2042 | 2043 | [[package]] 2044 | name = "thiserror" 2045 | version = "1.0.20" 2046 | source = "registry+https://github.com/rust-lang/crates.io-index" 2047 | checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" 2048 | dependencies = [ 2049 | "thiserror-impl", 2050 | ] 2051 | 2052 | [[package]] 2053 | name = "thiserror-impl" 2054 | version = "1.0.20" 2055 | source = "registry+https://github.com/rust-lang/crates.io-index" 2056 | checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" 2057 | dependencies = [ 2058 | "proc-macro2", 2059 | "quote", 2060 | "syn", 2061 | ] 2062 | 2063 | [[package]] 2064 | name = "thread_local" 2065 | version = "1.0.1" 2066 | source = "registry+https://github.com/rust-lang/crates.io-index" 2067 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 2068 | dependencies = [ 2069 | "lazy_static", 2070 | ] 2071 | 2072 | [[package]] 2073 | name = "threadpool" 2074 | version = "1.8.1" 2075 | source = "registry+https://github.com/rust-lang/crates.io-index" 2076 | checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" 2077 | dependencies = [ 2078 | "num_cpus", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "tiff" 2083 | version = "0.5.0" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f" 2086 | dependencies = [ 2087 | "byteorder", 2088 | "lzw", 2089 | "miniz_oxide", 2090 | ] 2091 | 2092 | [[package]] 2093 | name = "time" 2094 | version = "0.1.43" 2095 | source = "registry+https://github.com/rust-lang/crates.io-index" 2096 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 2097 | dependencies = [ 2098 | "libc", 2099 | "winapi 0.3.8", 2100 | ] 2101 | 2102 | [[package]] 2103 | name = "time" 2104 | version = "0.2.19" 2105 | source = "registry+https://github.com/rust-lang/crates.io-index" 2106 | checksum = "80c1a1fd93112fc50b11c43a1def21f926be3c18884fad676ea879572da070a1" 2107 | dependencies = [ 2108 | "const_fn", 2109 | "libc", 2110 | "standback", 2111 | "stdweb", 2112 | "time-macros", 2113 | "version_check", 2114 | "winapi 0.3.8", 2115 | ] 2116 | 2117 | [[package]] 2118 | name = "time-macros" 2119 | version = "0.1.0" 2120 | source = "registry+https://github.com/rust-lang/crates.io-index" 2121 | checksum = "9ae9b6e9f095bc105e183e3cd493d72579be3181ad4004fceb01adbe9eecab2d" 2122 | dependencies = [ 2123 | "proc-macro-hack", 2124 | "time-macros-impl", 2125 | ] 2126 | 2127 | [[package]] 2128 | name = "time-macros-impl" 2129 | version = "0.1.1" 2130 | source = "registry+https://github.com/rust-lang/crates.io-index" 2131 | checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" 2132 | dependencies = [ 2133 | "proc-macro-hack", 2134 | "proc-macro2", 2135 | "quote", 2136 | "standback", 2137 | "syn", 2138 | ] 2139 | 2140 | [[package]] 2141 | name = "tinyvec" 2142 | version = "0.3.4" 2143 | source = "registry+https://github.com/rust-lang/crates.io-index" 2144 | checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" 2145 | 2146 | [[package]] 2147 | name = "tokio" 2148 | version = "0.2.21" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" 2151 | dependencies = [ 2152 | "bytes", 2153 | "futures-core", 2154 | "iovec", 2155 | "lazy_static", 2156 | "libc", 2157 | "memchr", 2158 | "mio", 2159 | "mio-uds", 2160 | "pin-project-lite", 2161 | "signal-hook-registry", 2162 | "slab", 2163 | "winapi 0.3.8", 2164 | ] 2165 | 2166 | [[package]] 2167 | name = "tokio-openssl" 2168 | version = "0.4.0" 2169 | source = "registry+https://github.com/rust-lang/crates.io-index" 2170 | checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594" 2171 | dependencies = [ 2172 | "openssl", 2173 | "tokio", 2174 | ] 2175 | 2176 | [[package]] 2177 | name = "tokio-util" 2178 | version = "0.2.0" 2179 | source = "registry+https://github.com/rust-lang/crates.io-index" 2180 | checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" 2181 | dependencies = [ 2182 | "bytes", 2183 | "futures-core", 2184 | "futures-sink", 2185 | "log", 2186 | "pin-project-lite", 2187 | "tokio", 2188 | ] 2189 | 2190 | [[package]] 2191 | name = "tokio-util" 2192 | version = "0.3.1" 2193 | source = "registry+https://github.com/rust-lang/crates.io-index" 2194 | checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" 2195 | dependencies = [ 2196 | "bytes", 2197 | "futures-core", 2198 | "futures-sink", 2199 | "log", 2200 | "pin-project-lite", 2201 | "tokio", 2202 | ] 2203 | 2204 | [[package]] 2205 | name = "torch-sys" 2206 | version = "0.5.0" 2207 | source = "registry+https://github.com/rust-lang/crates.io-index" 2208 | checksum = "88ade099a9f752b2e57c7852fe022e3542ec7e196675acbc9bb0d3a380e18c62" 2209 | dependencies = [ 2210 | "anyhow", 2211 | "cc", 2212 | "curl", 2213 | "libc", 2214 | "zip", 2215 | ] 2216 | 2217 | [[package]] 2218 | name = "trust-dns-proto" 2219 | version = "0.19.5" 2220 | source = "registry+https://github.com/rust-lang/crates.io-index" 2221 | checksum = "cdd7061ba6f4d4d9721afedffbfd403f20f39a4301fee1b70d6fcd09cca69f28" 2222 | dependencies = [ 2223 | "async-trait", 2224 | "backtrace", 2225 | "enum-as-inner", 2226 | "futures", 2227 | "idna", 2228 | "lazy_static", 2229 | "log", 2230 | "rand 0.7.3", 2231 | "smallvec", 2232 | "thiserror", 2233 | "tokio", 2234 | "url", 2235 | ] 2236 | 2237 | [[package]] 2238 | name = "trust-dns-resolver" 2239 | version = "0.19.5" 2240 | source = "registry+https://github.com/rust-lang/crates.io-index" 2241 | checksum = "0f23cdfdc3d8300b3c50c9e84302d3bd6d860fb9529af84ace6cf9665f181b77" 2242 | dependencies = [ 2243 | "backtrace", 2244 | "cfg-if 0.1.10", 2245 | "futures", 2246 | "ipconfig", 2247 | "lazy_static", 2248 | "log", 2249 | "lru-cache", 2250 | "resolv-conf", 2251 | "smallvec", 2252 | "thiserror", 2253 | "tokio", 2254 | "trust-dns-proto", 2255 | ] 2256 | 2257 | [[package]] 2258 | name = "typenum" 2259 | version = "1.12.0" 2260 | source = "registry+https://github.com/rust-lang/crates.io-index" 2261 | checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" 2262 | 2263 | [[package]] 2264 | name = "unicode-bidi" 2265 | version = "0.3.4" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 2268 | dependencies = [ 2269 | "matches", 2270 | ] 2271 | 2272 | [[package]] 2273 | name = "unicode-normalization" 2274 | version = "0.1.12" 2275 | source = "registry+https://github.com/rust-lang/crates.io-index" 2276 | checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" 2277 | dependencies = [ 2278 | "smallvec", 2279 | ] 2280 | 2281 | [[package]] 2282 | name = "unicode-segmentation" 2283 | version = "1.6.0" 2284 | source = "registry+https://github.com/rust-lang/crates.io-index" 2285 | checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 2286 | 2287 | [[package]] 2288 | name = "unicode-width" 2289 | version = "0.1.7" 2290 | source = "registry+https://github.com/rust-lang/crates.io-index" 2291 | checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" 2292 | 2293 | [[package]] 2294 | name = "unicode-xid" 2295 | version = "0.2.0" 2296 | source = "registry+https://github.com/rust-lang/crates.io-index" 2297 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 2298 | 2299 | [[package]] 2300 | name = "url" 2301 | version = "2.1.1" 2302 | source = "registry+https://github.com/rust-lang/crates.io-index" 2303 | checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" 2304 | dependencies = [ 2305 | "idna", 2306 | "matches", 2307 | "percent-encoding", 2308 | ] 2309 | 2310 | [[package]] 2311 | name = "vcpkg" 2312 | version = "0.2.9" 2313 | source = "registry+https://github.com/rust-lang/crates.io-index" 2314 | checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c" 2315 | 2316 | [[package]] 2317 | name = "vec_map" 2318 | version = "0.8.2" 2319 | source = "registry+https://github.com/rust-lang/crates.io-index" 2320 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 2321 | 2322 | [[package]] 2323 | name = "version_check" 2324 | version = "0.9.2" 2325 | source = "registry+https://github.com/rust-lang/crates.io-index" 2326 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 2327 | 2328 | [[package]] 2329 | name = "wasi" 2330 | version = "0.9.0+wasi-snapshot-preview1" 2331 | source = "registry+https://github.com/rust-lang/crates.io-index" 2332 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2333 | 2334 | [[package]] 2335 | name = "wasi" 2336 | version = "0.10.2+wasi-snapshot-preview1" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 2339 | 2340 | [[package]] 2341 | name = "wasm-bindgen" 2342 | version = "0.2.68" 2343 | source = "registry+https://github.com/rust-lang/crates.io-index" 2344 | checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" 2345 | dependencies = [ 2346 | "cfg-if 0.1.10", 2347 | "wasm-bindgen-macro", 2348 | ] 2349 | 2350 | [[package]] 2351 | name = "wasm-bindgen-backend" 2352 | version = "0.2.68" 2353 | source = "registry+https://github.com/rust-lang/crates.io-index" 2354 | checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" 2355 | dependencies = [ 2356 | "bumpalo", 2357 | "lazy_static", 2358 | "log", 2359 | "proc-macro2", 2360 | "quote", 2361 | "syn", 2362 | "wasm-bindgen-shared", 2363 | ] 2364 | 2365 | [[package]] 2366 | name = "wasm-bindgen-macro" 2367 | version = "0.2.68" 2368 | source = "registry+https://github.com/rust-lang/crates.io-index" 2369 | checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" 2370 | dependencies = [ 2371 | "quote", 2372 | "wasm-bindgen-macro-support", 2373 | ] 2374 | 2375 | [[package]] 2376 | name = "wasm-bindgen-macro-support" 2377 | version = "0.2.68" 2378 | source = "registry+https://github.com/rust-lang/crates.io-index" 2379 | checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" 2380 | dependencies = [ 2381 | "proc-macro2", 2382 | "quote", 2383 | "syn", 2384 | "wasm-bindgen-backend", 2385 | "wasm-bindgen-shared", 2386 | ] 2387 | 2388 | [[package]] 2389 | name = "wasm-bindgen-shared" 2390 | version = "0.2.68" 2391 | source = "registry+https://github.com/rust-lang/crates.io-index" 2392 | checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" 2393 | 2394 | [[package]] 2395 | name = "widestring" 2396 | version = "0.4.0" 2397 | source = "registry+https://github.com/rust-lang/crates.io-index" 2398 | checksum = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" 2399 | 2400 | [[package]] 2401 | name = "winapi" 2402 | version = "0.2.8" 2403 | source = "registry+https://github.com/rust-lang/crates.io-index" 2404 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 2405 | 2406 | [[package]] 2407 | name = "winapi" 2408 | version = "0.3.8" 2409 | source = "registry+https://github.com/rust-lang/crates.io-index" 2410 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 2411 | dependencies = [ 2412 | "winapi-i686-pc-windows-gnu", 2413 | "winapi-x86_64-pc-windows-gnu", 2414 | ] 2415 | 2416 | [[package]] 2417 | name = "winapi-build" 2418 | version = "0.1.1" 2419 | source = "registry+https://github.com/rust-lang/crates.io-index" 2420 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 2421 | 2422 | [[package]] 2423 | name = "winapi-i686-pc-windows-gnu" 2424 | version = "0.4.0" 2425 | source = "registry+https://github.com/rust-lang/crates.io-index" 2426 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2427 | 2428 | [[package]] 2429 | name = "winapi-util" 2430 | version = "0.1.5" 2431 | source = "registry+https://github.com/rust-lang/crates.io-index" 2432 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 2433 | dependencies = [ 2434 | "winapi 0.3.8", 2435 | ] 2436 | 2437 | [[package]] 2438 | name = "winapi-x86_64-pc-windows-gnu" 2439 | version = "0.4.0" 2440 | source = "registry+https://github.com/rust-lang/crates.io-index" 2441 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2442 | 2443 | [[package]] 2444 | name = "winreg" 2445 | version = "0.6.2" 2446 | source = "registry+https://github.com/rust-lang/crates.io-index" 2447 | checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" 2448 | dependencies = [ 2449 | "winapi 0.3.8", 2450 | ] 2451 | 2452 | [[package]] 2453 | name = "ws2_32-sys" 2454 | version = "0.2.1" 2455 | source = "registry+https://github.com/rust-lang/crates.io-index" 2456 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 2457 | dependencies = [ 2458 | "winapi 0.2.8", 2459 | "winapi-build", 2460 | ] 2461 | 2462 | [[package]] 2463 | name = "zip" 2464 | version = "0.5.6" 2465 | source = "registry+https://github.com/rust-lang/crates.io-index" 2466 | checksum = "58287c28d78507f5f91f2a4cf1e8310e2c76fd4c6932f93ac60fd1ceb402db7d" 2467 | dependencies = [ 2468 | "bzip2", 2469 | "crc32fast", 2470 | "flate2", 2471 | "podio", 2472 | "time 0.1.43", 2473 | ] 2474 | -------------------------------------------------------------------------------- /server/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "actix-torch-server" 3 | version = "0.1.0" 4 | authors = ["Kyle Kosic "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | actix-web = { version="3.0", features=["openssl"] } 9 | anyhow = "1.0" 10 | base64 = "0.12" 11 | env_logger = "0.7" 12 | image = "0.23" 13 | serde = { version = "1.0", features = ["derive"] } 14 | structopt = "0.3" 15 | tch = "0.5" 16 | 17 | -------------------------------------------------------------------------------- /server/src/main.rs: -------------------------------------------------------------------------------- 1 | mod mnist_model; 2 | use mnist_model::{MnistInput, MnistModel}; 3 | 4 | use std::path::PathBuf; 5 | use std::sync::Arc; 6 | 7 | use actix_web::{middleware, post, web, App, Error, HttpResponse, HttpServer}; 8 | use base64; 9 | use env_logger; 10 | use serde::Deserialize; 11 | use structopt::StructOpt; 12 | 13 | #[derive(Debug, StructOpt)] 14 | struct Opt { 15 | /// Path to saved Torch jit model is saved 16 | #[structopt(short, long, parse(from_os_str))] 17 | model_path: PathBuf, 18 | /// Port to serve on 19 | #[structopt(short, long, default_value = "8080")] 20 | port: u32, 21 | } 22 | 23 | #[derive(Debug, Deserialize)] 24 | struct MnistRequest { 25 | // Base64 encoded image PNG/JPG 26 | image: String, 27 | } 28 | 29 | #[post("/mnist")] 30 | async fn predict_mnist( 31 | model: web::Data>, 32 | data: web::Json, 33 | ) -> Result { 34 | let res = web::block(move || { 35 | let image_bytes = base64::decode(&data.image)?; 36 | let input = MnistInput::from_image_bytes(image_bytes)?; 37 | model.predict(input) 38 | }) 39 | .await 40 | .map_err(|e| HttpResponse::InternalServerError().body(e.to_string()))?; 41 | Ok(HttpResponse::Ok() 42 | .content_type("application/json") 43 | .json(res)) 44 | } 45 | 46 | #[actix_web::main] 47 | async fn main() -> std::io::Result<()> { 48 | let opt = Opt::from_args(); 49 | std::env::set_var("RUST_LOG", "actix_web=info"); 50 | env_logger::init(); 51 | 52 | println!("Loading saved model from {}", opt.model_path.display()); 53 | let model = Arc::new({ 54 | MnistModel::from_file(&opt.model_path) 55 | .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))? 56 | }); 57 | 58 | let endpoint = format!("0.0.0.0:{}", opt.port); 59 | println!("Running server at {}", endpoint); 60 | HttpServer::new(move || { 61 | App::new() 62 | .wrap(middleware::Logger::default()) 63 | .data(model.clone()) 64 | .service(predict_mnist) 65 | }) 66 | .bind(endpoint)? 67 | .run() 68 | .await 69 | } 70 | -------------------------------------------------------------------------------- /server/src/mnist_model.rs: -------------------------------------------------------------------------------- 1 | use std::convert::TryFrom; 2 | use std::path::Path; 3 | 4 | use anyhow::Result; 5 | use image::{self, imageops::FilterType}; 6 | use serde::Serialize; 7 | use tch::{CModule, Kind, TchError, Tensor}; 8 | 9 | #[derive(Debug)] 10 | pub struct MnistInput(Vec); 11 | 12 | impl MnistInput { 13 | pub fn from_image_bytes(bytes: Vec) -> Result { 14 | const NORM_SCALE: f32 = 1. / 255.; 15 | let im = image::load_from_memory(&bytes)? 16 | .resize_exact(28, 28, FilterType::Nearest) 17 | .grayscale() 18 | .to_bytes() 19 | .into_iter() 20 | .map(|x| (x as f32) * NORM_SCALE) 21 | .collect::>(); 22 | Ok(Self(im)) 23 | } 24 | } 25 | 26 | impl TryFrom for Tensor { 27 | type Error = TchError; 28 | 29 | fn try_from(value: MnistInput) -> Result { 30 | Tensor::f_of_slice(&value.0)?.f_reshape(&[1, 1, 28, 28]) 31 | } 32 | } 33 | 34 | #[derive(Debug, Serialize)] 35 | pub struct MnistPrediction { 36 | pub label: u8, 37 | pub confidence: f64, 38 | } 39 | 40 | pub struct MnistModel { 41 | model: CModule, 42 | } 43 | 44 | impl MnistModel { 45 | pub fn from_file(path: impl AsRef) -> Result { 46 | let model = CModule::load(path)?; 47 | Ok(Self { model }) 48 | } 49 | 50 | pub fn predict(&self, image: MnistInput) -> Result { 51 | let tensor = Tensor::try_from(image)?; 52 | let output: Vec = self 53 | .model 54 | .forward_ts(&[tensor])? 55 | .softmax(-1, Kind::Double) 56 | .into(); 57 | 58 | let mut confidence = 0f64; 59 | let mut label = 0u8; 60 | for (i, prob) in output.into_iter().enumerate() { 61 | if prob > confidence { 62 | confidence = prob; 63 | label = i as u8; 64 | } 65 | } 66 | 67 | Ok(MnistPrediction { label, confidence }) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /training/train.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | Script which runs the training procedure 4 | """ 5 | import argparse 6 | import os 7 | 8 | import torch 9 | import torch.nn as nn 10 | import torch.nn.functional as F 11 | import torch.optim as optim 12 | from torchvision import datasets, transforms 13 | from torch.utils.data import DataLoader 14 | 15 | 16 | SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 17 | REPO_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "..")) 18 | 19 | 20 | class Net(nn.Module): 21 | def __init__(self): 22 | super().__init__() 23 | self.conv1 = nn.Conv2d(1, 64, 3) 24 | self.conv2 = nn.Conv2d(64, 16, 3) 25 | self.conv3 = nn.Conv2d(16, 16, 3) 26 | self.fc = nn.Linear(7744, 10) 27 | 28 | def forward(self, x): 29 | x = self.conv1(x) 30 | x = F.relu(x) 31 | x = self.conv2(x) 32 | x = F.relu(x) 33 | x = self.conv3(x) 34 | x = F.relu(x) 35 | x = torch.flatten(x, 1) 36 | x = self.fc(x) 37 | return F.log_softmax(x, dim=1) 38 | 39 | 40 | def train( 41 | model: nn.Module, 42 | device: torch.device, 43 | train_loader: DataLoader, 44 | optimizer: optim.Optimizer, 45 | epoch: int, 46 | ): 47 | model.train() 48 | for batch_idx, (data, target) in enumerate(train_loader): 49 | data, target = data.to(device), target.to(device) 50 | optimizer.zero_grad() 51 | output = model(data) 52 | loss = F.nll_loss(output, target) 53 | loss.backward() 54 | optimizer.step() 55 | if batch_idx % 10 == 0: 56 | progress = batch_idx / len(train_loader) * 100 57 | print( 58 | f"Train epoch {epoch} progress: {progress:.2f}% " 59 | f"Loss: {loss.item():.6f}" 60 | ) 61 | 62 | 63 | def test(model: nn.Module, device: torch.device, test_loader: DataLoader): 64 | model.eval() 65 | test_loss = 0 66 | correct = 0 67 | with torch.no_grad(): 68 | for data, target in test_loader: 69 | data, target = data.to(device), target.to(device) 70 | output = model(data) 71 | test_loss += F.nll_loss(output, target, reduction="sum").item() 72 | pred = output.argmax(dim=1, keepdim=True) 73 | correct += pred.eq(target.view_as(pred)).sum().item() 74 | 75 | test_loss /= len(test_loader.dataset) 76 | accuracy = correct / len(test_loader.dataset) * 100 77 | print(f"Test average loss: {test_loss:.6f} Accuracy: {accuracy:.2f}%") 78 | 79 | 80 | def parse_args() -> argparse.Namespace: 81 | parser = argparse.ArgumentParser() 82 | parser.add_argument( 83 | "--batch_size", 84 | type=int, 85 | help="Size of training batches", 86 | default=64, 87 | ) 88 | parser.add_argument( 89 | "--epochs", 90 | type=int, 91 | help="Number of training epochs", 92 | default=2, 93 | ) 94 | parser.add_argument( 95 | "--learning-rate", 96 | type=float, 97 | help="Initial learning rate for training", 98 | default=5e-4, 99 | ) 100 | parser.add_argument( 101 | "--output-path", 102 | type=str, 103 | help="Path to save trained model", 104 | default=os.path.join(REPO_DIR, "saved_model", "model.pt"), 105 | ) 106 | parser.add_argument( 107 | "--data-path", 108 | type=str, 109 | help="Path to download training data", 110 | default=os.path.join(REPO_DIR, "data"), 111 | ) 112 | parser.add_argument( 113 | "--no-cuda", 114 | action="store_true", 115 | help="Disable CUDA training", 116 | ) 117 | parser.add_argument( 118 | "--seed", 119 | type=int, 120 | help="Random seed for training", 121 | default=0, 122 | ) 123 | return parser.parse_args() 124 | 125 | 126 | def main(args: argparse.Namespace): 127 | use_cuda = torch.cuda.is_available() and not args.no_cuda 128 | torch.manual_seed(args.seed) 129 | 130 | train_kwargs = {"batch_size": args.batch_size} 131 | test_kwargs = {"batch_size": 500} 132 | if use_cuda: 133 | kwargs = { 134 | "num_workers": 1, 135 | "pin_memory": True, 136 | "shuffle": True, 137 | } 138 | train_kwargs.update(kwargs) 139 | test_kwargs.update(kwargs) 140 | 141 | transform = transforms.Compose( 142 | [transforms.ToTensor(), transforms.Normalize((0.1308,), (0.3081,))] 143 | ) 144 | train_ds = datasets.MNIST( 145 | args.data_path, train=True, download=True, transform=transform 146 | ) 147 | test_ds = datasets.MNIST( 148 | args.data_path, train=False, download=True, transform=transform 149 | ) 150 | train_loader = DataLoader(train_ds, **train_kwargs) 151 | test_loader = DataLoader(test_ds, **test_kwargs) 152 | 153 | device = torch.device("cuda" if use_cuda else "cpu") 154 | model = Net().to(device) 155 | optimizer = optim.Adam(model.parameters(), lr=args.learning_rate) 156 | 157 | for epoch in range(args.epochs): 158 | train(model, device, train_loader, optimizer, epoch) 159 | test(model, device, test_loader) 160 | 161 | model.eval() 162 | script_module = torch.jit.script(model) 163 | script_module.save(args.output_path) 164 | print(f"Model saved to {args.output_path}") 165 | 166 | 167 | if __name__ == "__main__": 168 | main(parse_args()) 169 | --------------------------------------------------------------------------------