diff --git a/.env.sample b/.env.sample index 1e54855..7a1a670 100644 --- a/.env.sample +++ b/.env.sample @@ -2,6 +2,7 @@ RUST_LOG=api=trace SIRENE_ENV=development HOST=localhost PORT=3000 +API_KEY= DATABASE_URL=postgresql://sirene:sirenepw@127.0.0.1:5432/sirene TEMP_FOLDER=./data/temp FILE_FOLDER=./data/files diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..9ab22a5 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,25 @@ +name: Rust + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + - name: Install minimal nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + profile: minimal + override: true + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + - name: Run tests + uses: actions-rs/cargo@v1 + with: + command: test diff --git a/Cargo.lock b/Cargo.lock index 72cc274..2834d43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,2010 +4,1948 @@ name = "adler32" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "anyhow" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" [[package]] name = "atty" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", + "winapi 0.3.8", ] [[package]] name = "autocfg" -version = "0.1.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "base64" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "safemem", ] [[package]] name = "base64" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", ] [[package]] name = "base64" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "bitflags" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bumpalo" -version = "3.1.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" [[package]] name = "byteorder" -version = "1.3.2" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "bytes" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" [[package]] name = "bzip2" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" dependencies = [ - "bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "bzip2-sys", + "libc", ] [[package]] name = "bzip2-sys" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6584aa36f5ad4c9247f5323b0a42f37802b37a836f0ad87084d7a33961abe25f" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", ] [[package]] name = "c2-chacha" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", ] [[package]] name = "cc" -version = "1.0.45" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" dependencies = [ - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits", + "serde", + "time", ] [[package]] name = "clap" version = "3.0.0-beta.1" -source = "git+https://github.com/clap-rs/clap.git#af454200275040e18667d2756266d52ae3cd2473" +source = "git+https://github.com/clap-rs/clap.git#e4a7f5012855e9dd906caaa7028393cf1926da8e" dependencies = [ - "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap_derive 0.3.0 (git+https://github.com/clap-rs/clap_derive)", - "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term", + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "strsim", + "textwrap", + "unicode-width", + "vec_map", ] [[package]] name = "clap_derive" -version = "0.3.0" -source = "git+https://github.com/clap-rs/clap_derive#0352bb30c897b00af88ad240e8e6f4aaf1855d05" +version = "3.0.0-beta.1" +source = "git+https://github.com/clap-rs/clap.git#e4a7f5012855e9dd906caaa7028393cf1926da8e" dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-error 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro-error", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "cookie" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fac5e7bdefb6160fb181ee0eaa6f96704b625c70e6d61c465cb35750a4ea12" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.9.3", + "ring", + "time", + "url 1.7.2", ] [[package]] name = "core-foundation" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys", + "libc", ] [[package]] name = "core-foundation-sys" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" [[package]] name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "custom_error" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a0fc65739ae998afc8d68e64bdac2efd1bc4ffa1a0703d171ef2defae3792f" [[package]] name = "devise" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3" dependencies = [ - "devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "devise_codegen", + "devise_core", ] [[package]] name = "devise_codegen" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7" dependencies = [ - "devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "devise_core", + "quote 0.6.13", ] [[package]] name = "devise_core" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", ] [[package]] name = "diesel" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7cc03b910de9935007861dce440881f69102aaaedfd4bc5a6f40340ca5840c" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "byteorder", + "chrono", + "diesel_derives", + "pq-sys", + "r2d2", + "serde_json", ] [[package]] name = "diesel_derives" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "diesel_migrations" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" dependencies = [ - "migrations_internals 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "migrations_macros 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "migrations_internals", + "migrations_macros", ] [[package]] name = "dotenv" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "dtoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" [[package]] name = "encoding_rs" -version = "0.8.20" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "filetime" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff6d4dab0aa0c8e6346d46052e93b13a16cf847b54ed357087c35011048cc7d" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.8", ] [[package]] name = "flate2" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", ] [[package]] name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fsevent" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fsevent-sys", ] [[package]] name = "fsevent-sys" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures-channel" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", ] [[package]] name = "futures-core" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" [[package]] name = "futures-io" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" [[package]] name = "futures-sink" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" [[package]] name = "futures-task" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" [[package]] name = "futures-util" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-io", + "futures-task", + "memchr", + "pin-utils", + "slab", ] [[package]] name = "getrandom" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", ] [[package]] name = "h2" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "log 0.4.8", + "slab", + "tokio", + "tokio-util", ] [[package]] name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" dependencies = [ - "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c55f143919fbc0bc77e427fe2d74cf23786d7c1875666f2fde3ac3c659bb67" +dependencies = [ + "libc", ] [[package]] name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "fnv", + "itoa", ] [[package]] name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "http", ] [[package]] name = "httparse" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" [[package]] name = "hyper" version = "0.10.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.9.3", + "httparse", + "language-tags", + "log 0.3.9", + "mime 0.2.6", + "num_cpus", + "time", + "traitobject", + "typeable", + "unicase 1.4.2", + "url 1.7.2", ] [[package]] name = "hyper" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "log 0.4.8", + "net2", + "pin-project", + "time", + "tokio", + "tower-service", + "want", ] [[package]] name = "hyper-tls" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "hyper 0.13.2", + "native-tls", + "tokio", + "tokio-tls", ] [[package]] name = "idna" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "idna" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.2.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" +dependencies = [ + "autocfg", +] [[package]] name = "inotify" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "inotify-sys", + "libc", ] [[package]] name = "inotify-sys" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" [[package]] name = "js-sys" version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" dependencies = [ - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "language-tags" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.62" +version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" [[package]] name = "lock_api" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" dependencies = [ - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard", ] [[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", ] [[package]] name = "log" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "matches" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" -version = "2.2.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53445de381a1f436797497c61d851644d0e8e88e6140f22872ad33a704933978" [[package]] name = "migrations_internals" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8089920229070f914b9ce9b07ef60e175b2b9bc2d35c3edd8bf4433604e863b9" dependencies = [ - "diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel", ] [[package]] name = "migrations_macros" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719ef0bc7f531428764c9b70661c14abd50a7f3d21f355752d9985aa21251c9e" dependencies = [ - "migrations_internals 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "migrations_internals", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "mime" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9", ] [[package]] name = "mime" -version = "0.3.14" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mime_guess" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" dependencies = [ - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.16", + "unicase 2.6.0", ] [[package]] name = "miniz_oxide" -version = "0.3.2" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" dependencies = [ - "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32", ] [[package]] name = "mio" version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log 0.4.8", + "miow", + "net2", + "slab", + "winapi 0.2.8", ] [[package]] name = "mio-extras" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell", + "log 0.4.8", + "mio", + "slab", ] [[package]] name = "miow" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", ] [[package]] name = "native-tls" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "libc", + "log 0.4.8", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "winapi 0.3.8", ] [[package]] name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", + "version_check 0.1.5", ] [[package]] name = "notify" -version = "4.0.13" +version = "4.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio", + "mio-extras", + "walkdir", + "winapi 0.3.8", ] [[package]] name = "num-integer" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" dependencies = [ - "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", ] [[package]] name = "num-traits" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ - "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "num_cpus" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "openssl" -version = "0.10.26" +version = "0.10.28" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52" dependencies = [ - "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cfg-if", + "foreign-types", + "lazy_static", + "libc", + "openssl-sys", ] [[package]] name = "openssl-probe" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-sys" -version = "0.9.53" +version = "0.9.54" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" dependencies = [ - "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] name = "parking_lot" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" dependencies = [ - "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api", + "parking_lot_core", ] [[package]] name = "parking_lot_core" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec 1.2.0", + "winapi 0.3.8", ] [[package]] name = "pear" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25" dependencies = [ - "pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pear_codegen", ] [[package]] name = "pear_codegen" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", + "version_check 0.1.5", + "yansi 0.4.0", ] [[package]] name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" dependencies = [ - "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "pin-project-lite" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" [[package]] name = "pin-utils" version = "0.1.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" [[package]] name = "pkg-config" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] name = "podio" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" [[package]] name = "ppv-lite86" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "pq-sys" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" dependencies = [ - "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg", ] [[package]] name = "proc-macro-error" -version = "0.4.4" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" dependencies = [ - "proc-macro-error-attr 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error-attr", + "proc-macro2 1.0.8", + "quote 1.0.2", + "rustversion", + "syn 1.0.14", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.3" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "rustversion", + "syn 1.0.14", + "syn-mid", ] [[package]] name = "proc-macro2" version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0", ] [[package]] name = "proc-macro2" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0", ] -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30", ] [[package]] name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", ] [[package]] name = "r2d2" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1497e40855348e4a8a40767d8e55174bce1e445a3ac9254ad44ad468ee0485af" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "parking_lot", + "scheduled-thread-pool", ] [[package]] name = "rand" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] name = "rand_chacha" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" dependencies = [ - "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha", + "rand_core", ] [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core", ] [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "remove_dir_all" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "reqwest" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae3fc32eacd4a5200c6b34bd6c057b07fb64f5a1e55bb67d624cc1393354621" +dependencies = [ + "base64 0.11.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper 0.13.2", + "hyper-tls", + "js-sys", + "lazy_static", + "log 0.4.8", + "mime 0.3.16", + "mime_guess", + "native-tls", + "percent-encoding 2.1.0", + "pin-project-lite", + "serde", + "serde_urlencoded", + "time", + "tokio", + "tokio-tls", + "url 2.1.1", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", ] [[package]] name = "ring" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" dependencies = [ - "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "lazy_static", + "libc", + "untrusted", ] [[package]] name = "rocket" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42c1e9deb3ef4fa430d307bfccd4231434b707ca1328fae339c43ad1201cc6f7" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "base64 0.10.1", + "log 0.4.8", + "memchr", + "num_cpus", + "pear", + "rocket_codegen", + "rocket_http", + "state", + "time", + "toml", + "version_check 0.9.1", + "yansi 0.5.0", ] [[package]] name = "rocket_codegen" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4" dependencies = [ - "devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "devise", + "indexmap", + "quote 0.6.13", + "rocket_http", + "version_check 0.9.1", + "yansi 0.5.0", ] [[package]] name = "rocket_contrib" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "notify 4.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "notify", + "rocket", + "serde", + "serde_json", ] [[package]] name = "rocket_http" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817" dependencies = [ - "cookie 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie", + "hyper 0.10.16", + "indexmap", + "pear", + "percent-encoding 1.0.1", + "smallvec 0.6.13", + "state", + "time", + "unicode-xid 0.1.0", ] [[package]] name = "rustversion" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "ryu" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" [[package]] name = "safemem" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" [[package]] name = "same-file" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "schannel" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "winapi 0.3.8", ] [[package]] name = "scheduled-thread-pool" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5de7bc31f28f8e6c28df5e1bf3d10610f5fdc14cc95f272853512c70a2bd779" dependencies = [ - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot", ] [[package]] name = "scopeguard" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "security-framework" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" dependencies = [ - "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", ] [[package]] name = "security-framework-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver" -version = "0.9.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" dependencies = [ - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "serde_json" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] name = "serde_urlencoded" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa", + "itoa", + "serde", + "url 2.1.1", ] [[package]] name = "sirene" version = "1.0.3" dependencies = [ - "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 3.0.0-beta.1 (git+https://github.com/clap-rs/clap.git)", - "custom_error 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)", - "r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "zip 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "clap", + "custom_error", + "diesel", + "diesel_migrations", + "dotenv", + "openssl", + "r2d2", + "reqwest", + "rocket", + "rocket_contrib", + "serde", + "serde_json", + "zip", ] [[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" -version = "0.6.10" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" +dependencies = [ + "maybe-uninit", +] [[package]] name = "smallvec" -version = "1.0.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" [[package]] name = "sourcefile" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" [[package]] name = "state" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" [[package]] name = "strsim" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "syn" -version = "0.11.11" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" [[package]] name = "syn" version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", ] [[package]] name = "syn" -version = "1.0.5" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "unicode-xid 0.2.0", ] [[package]] name = "syn-mid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synom" -version = "0.11.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", ] [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.8", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_syscall", + "winapi 0.3.8", ] [[package]] name = "tokio" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "fnv", + "iovec", + "lazy_static", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "slab", ] [[package]] name = "tokio-tls" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bde02a3a5291395f59b06ec6945a3077602fac2b07eeeaf0dee2122f3619828" dependencies = [ - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", + "tokio", ] [[package]] name = "tokio-util" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures-core", + "futures-sink", + "log 0.4.8", + "pin-project-lite", + "tokio", ] [[package]] name = "toml" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "tower-service" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" [[package]] name = "try-lock" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "typeable" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" [[package]] name = "unicase" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5", ] [[package]] name = "unicase" -version = "2.5.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.9.1", ] [[package]] name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", ] [[package]] name = "unicode-normalization" -version = "0.1.8" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" dependencies = [ - "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0", ] [[package]] name = "unicode-segmentation" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" [[package]] name = "unicode-width" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-xid" -version = "0.0.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "untrusted" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" [[package]] name = "url" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", ] [[package]] name = "url" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.2.0", + "matches", + "percent-encoding 2.1.0", ] [[package]] name = "vcpkg" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" [[package]] name = "version_check" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" [[package]] name = "walkdir" -version = "2.2.9" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" dependencies = [ - "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file", + "winapi 0.3.8", + "winapi-util", ] [[package]] name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "try-lock", ] [[package]] name = "wasi" -version = "0.7.0" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" dependencies = [ - "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo", + "lazy_static", + "log 0.4.8", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2", + "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" [[package]] name = "wasm-bindgen-webidl" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" dependencies = [ - "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "heck", + "log 0.4.8", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn 1.0.14", + "wasm-bindgen-backend", + "weedle", ] [[package]] name = "web-sys" version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" dependencies = [ - "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "js-sys", + "sourcefile", + "wasm-bindgen", + "wasm-bindgen-webidl", ] [[package]] name = "weedle" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nom", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winreg" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "ws2_32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "yansi" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48" [[package]] name = "yansi" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" [[package]] name = "zip" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e41ff37ba788e2169b19fa70253b70cb53d9f2db9fb9aea9bcfc5047e02c3bae" dependencies = [ - "bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" -"checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" -"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" -"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" -"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" -"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" -"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" -"checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" -"checksum bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6584aa36f5ad4c9247f5323b0a42f37802b37a836f0ad87084d7a33961abe25f" -"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" -"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" -"checksum clap 3.0.0-beta.1 (git+https://github.com/clap-rs/clap.git)" = "" -"checksum clap_derive 0.3.0 (git+https://github.com/clap-rs/clap_derive)" = "" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cookie 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "99be24cfcf40d56ed37fd11c2123be833959bbc5bddecb46e1c2e442e15fa3e0" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -"checksum custom_error 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93a0fc65739ae998afc8d68e64bdac2efd1bc4ffa1a0703d171ef2defae3792f" -"checksum devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3" -"checksum devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7" -"checksum devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487" -"checksum diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7cc03b910de9935007861dce440881f69102aaaedfd4bc5a6f40340ca5840c" -"checksum diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62a27666098617d52c487a41f70de23d44a1dc1f3aa5877ceba2790fb1f1cab4" -"checksum diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" -"checksum dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" -"checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" -"checksum filetime 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd7380b54ced79dda72ecc35cc4fbbd1da6bba54afaa37e96fd1c2a308cd469" -"checksum flate2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ad3c5233c9a940c8719031b423d7e6c16af66e031cb0420b0896f5245bf181d3" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" -"checksum fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" -"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" -"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" -"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" -"checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" -"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" -"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" -"checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" -"checksum hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf49cfb32edee45d890537d9057d1b02ed55f53b7b6a30bae83a38c9231749e" -"checksum hyper-tls 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum indexmap 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a61202fbe46c4a951e9404a720a0180bcf3212c750d735cb5c4ba4dc551299f3" -"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" -"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" -"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" -"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" -"checksum migrations_internals 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8089920229070f914b9ce9b07ef60e175b2b9bc2d35c3edd8bf4433604e863b9" -"checksum migrations_macros 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1664412abf7db2b8a6d58be42a38b099780cc542b5b350383b805d88932833fe" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" -"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" -"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10" -"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" -"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" -"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum notify 4.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1191efa2b8fe041decb55c238a125b7a1aeb6fad7a525133a02be5ec949ff3cb" -"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" -"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" -"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" -"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" -"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" -"checksum pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25" -"checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" -"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" -"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422" -"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" -"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" -"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" -"checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" -"checksum proc-macro-error 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53c98547ceaea14eeb26fcadf51dc70d01a2479a7839170eae133721105e4428" -"checksum proc-macro-error-attr 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c2bf5d493cf5d3e296beccfd61794e445e830dfc8070a9c248ad3ee071392c6c" -"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1497e40855348e4a8a40767d8e55174bce1e445a3ac9254ad44ad468ee0485af" -"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0e798e19e258bf6c30a304622e3e9ac820e483b06a1857a026e1f109b113fe4" -"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" -"checksum rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "42c1e9deb3ef4fa430d307bfccd4231434b707ca1328fae339c43ad1201cc6f7" -"checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4" -"checksum rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f" -"checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustversion 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0538bd897e17257b0128d2fd95c2ed6df939374073a36166051a79e2eb7986" -"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" -"checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0" -"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" -"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" -"checksum scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd07742e081ff6c077f5f6b283f12f32b9e7cc765b316160d66289b74546fbb3" -"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" -"checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2" -"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" -"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" -"checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" -"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" -"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" -"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" -"checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" -"checksum strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "032c03039aae92b350aad2e3779c352e104d919cb192ba2fabbd7b831ce4f0f6" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" -"checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa2fdcfa937b20cb3c822a635ceecd5fc1a27a6a474527e5516aa24b8c8820a" -"checksum tokio-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bde02a3a5291395f59b06ec6945a3077602fac2b07eeeaf0dee2122f3619828" -"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" -"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" -"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" -"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" -"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" -"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" -"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" -"checksum wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" -"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" -"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" -"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" -"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" -"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" -"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48" -"checksum yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" -"checksum zip 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e41ff37ba788e2169b19fa70253b70cb53d9f2db9fb9aea9bcfc5047e02c3bae" + "bzip2", + "crc32fast", + "flate2", + "podio", + "time", +] diff --git a/Cargo.toml b/Cargo.toml index ab1cbc6..80e28c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" chrono = { version = "0.4", features = ["serde"] } clap = { git = "https://github.com/clap-rs/clap.git" } custom_error = "1.7" -diesel = { version = "1.4", features = ["postgres", "chrono", "r2d2", "64-column-tables"] } +diesel = { version = "1.4", features = ["postgres", "chrono", "r2d2", "serde_json", "64-column-tables"] } diesel_migrations = { version = "1.4", features = ["postgres"] } dotenv = "0.15" openssl = "0.10" diff --git a/README.md b/README.md index 37ae2a1..cd28695 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,103 @@ createuser --pwprompt sirene # set password to sirenepw for instance createdb --owner=sirene sirene ``` -### Usage +## Documentation + +### CLI + +**> sirene** + +``` +> sirene -h + +USAGE: + sirene [OPTIONS] + +FLAGS: + -h, --help Prints help information + -V, --version Prints version information + +OPTIONS: + --db-folder Path to the file storage folder for the database, you can set in environment + variable as DB_FOLDER Could be the same as FILE_FOLDER if this app and the + database are on the same file system Files copied by this app inside FILE_FOLDER + must be visible by the database in DB_FOLDER + --file-folder Path to the file storage folder for this app, you can set in environment variable + as FILE_FOLDER + --temp-folder Path to the temp folder, you can set in environment variable as TEMP_FOLDER + +SUBCOMMANDS: + help Prints this message or the help of the given subcommand(s) + serve Serve data from database to /unites_legales/ and /etablissements/ + update Update data from CSV source files +``` + +**> sirene serve --help** + +``` +USAGE: + sirene serve [OPTIONS] + +FLAGS: + --help Prints help information + -V, --version Prints version information + +OPTIONS: + -k, --api-key API key needed to allow maintenance operation from HTTP, you can set in environment + variable as API_KEY + --env Production, Staging or Development, will change log level, you can set in environment + variable as SIRENE_ENV + -h, --host Listen this host, you can set in environment variable as HOST + -p, --port Listen this port, you can set in environment variable as PORT +``` + +**> sirene update --help** + +``` +USAGE: + sirene update [FLAGS] [SUBCOMMAND] + +ARGS: + Configure which part will be updated, UnitesLegales, Etablissements or All + +FLAGS: + --data-only Use an existing CSV file already present in FILE_FOLDER and does not delete it + --force Force update even if the source data where not updated + -h, --help Prints help information + -V, --version Prints version information + +SUBCOMMANDS: + clean-file Clean files from FILE_FOLDER + download-file Download file in TEMP_FOLDER + help Prints this message or the help of the given subcommand(s) + insert-data Load CSV file in database in loader-table from DB_FOLDER + swap-data Swap loader-table to production + unzip-file Unzip file from TEMP_FOLDER, and move it to the FILE_FOLDER +``` + +### HTTP API + +``` +GET /v3/unites_legales/ +GET /v3/etablissements/ +``` + +**Maintenance** + +_This API is enabled only if you have provided an API_KEY when starting the `serve` process._ + +``` +POST /admin/update + +{ + api_key: string, + group_type: "UnitesLegales" | "Etablissements" | "All", + force: bool, + data_only: bool, +} +``` + +### Basic usage Serve: diff --git a/docker-compose.yml b/docker-compose.yml index 5734996..fe48a3a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: - "3000:3000" environment: - RUST_LOG=${RUST_LOG} + - API_KEY=${API_KEY} - SIRENE_ENV=${SIRENE_ENV} - DATABASE_URL=${DATABASE_URL} - TEMP_FOLDER=/app/data/temp diff --git a/migrations/2020-01-17-172431_create_update_metadata/down.sql b/migrations/2020-01-17-172431_create_update_metadata/down.sql new file mode 100644 index 0000000..df39a76 --- /dev/null +++ b/migrations/2020-01-17-172431_create_update_metadata/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."update_metadata"; diff --git a/migrations/2020-01-17-172431_create_update_metadata/up.sql b/migrations/2020-01-17-172431_create_update_metadata/up.sql new file mode 100644 index 0000000..291807c --- /dev/null +++ b/migrations/2020-01-17-172431_create_update_metadata/up.sql @@ -0,0 +1,17 @@ +CREATE TABLE "public"."update_metadata" +( + "id" serial, + "synthetic_group_type" text NOT NULL, + "force" boolean NOT NULL, + "data_only" boolean NOT NULL, + "status" text NOT NULL DEFAULT 'launched', + "summary" jsonb, + "error" text, + "launched_timestamp" timestamptz NOT NULL, + "finished_timestamp" timestamptz, + "created_at" timestamptz NOT NULL DEFAULT NOW(), + "updated_at" timestamptz NOT NULL DEFAULT NOW(), + PRIMARY KEY ("id") +); + +SELECT diesel_manage_updated_at('update_metadata'); diff --git a/src/commands/common.rs b/src/commands/common.rs new file mode 100644 index 0000000..cfcef5f --- /dev/null +++ b/src/commands/common.rs @@ -0,0 +1,27 @@ +use crate::models::update_metadata::common::SyntheticGroupType; +use serde::Deserialize; + +pub struct FolderOptions { + pub temp: String, + pub file: String, + pub db: String, +} + +arg_enum! { + #[derive(Debug, Deserialize, Clone, Copy)] + pub enum CmdGroupType { + UnitesLegales, + Etablissements, + All + } +} + +impl From for SyntheticGroupType { + fn from(group: CmdGroupType) -> Self { + match group { + CmdGroupType::UnitesLegales => SyntheticGroupType::UnitesLegales, + CmdGroupType::Etablissements => SyntheticGroupType::Etablissements, + CmdGroupType::All => SyntheticGroupType::All, + } + } +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index f2bca6e..f472294 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,8 +1,12 @@ +mod common; mod serve; mod update; use crate::connectors::ConnectorsBuilders; +use clap::Clap; +use common::FolderOptions; use serve::ServeFlags; +use std::env; use update::UpdateFlags; /// Sirene service used to update data in database @@ -10,6 +14,20 @@ use update::UpdateFlags; #[derive(Clap, Debug)] #[clap(version = "1.0.0", author = "Julien Blatecky")] struct Opts { + /// Path to the temp folder, you can set in environment variable as TEMP_FOLDER + #[clap(long = "temp-folder")] + temp_folder: Option, + + /// Path to the file storage folder for this app, you can set in environment variable as FILE_FOLDER + #[clap(long = "file-folder")] + file_folder: Option, + + /// Path to the file storage folder for the database, you can set in environment variable as DB_FOLDER + /// Could be the same as FILE_FOLDER if this app and the database are on the same file system + /// Files copied by this app inside FILE_FOLDER must be visible by the database in DB_FOLDER + #[clap(long = "db-folder")] + db_folder: Option, + #[clap(subcommand)] main_command: MainCommand, } @@ -28,8 +46,26 @@ enum MainCommand { pub fn run(builders: ConnectorsBuilders) { let opts = Opts::parse(); + let temp_folder = opts + .temp_folder + .unwrap_or_else(|| env::var("TEMP_FOLDER").unwrap_or(String::from("./data/temp"))); + + let file_folder = opts + .file_folder + .unwrap_or_else(|| env::var("FILE_FOLDER").unwrap_or(String::from("./data/files"))); + + let db_folder = opts + .db_folder + .unwrap_or_else(|| env::var("DB_FOLDER").unwrap_or(file_folder.clone())); + + let folder_options = FolderOptions { + temp: temp_folder, + file: file_folder, + db: db_folder, + }; + match opts.main_command { - MainCommand::Update(update_flags) => update::run(update_flags, builders), - MainCommand::Serve(serve_flags) => serve::run(serve_flags, builders), + MainCommand::Update(update_flags) => update::run(update_flags, folder_options, builders), + MainCommand::Serve(serve_flags) => serve::run(serve_flags, folder_options, builders), } } diff --git a/src/commands/serve/mod.rs b/src/commands/serve/mod.rs index 83ba5c9..8bf1034 100644 --- a/src/commands/serve/mod.rs +++ b/src/commands/serve/mod.rs @@ -1,22 +1,27 @@ mod runner; +use super::common::FolderOptions; use crate::connectors::ConnectorsBuilders; use rocket::config::{Config, Environment}; use std::env; #[derive(Clap, Debug)] pub struct ServeFlags { - /// Listen this port + /// Production, Staging or Development, will change log level, you can set in environment variable as SIRENE_ENV #[clap(long = "env")] environment: Option, - /// Listen this port + /// Listen this port, you can set in environment variable as PORT #[clap(short = "p", long = "port")] port: Option, - /// Listen this host + /// Listen this host, you can set in environment variable as HOST #[clap(short = "h", long = "host")] host: Option, + + /// API key needed to allow maintenance operation from HTTP, you can set in environment variable as API_KEY + #[clap(short = "k", long = "api-key")] + api_key: Option, } arg_enum! { @@ -49,7 +54,7 @@ impl CmdEnvironment { } } -pub fn run(flags: ServeFlags, builders: ConnectorsBuilders) { +pub fn run(flags: ServeFlags, folder_options: FolderOptions, builders: ConnectorsBuilders) { let env = flags.environment.unwrap_or_else(|| { CmdEnvironment::from_str(env::var("SIRENE_ENV").expect("Missing SIRENE_ENV")) .expect("Invalid SIRENE_ENV") @@ -66,10 +71,15 @@ pub fn run(flags: ServeFlags, builders: ConnectorsBuilders) { .host .unwrap_or_else(|| env::var("HOST").expect("Missing HOST")); + let api_key = match flags.api_key { + Some(key) => Some(key), + None => env::var("API_KEY").ok(), + }; + let config = Config::build(env.into()) .address(host) .port(port) .finalize(); - runner::run(config.unwrap(), builders) + runner::run(config.unwrap(), api_key, folder_options, builders) } diff --git a/src/commands/serve/runner/common.rs b/src/commands/serve/runner/common.rs index a43d5e8..c0eace1 100644 --- a/src/commands/serve/runner/common.rs +++ b/src/commands/serve/runner/common.rs @@ -1,10 +1,27 @@ +use super::super::super::common::FolderOptions; use crate::connectors::Connectors; use crate::models::etablissement::common::Etablissement; use crate::models::unite_legale::common::UniteLegale; -use serde::Serialize; +use crate::models::update_metadata::common::{SyntheticGroupType, UpdateSummary}; +use serde::{Deserialize, Serialize}; pub struct Context { pub connectors: Connectors, + pub api_key: Option, + pub folder_options: FolderOptions, +} + +#[derive(Deserialize)] +pub struct UpdateOptions { + pub api_key: String, + pub group_type: SyntheticGroupType, + pub force: bool, + pub data_only: bool, +} + +#[derive(Serialize)] +pub struct UpdateResponse { + pub summary: UpdateSummary, } #[derive(Serialize)] diff --git a/src/commands/serve/runner/error.rs b/src/commands/serve/runner/error.rs index 2e0bdc3..bc63169 100644 --- a/src/commands/serve/runner/error.rs +++ b/src/commands/serve/runner/error.rs @@ -1,4 +1,5 @@ use crate::models::{etablissement, unite_legale}; +use crate::update::error::Error as InternalUpdateError; use custom_error::custom_error; use rocket::http::Status; use rocket::request::Request; @@ -6,6 +7,10 @@ use rocket::response::{self, content, Responder, Response}; use serde::Serialize; custom_error! { pub Error + InvalidData = "Invalid data", + MissingApiKeyError = "[Admin] Missing API key in configuration", + ApiKeyError = "[Admin] Wrong API key", + UpdateError {source: InternalUpdateError} = "[Update] {source}", UniteLegaleError {source: unite_legale::error::Error} = "[UniteLegale] {source}", EtablissementError {source: etablissement::error::Error} = "[Etablissement] {source}", } @@ -21,6 +26,10 @@ impl<'r> Responder<'r> for Error { println!("{}", self); let status = match &self { + Error::InvalidData => Status::BadRequest, + Error::MissingApiKeyError => return Err(Status::Unauthorized), + Error::ApiKeyError => return Err(Status::Unauthorized), + Error::UpdateError { source: _ } => Status::InternalServerError, Error::UniteLegaleError { source } => match source { unite_legale::error::Error::UniteLegaleNotFound => Status::NotFound, _ => Status::InternalServerError, diff --git a/src/commands/serve/runner/mod.rs b/src/commands/serve/runner/mod.rs index 7539049..ba34358 100644 --- a/src/commands/serve/runner/mod.rs +++ b/src/commands/serve/runner/mod.rs @@ -1,11 +1,14 @@ mod common; mod error; +use super::super::common::FolderOptions; use crate::connectors::ConnectorsBuilders; use crate::models; +use crate::update::{common::Config as DataConfig, update as update_data}; use common::{ Context, EtablissementInnerResponse, EtablissementResponse, UniteLegaleEtablissementInnerResponse, UniteLegaleInnerResponse, UniteLegaleResponse, + UpdateOptions, UpdateResponse, }; use error::Error; use rocket::config::Config; @@ -17,11 +20,44 @@ fn index() -> &'static str { "SIRENE API v3" } +#[post("/update", format = "application/json", data = "")] +fn update( + state: State, + options: Json, +) -> Result, Error> { + let api_key = match &state.api_key { + Some(key) => key, + None => return Err(Error::MissingApiKeyError), + }; + + if &options.api_key != api_key { + return Err(Error::ApiKeyError); + } + + let summary = update_data( + options.group_type, + DataConfig { + force: options.force, + data_only: options.data_only, + temp_folder: state.folder_options.temp.clone(), + file_folder: state.folder_options.file.clone(), + db_folder: state.folder_options.db.clone(), + }, + &state.connectors, + )?; + + Ok(Json(UpdateResponse { summary })) +} + #[get("/unites_legales/")] fn unites_legales( state: State, siren: String, ) -> Result, Error> { + if siren.len() != 9 { + return Err(Error::InvalidData); + } + let unite_legale = models::unite_legale::get(&state.connectors, &siren)?; let etablissements = models::etablissement::get_with_siren(&state.connectors, &siren)?; let etablissement_siege = @@ -41,6 +77,10 @@ fn etablissements( state: State, siret: String, ) -> Result, Error> { + if siret.len() != 14 { + return Err(Error::InvalidData); + } + let etablissement = models::etablissement::get(&state.connectors, &siret)?; let unite_legale = models::unite_legale::get(&state.connectors, &etablissement.siren)?; let etablissement_siege = @@ -57,11 +97,19 @@ fn etablissements( })) } -pub fn run(config: Config, builders: ConnectorsBuilders) { +pub fn run( + config: Config, + api_key: Option, + folder_options: FolderOptions, + builders: ConnectorsBuilders, +) { rocket::custom(config) .mount("/v3", routes![index, unites_legales, etablissements]) + .mount("/admin", routes![update]) .manage(Context { connectors: builders.create(), + api_key, + folder_options, }) .launch(); } diff --git a/src/commands/update.rs b/src/commands/update.rs new file mode 100644 index 0000000..71c6bca --- /dev/null +++ b/src/commands/update.rs @@ -0,0 +1,78 @@ +use super::common::{CmdGroupType, FolderOptions}; +use crate::connectors::ConnectorsBuilders; +use crate::models::update_metadata::common::{Step, SyntheticGroupType}; +use crate::update::{common::Config, update, update_step}; + +#[derive(Clap, Debug)] +pub struct UpdateFlags { + /// Configure which part will be updated, UnitesLegales, Etablissements or All + group_type: CmdGroupType, + + /// Force update even if the source data where not updated + #[clap(long = "force")] + force: bool, + + /// Use an existing CSV file already present in FILE_FOLDER and does not delete it + #[clap(long = "data-only")] + data_only: bool, + + #[clap(subcommand)] + subcmd: Option, +} + +#[derive(Clap, Debug)] +enum UpdateSubCommand { + /// Download file in TEMP_FOLDER + #[clap(name = "download-file")] + DownloadFile, + + /// Unzip file from TEMP_FOLDER, and move it to the FILE_FOLDER + #[clap(name = "unzip-file")] + UnzipFile, + + /// Load CSV file in database in loader-table from DB_FOLDER + #[clap(name = "insert-data")] + InsertData, + + /// Swap loader-table to production + #[clap(name = "swap-data")] + SwapData, + + /// Clean files from FILE_FOLDER + #[clap(name = "clean-file")] + CleanFile, +} + +pub fn run(flags: UpdateFlags, folder_options: FolderOptions, builders: ConnectorsBuilders) { + let connectors = builders.create(); + let synthetic_group_type: SyntheticGroupType = flags.group_type.into(); + + // Prepare config + let config = Config { + force: flags.force, + data_only: flags.data_only, + temp_folder: folder_options.temp, + file_folder: folder_options.file, + db_folder: folder_options.db, + }; + + let summary_result = match flags.subcmd { + Some(subcmd) => { + let step = match subcmd { + UpdateSubCommand::DownloadFile => Step::DownloadFile, + UpdateSubCommand::UnzipFile => Step::UnzipFile, + UpdateSubCommand::InsertData => Step::InsertData, + UpdateSubCommand::SwapData => Step::SwapData, + UpdateSubCommand::CleanFile => Step::CleanFile, + }; + + update_step(step, synthetic_group_type, config, &connectors) + } + None => update(synthetic_group_type, config, &connectors), + }; + + match summary_result { + Ok(summary) => println!("{}", serde_json::to_string(&summary).unwrap()), + Err(error) => error.exit(), + } +} diff --git a/src/commands/update/mod.rs b/src/commands/update/mod.rs deleted file mode 100644 index a0af344..0000000 --- a/src/commands/update/mod.rs +++ /dev/null @@ -1,143 +0,0 @@ -mod runner; - -use crate::connectors::ConnectorsBuilders; -use crate::models::metadata::common::GroupType; -use std::env; - -#[derive(Clap, Debug)] -pub struct UpdateFlags { - /// Configure which part will be updated - group_type: CmdGroupType, - - /// Force update even if the source data where not updated - #[clap(long = "force")] - force: bool, - - /// Use an existing CSV file already present in FILE_FOLDER and does not delete it - #[clap(long = "data-only")] - data_only: bool, - - /// Path to the temp folder, you can set in environment variable as TEMP_FOLDER - #[clap(long = "temp-folder")] - temp_folder: Option, - - /// Path to the file storage folder for this app, you can set in environment variable as FILE_FOLDER - #[clap(long = "file-folder")] - file_folder: Option, - - /// Path to the file storage folder for the database, you can set in environment variable as DB_FOLDER - /// Could be the same as FILE_FOLDER if this app and the database are on the same file system - /// Files copied by this app inside FILE_FOLDER must be visible by the database in DB_FOLDER - #[clap(long = "db-folder")] - db_folder: Option, - - #[clap(subcommand)] - subcmd: Option, -} - -arg_enum! { - #[derive(Debug)] - enum CmdGroupType { - UnitesLegales, - Etablissements, - All - } -} - -impl From for Vec { - fn from(group: CmdGroupType) -> Self { - match group { - CmdGroupType::UnitesLegales => vec![GroupType::UnitesLegales], - CmdGroupType::Etablissements => vec![GroupType::Etablissements], - CmdGroupType::All => vec![GroupType::UnitesLegales, GroupType::Etablissements], - } - } -} - -#[derive(Clap, Debug)] -enum UpdateSubCommand { - /// Download file in TEMP_FOLDER - #[clap(name = "download-file")] - DownloadFile, - - /// Unzip file from TEMP_FOLDER, and move it to the FILE_FOLDER - #[clap(name = "unzip-file")] - UnzipFile, - - /// Load CSV file in database in loader-table from DB_FOLDER - #[clap(name = "insert-data")] - InsertData, - - /// Swap loader-table to production - #[clap(name = "swap-data")] - SwapData, - - /// Clean files from FILE_FOLDER - #[clap(name = "clean-file")] - CleanFile, -} - -pub fn run(flags: UpdateFlags, builders: ConnectorsBuilders) { - let group_type: Vec = flags.group_type.into(); - - let temp_folder = flags - .temp_folder - .unwrap_or_else(|| env::var("TEMP_FOLDER").unwrap_or(String::from("./data/temp"))); - - let file_folder = flags - .file_folder - .unwrap_or_else(|| env::var("FILE_FOLDER").unwrap_or(String::from("./data/files"))); - - let db_folder = flags - .db_folder - .unwrap_or_else(|| env::var("DB_FOLDER").unwrap_or(file_folder.clone())); - - let connectors = builders.create(); - let result: Result<(), runner::error::Error>; - - match flags.subcmd { - Some(subcmd) => match subcmd { - UpdateSubCommand::DownloadFile => { - result = - runner::step_download_file(&group_type, &temp_folder, flags.force, &connectors); - } - UpdateSubCommand::UnzipFile => { - result = runner::step_unzip_file( - &group_type, - &temp_folder, - &file_folder, - flags.force, - &connectors, - ); - } - UpdateSubCommand::InsertData => { - result = - runner::step_insert_data(&group_type, &db_folder, flags.force, &connectors); - } - UpdateSubCommand::SwapData => { - result = runner::step_swap_data(&group_type, flags.force, &connectors); - } - UpdateSubCommand::CleanFile => { - result = - runner::step_clean_file(&group_type, &temp_folder, &file_folder, &connectors); - } - }, - None => { - result = runner::update( - &group_type, - runner::Config { - force: flags.force, - data_only: flags.data_only, - temp_folder, - file_folder, - db_folder, - }, - &connectors, - ) - } - } - - if let Err(error) = result { - error.exit(); - } -} diff --git a/src/commands/update/runner/mod.rs b/src/commands/update/runner/mod.rs deleted file mode 100644 index 94ac32a..0000000 --- a/src/commands/update/runner/mod.rs +++ /dev/null @@ -1,448 +0,0 @@ -pub mod error; - -use crate::connectors::Connectors; -use crate::models; -use crate::models::metadata; -use crate::models::metadata::common::GroupType; -use chrono::{DateTime, Utc}; -use error::Error; -use reqwest::header::LAST_MODIFIED; -use std::fs::{canonicalize, create_dir_all, remove_file, set_permissions, File, Permissions}; -use std::io; -use std::path::PathBuf; - -#[derive(Debug)] -pub struct Config { - pub force: bool, - pub data_only: bool, - pub temp_folder: String, - pub file_folder: String, - pub db_folder: String, -} - -pub fn update( - groups: &Vec, - config: Config, - connectors: &Connectors, -) -> Result<(), Error> { - println!("[Update] Starting"); - - if !config.data_only { - println!("[Update] Downloading files"); - step_download_file(groups, &config.temp_folder, config.force, connectors)?; - - println!("[Update] Unzipping files"); - step_unzip_file( - groups, - &config.temp_folder, - &config.file_folder, - config.force, - connectors, - )?; - } - - println!("[Update] Inserting data"); - step_insert_data(groups, &config.db_folder, config.force, connectors)?; - - println!("[Update] Swaping data"); - step_swap_data(groups, config.force, connectors)?; - - if !config.data_only { - println!("[Update] Cleaning files"); - step_clean_file(groups, &config.temp_folder, &config.file_folder, connectors)?; - } - - println!("[Update] Finished"); - - Ok(()) -} - -pub fn step_download_file( - groups: &Vec, - temp_folder: &String, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - for group in groups { - download_file(*group, temp_folder, force, connectors)?; - } - Ok(()) -} - -pub fn step_unzip_file( - groups: &Vec, - temp_folder: &String, - file_folder: &String, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - for group in groups { - unzip_file(*group, temp_folder, file_folder, force, connectors)?; - } - Ok(()) -} - -pub fn step_insert_data( - groups: &Vec, - db_folder: &String, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - for group in groups { - insert_data(*group, db_folder, force, connectors)?; - } - Ok(()) -} - -pub fn step_swap_data( - groups: &Vec, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - for group in groups { - swap_data(*group, force, connectors)?; - } - Ok(()) -} - -pub fn step_clean_file( - groups: &Vec, - temp_folder: &String, - file_folder: &String, - connectors: &Connectors, -) -> Result<(), Error> { - for group in groups { - clean_file(*group, temp_folder, file_folder, connectors)?; - } - Ok(()) -} - -fn download_file( - group: GroupType, - temp_folder: &String, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - println!("[Download] Downloading {:#?}", group); - - let group_metadata = metadata::get(connectors, group)?; - - // Create temp path - create_dir_all(temp_folder).map_err(|io_error| Error::TempFolderCreationError { io_error })?; - - // Get Zip path - let mut zip_path = PathBuf::from(temp_folder); - zip_path.push(group_metadata.file_name); - zip_path.set_extension("zip"); - - // Prepare file download - let mut resp = reqwest::blocking::get(group_metadata.url.as_str()) - .map_err(|req_error| Error::DownloadError { req_error })?; - - // Decode Last-Modified header - let last_modified_str = resp - .headers() - .get(LAST_MODIFIED) - .ok_or(Error::MissingLastModifiedHeader)? - .to_str() - .map_err(|head_error| Error::InvalidLastModifiedHeader { head_error })?; - let last_modified = DateTime::parse_from_rfc2822(last_modified_str) - .map_err(|date_error| Error::InvalidLastModifiedDate { date_error })?; - let last_modified = last_modified.with_timezone(&Utc); - - // Test if not already imported or downloaded - if !force { - if let Some(last_imported_timestamp) = group_metadata.last_imported_timestamp { - if last_modified.le(&last_imported_timestamp) { - println!("[Download] {:#?} already imported", group); - return Ok(()); - } - } - - if let Some(staging_file_timestamp) = group_metadata.staging_file_timestamp { - if last_modified.le(&staging_file_timestamp) { - println!("[Download] {:#?} already downloaded", group); - return Ok(()); - } - } - } - - // Download data and store it on filesystem - let mut out = - File::create(zip_path).map_err(|io_error| Error::FileCreationError { io_error })?; - io::copy(&mut resp, &mut out).map_err(|io_error| Error::FileCopyError { io_error })?; - println!("[Download] Download of {:#?} finished", group); - - // Update staging file timestamp - metadata::set_staging_file_timestamp(connectors, group, last_modified)?; - - Ok(()) -} - -fn unzip_file( - group: GroupType, - temp_folder: &String, - file_folder: &String, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - println!("[Unzip] Unzipping {:#?}", group); - - let group_metadata = metadata::get(connectors, group)?; - - // Unzip only if zip file is referenced in database - let staging_file_timestamp = match group_metadata.staging_file_timestamp { - Some(staging_file_timestamp) => staging_file_timestamp, - None => { - println!("[Unzip] Nothing to unzip for {:#?}", group); - return Ok(()); - } - }; - - // Test if not already imported or unzipped - if !force { - if let Some(staging_csv_file_timestamp) = group_metadata.staging_csv_file_timestamp { - if let Some(last_imported_timestamp) = group_metadata.last_imported_timestamp { - if staging_csv_file_timestamp.le(&last_imported_timestamp) { - println!("[Unzip] {:#?} already imported", group); - return Ok(()); - } - } - - if staging_file_timestamp.le(&staging_csv_file_timestamp) { - println!("[Unzip] {:#?} already unzipped", group); - return Ok(()); - } - } - } - - // Get Zip path - let mut zip_path = PathBuf::from(temp_folder); - zip_path.push(group_metadata.file_name.clone()); - zip_path.set_extension("zip"); - - // Get CSV path - let mut csv_path = PathBuf::from(file_folder); - csv_path.push(group_metadata.file_name); - csv_path.set_extension("csv"); - - if let Some(p) = csv_path.parent() { - if !p.exists() { - create_dir_all(&p).map_err(|io_error| Error::FileFolderCreationError { io_error })?; - } - } - - let zip_file = File::open(&zip_path).map_err(|io_error| Error::ZipOpenError { io_error })?; - let mut archive = - zip::ZipArchive::new(zip_file).map_err(|zip_error| Error::ZipDecodeError { zip_error })?; - - if archive.len() != 1 { - return Err(Error::ZipFormatError); - } - - let mut zipped_csv_file = archive - .by_index(0) - .map_err(|zip_error| Error::ZipAccessFileError { zip_error })?; - - println!( - "[Unzip] Unzipping file {:#?} extracted to \"{}\" ({} bytes)", - group, - csv_path.as_path().display(), - zipped_csv_file.size() - ); - - let mut csv_file = - File::create(&csv_path).map_err(|io_error| Error::FileCSVCreationError { io_error })?; - io::copy(&mut zipped_csv_file, &mut csv_file) - .map_err(|io_error| Error::FileCSVCopyError { io_error })?; - - // Get and Set permissions - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - if let Some(mode) = zipped_csv_file.unix_mode() { - set_permissions(&csv_path, Permissions::from_mode(mode)) - .map_err(|io_error| Error::FileCSVPermissionError { io_error })?; - } - } - - models::metadata::set_staging_csv_file_timestamp(connectors, group, staging_file_timestamp)?; - - println!("[Unzip] Unzip of {:#?} finished", group); - - Ok(()) -} - -fn insert_data( - group: GroupType, - db_folder: &String, - force: bool, - connectors: &Connectors, -) -> Result<(), Error> { - println!("[Insert] Insert {:#?}", group); - - let group_metadata = metadata::get(connectors, group)?; - - // Insert only if csv file is referenced in database - let staging_csv_file_timestamp = match group_metadata.staging_csv_file_timestamp { - Some(staging_csv_file_timestamp) => staging_csv_file_timestamp, - None => { - println!("[Insert] Nothing to insert for {:#?}", group); - return Ok(()); - } - }; - - // Test if not already inserted - if !force { - if let Some(staging_imported_timestamp) = group_metadata.staging_imported_timestamp { - if let Some(last_imported_timestamp) = group_metadata.last_imported_timestamp { - if staging_imported_timestamp.le(&last_imported_timestamp) { - println!("[Insert] {:#?} already imported", group); - return Ok(()); - } - } - - if staging_csv_file_timestamp.le(&staging_imported_timestamp) { - println!("[Insert] {:#?} already inserted", group); - return Ok(()); - } - } - } - - // Get CSV path - let mut csv_path = PathBuf::from(db_folder); - csv_path.push(group_metadata.file_name); - csv_path.set_extension("csv"); - let absolute_csv_path = - canonicalize(csv_path).map_err(|io_error| Error::InvalidComponentInCSVPath { io_error })?; - let csv_path_str = absolute_csv_path - .into_os_string() - .into_string() - .map_err(|_| Error::InvalidCSVPath)?; - - match group { - GroupType::Etablissements => { - models::etablissement::insert_in_staging(connectors, csv_path_str)?; - } - GroupType::UnitesLegales => { - models::unite_legale::insert_in_staging(connectors, csv_path_str)?; - } - } - - models::metadata::set_staging_imported_timestamp( - connectors, - group, - staging_csv_file_timestamp, - )?; - - println!("[Insert] Finished insert of {:#?}", group); - - Ok(()) -} - -fn swap_data(group_type: GroupType, force: bool, connectors: &Connectors) -> Result<(), Error> { - println!("[Insert] Swapping {:#?}", group_type); - - let group_metadata = metadata::get(connectors, group_type)?; - - // Swap only if inserted data are referenced in database - let staging_imported_timestamp = match group_metadata.staging_imported_timestamp { - Some(staging_imported_timestamp) => staging_imported_timestamp, - None => { - println!("[Swap] Nothing to swap for {:#?}", group_type); - return Ok(()); - } - }; - - // Test if not already swapped - if !force { - if let Some(last_imported_timestamp) = group_metadata.last_imported_timestamp { - if staging_imported_timestamp.le(&last_imported_timestamp) { - println!("[Swap] {:#?} already imported", group_type); - return Ok(()); - } - } - } - - match group_type { - GroupType::Etablissements => { - if !force { - let count = models::etablissement::count(connectors)? as f64; - let count_staging = models::etablissement::count_staging(connectors)? as f64; - - let max_count_staging = count * 1.01; - let min_count_staging = count * 0.99; - - if count != 0.0 - && (count_staging < min_count_staging || max_count_staging < count_staging) - { - return Err(Error::SwapStoppedTooMuchDifference { group_type }); - } - } - - models::etablissement::swap(connectors)?; - } - GroupType::UnitesLegales => { - if !force { - let count = models::unite_legale::count(connectors)? as f64; - let count_staging = models::unite_legale::count_staging(connectors)? as f64; - - let max_count_staging = count * 1.01; - let min_count_staging = count * 0.99; - - if count != 0.0 - && (count_staging < min_count_staging || max_count_staging < count_staging) - { - return Err(Error::SwapStoppedTooMuchDifference { group_type }); - } - } - - models::unite_legale::swap(connectors)?; - } - } - - models::metadata::set_last_imported_timestamp( - connectors, - group_type, - staging_imported_timestamp, - )?; - - println!("[Insert] Swap of {:#?} finished", group_type); - - Ok(()) -} - -fn clean_file( - group: GroupType, - temp_folder: &String, - file_folder: &String, - connectors: &Connectors, -) -> Result<(), Error> { - println!("[Clean] Cleaning {:#?}", group); - - let group_metadata = metadata::get(connectors, group)?; - - // Get Zip path - let mut zip_path = PathBuf::from(temp_folder); - zip_path.push(group_metadata.file_name.clone()); - zip_path.set_extension("zip"); - - // Get CSV path - let mut csv_path = PathBuf::from(file_folder); - csv_path.push(group_metadata.file_name); - csv_path.set_extension("csv"); - - if let Err(error) = remove_file(zip_path) { - println!("[Clean] Zip not deleted ({})", error); - } - - if let Err(error) = remove_file(csv_path) { - println!("[Clean] CSV not deleted ({})", error); - } - - models::metadata::reset_staging_timestamps(connectors, group)?; - - println!("[Clean] Finished cleaning of {:#?}", group); - - Ok(()) -} diff --git a/src/main.rs b/src/main.rs index fc9ef95..ce67aff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,9 @@ extern crate zip; mod commands; mod connectors; mod models; +mod update; +use chrono::Utc; use connectors::ConnectorsBuilders; use dotenv::dotenv; @@ -33,6 +35,15 @@ fn main() { // Load database let connectors_builders = ConnectorsBuilders::new(); + // Close running updates + let connectors = connectors_builders.create(); + models::update_metadata::error_update( + &connectors, + String::from("Program unexpectedly closed"), + Utc::now(), + ) + .unwrap(); // Fail launch in case of error + // Run command commands::run(connectors_builders); } diff --git a/src/models/common.rs b/src/models/common.rs new file mode 100644 index 0000000..9abbf42 --- /dev/null +++ b/src/models/common.rs @@ -0,0 +1,14 @@ +use crate::connectors::Connectors; +use custom_error::custom_error; + +pub trait UpdatableModel { + fn count(&self, connectors: &Connectors) -> Result; + fn count_staging(&self, connectors: &Connectors) -> Result; + fn insert_in_staging(&self, connectors: &Connectors, file_path: String) -> Result; + fn swap(&self, connectors: &Connectors) -> Result<(), Error>; +} + +custom_error! { pub Error + LocalConnectionFailed{source: r2d2::Error} = "Unable to connect to local database ({source}).", + DatabaseError{source: diesel::result::Error} = "Unable to run some operations on updatable model ({source}).", +} diff --git a/src/models/etablissement/mod.rs b/src/models/etablissement/mod.rs index 37ad27b..efa7671 100644 --- a/src/models/etablissement/mod.rs +++ b/src/models/etablissement/mod.rs @@ -2,6 +2,7 @@ mod columns; pub mod common; pub mod error; +use super::common::{Error as UpdatableError, UpdatableModel}; use super::schema::etablissement::dsl; use crate::connectors::Connectors; use common::Etablissement; @@ -17,24 +18,6 @@ pub fn get(connectors: &Connectors, siret: &String) -> Result Result { - let connection = connectors.local.pool.get()?; - dsl::etablissement - .select(diesel::dsl::count(dsl::siret)) - .first::(&connection) - .map_err(|error| error.into()) -} - -pub fn count_staging(connectors: &Connectors) -> Result { - use super::schema::etablissement_staging::dsl; - - let connection = connectors.local.pool.get()?; - dsl::etablissement_staging - .select(diesel::dsl::count(dsl::siret)) - .first::(&connection) - .map_err(|error| error.into()) -} - pub fn get_with_siren( connectors: &Connectors, siren: &String, @@ -57,46 +40,73 @@ pub fn get_siege_with_siren( .map_err(|error| error.into()) } -pub fn insert_in_staging(connectors: &Connectors, file_path: String) -> Result { - let connection = connectors.local.pool.get()?; - sql_query("TRUNCATE etablissement_staging").execute(&connection)?; - let query = format!( - "COPY etablissement_staging({}) FROM '{}' DELIMITER ',' CSV HEADER", - columns::COLUMNS, - file_path - ); - sql_query(query) - .execute(&connection) - .map(|count| count > 0) - .map_err(|error| error.into()) -} +pub struct EtablissementModel {} -pub fn swap(connectors: &Connectors) -> Result<(), Error> { - let connection = connectors.local.pool.get()?; - connection.build_transaction().read_write().run(|| { - sql_query("ALTER TABLE etablissement RENAME TO etablissement_temp").execute(&connection)?; - sql_query("ALTER TABLE etablissement_staging RENAME TO etablissement") - .execute(&connection)?; - sql_query("ALTER TABLE etablissement_temp RENAME TO etablissement_staging") - .execute(&connection)?; +impl UpdatableModel for EtablissementModel { + fn count(&self, connectors: &Connectors) -> Result { + let connection = connectors.local.pool.get()?; + dsl::etablissement + .select(diesel::dsl::count(dsl::siret)) + .first::(&connection) + .map_err(|error| error.into()) + } + + fn count_staging(&self, connectors: &Connectors) -> Result { + use super::schema::etablissement_staging::dsl; + + let connection = connectors.local.pool.get()?; + dsl::etablissement_staging + .select(diesel::dsl::count(dsl::siret)) + .first::(&connection) + .map_err(|error| error.into()) + } + + fn insert_in_staging( + &self, + connectors: &Connectors, + file_path: String, + ) -> Result { + let connection = connectors.local.pool.get()?; sql_query("TRUNCATE etablissement_staging").execute(&connection)?; - sql_query( - r#" + let query = format!( + "COPY etablissement_staging({}) FROM '{}' DELIMITER ',' CSV HEADER", + columns::COLUMNS, + file_path + ); + sql_query(query) + .execute(&connection) + .map(|count| count > 0) + .map_err(|error| error.into()) + } + + fn swap(&self, connectors: &Connectors) -> Result<(), UpdatableError> { + let connection = connectors.local.pool.get()?; + connection.build_transaction().read_write().run(|| { + sql_query("ALTER TABLE etablissement RENAME TO etablissement_temp") + .execute(&connection)?; + sql_query("ALTER TABLE etablissement_staging RENAME TO etablissement") + .execute(&connection)?; + sql_query("ALTER TABLE etablissement_temp RENAME TO etablissement_staging") + .execute(&connection)?; + sql_query("TRUNCATE etablissement_staging").execute(&connection)?; + sql_query( + r#" UPDATE group_metadata SET last_imported_timestamp = staging_imported_timestamp WHERE group_type = 'etablissements' "#, - ) - .execute(&connection)?; - sql_query( - r#" + ) + .execute(&connection)?; + sql_query( + r#" UPDATE group_metadata SET staging_imported_timestamp = NULL WHERE group_type = 'etablissements' "#, - ) - .execute(&connection)?; + ) + .execute(&connection)?; - Ok(()) - }) + Ok(()) + }) + } } diff --git a/src/models/metadata/common.rs b/src/models/group_metadata/common.rs similarity index 84% rename from src/models/metadata/common.rs rename to src/models/group_metadata/common.rs index dbda143..59ce012 100644 --- a/src/models/metadata/common.rs +++ b/src/models/group_metadata/common.rs @@ -1,4 +1,7 @@ +use super::super::common::UpdatableModel; +use super::super::etablissement::EtablissementModel; use super::super::schema::group_metadata; +use super::super::unite_legale::UniteLegaleModel; use chrono::{DateTime, Utc}; use diesel::deserialize::{self, FromSql}; use diesel::pg::Pg; @@ -38,6 +41,15 @@ pub enum GroupType { Etablissements, } +impl GroupType { + pub fn get_updatable_model(&self) -> Box { + match self { + GroupType::UnitesLegales => Box::new(UniteLegaleModel {}), + GroupType::Etablissements => Box::new(EtablissementModel {}), + } + } +} + // SQL conversion impl ToSql for GroupType { fn to_sql(&self, out: &mut Output) -> serialize::Result { diff --git a/src/models/metadata/error.rs b/src/models/group_metadata/error.rs similarity index 100% rename from src/models/metadata/error.rs rename to src/models/group_metadata/error.rs diff --git a/src/models/metadata/mod.rs b/src/models/group_metadata/mod.rs similarity index 100% rename from src/models/metadata/mod.rs rename to src/models/group_metadata/mod.rs diff --git a/src/models/mod.rs b/src/models/mod.rs index aa8eaee..54bb5f8 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,4 +1,6 @@ +pub mod common; pub mod etablissement; -pub mod metadata; +pub mod group_metadata; pub mod schema; pub mod unite_legale; +pub mod update_metadata; diff --git a/src/models/schema.rs b/src/models/schema.rs index 1419402..8077f85 100644 --- a/src/models/schema.rs +++ b/src/models/schema.rs @@ -196,10 +196,27 @@ table! { } } +table! { + update_metadata (id) { + id -> Int4, + synthetic_group_type -> Text, + force -> Bool, + data_only -> Bool, + status -> Text, + summary -> Nullable, + error -> Nullable, + launched_timestamp -> Timestamptz, + finished_timestamp -> Nullable, + created_at -> Timestamptz, + updated_at -> Timestamptz, + } +} + allow_tables_to_appear_in_same_query!( etablissement, etablissement_staging, group_metadata, unite_legale, unite_legale_staging, + update_metadata, ); diff --git a/src/models/unite_legale/mod.rs b/src/models/unite_legale/mod.rs index 1707868..f2e80ab 100644 --- a/src/models/unite_legale/mod.rs +++ b/src/models/unite_legale/mod.rs @@ -2,6 +2,7 @@ mod columns; pub mod common; pub mod error; +use super::common::{Error as UpdatableError, UpdatableModel}; use super::schema::unite_legale::dsl; use crate::connectors::Connectors; use common::UniteLegale; @@ -17,64 +18,73 @@ pub fn get(connectors: &Connectors, siren: &String) -> Result Result { - let connection = connectors.local.pool.get()?; - dsl::unite_legale - .select(diesel::dsl::count(dsl::siren)) - .first::(&connection) - .map_err(|error| error.into()) -} +pub struct UniteLegaleModel {} -pub fn count_staging(connectors: &Connectors) -> Result { - use super::schema::unite_legale_staging::dsl; +impl UpdatableModel for UniteLegaleModel { + fn count(&self, connectors: &Connectors) -> Result { + let connection = connectors.local.pool.get()?; + dsl::unite_legale + .select(diesel::dsl::count(dsl::siren)) + .first::(&connection) + .map_err(|error| error.into()) + } - let connection = connectors.local.pool.get()?; - dsl::unite_legale_staging - .select(diesel::dsl::count(dsl::siren)) - .first::(&connection) - .map_err(|error| error.into()) -} + fn count_staging(&self, connectors: &Connectors) -> Result { + use super::schema::unite_legale_staging::dsl; -pub fn insert_in_staging(connectors: &Connectors, file_path: String) -> Result { - let connection = connectors.local.pool.get()?; - sql_query("TRUNCATE unite_legale_staging").execute(&connection)?; - let query = format!( - "COPY unite_legale_staging({}) FROM '{}' DELIMITER ',' CSV HEADER", - columns::COLUMNS, - file_path - ); - sql_query(query) - .execute(&connection) - .map(|count| count > 0) - .map_err(|error| error.into()) -} + let connection = connectors.local.pool.get()?; + dsl::unite_legale_staging + .select(diesel::dsl::count(dsl::siren)) + .first::(&connection) + .map_err(|error| error.into()) + } -pub fn swap(connectors: &Connectors) -> Result<(), Error> { - let connection = connectors.local.pool.get()?; - connection.build_transaction().read_write().run(|| { - sql_query("ALTER TABLE unite_legale RENAME TO unite_legale_temp").execute(&connection)?; - sql_query("ALTER TABLE unite_legale_staging RENAME TO unite_legale") + fn insert_in_staging( + &self, + connectors: &Connectors, + file_path: String, + ) -> Result { + let connection = connectors.local.pool.get()?; + sql_query("TRUNCATE unite_legale_staging").execute(&connection)?; + let query = format!( + "COPY unite_legale_staging({}) FROM '{}' DELIMITER ',' CSV HEADER", + columns::COLUMNS, + file_path + ); + sql_query(query) + .execute(&connection) + .map(|count| count > 0) + .map_err(|error| error.into()) + } + + fn swap(&self, connectors: &Connectors) -> Result<(), UpdatableError> { + let connection = connectors.local.pool.get()?; + connection.build_transaction().read_write().run(|| { + sql_query("ALTER TABLE unite_legale RENAME TO unite_legale_temp") + .execute(&connection)?; + sql_query("ALTER TABLE unite_legale_staging RENAME TO unite_legale") + .execute(&connection)?; + sql_query("ALTER TABLE unite_legale_temp RENAME TO unite_legale_staging") + .execute(&connection)?; + sql_query("TRUNCATE unite_legale_staging").execute(&connection)?; + sql_query( + r#" + UPDATE group_metadata + SET last_imported_timestamp = staging_imported_timestamp + WHERE group_type = 'unites_legales' + "#, + ) .execute(&connection)?; - sql_query("ALTER TABLE unite_legale_temp RENAME TO unite_legale_staging") + sql_query( + r#" + UPDATE group_metadata + SET staging_imported_timestamp = NULL + WHERE group_type = 'unites_legales' + "#, + ) .execute(&connection)?; - sql_query("TRUNCATE unite_legale_staging").execute(&connection)?; - sql_query( - r#" - UPDATE group_metadata - SET last_imported_timestamp = staging_imported_timestamp - WHERE group_type = 'unites_legales' - "#, - ) - .execute(&connection)?; - sql_query( - r#" - UPDATE group_metadata - SET staging_imported_timestamp = NULL - WHERE group_type = 'unites_legales' - "#, - ) - .execute(&connection)?; - Ok(()) - }) + Ok(()) + }) + } } diff --git a/src/models/update_metadata/common.rs b/src/models/update_metadata/common.rs new file mode 100644 index 0000000..540d348 --- /dev/null +++ b/src/models/update_metadata/common.rs @@ -0,0 +1,179 @@ +use super::super::group_metadata::common::GroupType; +use super::super::schema::update_metadata; +use chrono::{DateTime, Utc}; +use diesel::deserialize::{self, FromSql}; +use diesel::pg::Pg; +use diesel::serialize::{self, IsNull, Output, ToSql}; +use diesel::sql_types::{Jsonb, Text}; +use serde::{Deserialize, Serialize}; +use std::io::Write; + +#[derive(Insertable)] +#[table_name = "update_metadata"] +pub struct LaunchUpdateMetadata { + pub synthetic_group_type: SyntheticGroupType, + pub force: bool, + pub data_only: bool, + pub launched_timestamp: DateTime, +} + +#[derive(AsChangeset)] +#[table_name = "update_metadata"] +#[changeset_options(treat_none_as_null = "true")] +pub struct FinishedUpdateMetadata { + pub status: UpdateStatus, + pub summary: UpdateSummary, + pub finished_timestamp: DateTime, +} + +#[derive(AsChangeset)] +#[table_name = "update_metadata"] +#[changeset_options(treat_none_as_null = "true")] +pub struct ErrorUpdateMetadata { + pub status: UpdateStatus, + pub error: String, + pub finished_timestamp: DateTime, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, FromSqlRow, AsExpression)] +#[sql_type = "Text"] +pub enum SyntheticGroupType { + UnitesLegales, + Etablissements, + All, +} + +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, FromSqlRow, AsExpression)] +#[sql_type = "Text"] +pub enum UpdateStatus { + Launched, + Finished, + Error, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct UpdateGroupSummary { + pub group_type: GroupType, + pub updated: bool, + pub status_label: String, + pub started_timestamp: DateTime, + pub finished_timestamp: DateTime, +} + +#[derive(Deserialize, Serialize, Clone, Copy, Debug)] +pub enum Step { + DownloadFile, + UnzipFile, + InsertData, + SwapData, + CleanFile, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct UpdateStepSummary { + pub step: Step, + pub updated: bool, + pub started_timestamp: DateTime, + pub finished_timestamp: DateTime, + pub groups: Vec, +} + +#[derive(FromSqlRow, AsExpression, Deserialize, Serialize, Clone, Debug)] +#[sql_type = "Jsonb"] +pub struct UpdateSummary { + pub updated: bool, + pub started_timestamp: DateTime, + pub finished_timestamp: DateTime, + pub steps: Vec, +} + +impl FromSql for UpdateSummary { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + let value = >::from_sql(bytes)?; + Ok(serde_json::from_value(value)?) + } +} + +impl ToSql for UpdateSummary { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + let value = serde_json::to_value(self)?; + >::to_sql(&value, out) + } +} + +// Type conversion +impl From for Vec { + fn from(group: SyntheticGroupType) -> Self { + match group { + SyntheticGroupType::UnitesLegales => vec![GroupType::UnitesLegales], + SyntheticGroupType::Etablissements => vec![GroupType::Etablissements], + SyntheticGroupType::All => vec![GroupType::UnitesLegales, GroupType::Etablissements], + } + } +} + +// SQL conversion +impl ToSql for SyntheticGroupType { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + match *self { + SyntheticGroupType::UnitesLegales => out.write_all(b"unites_legales")?, + SyntheticGroupType::Etablissements => out.write_all(b"etablissements")?, + SyntheticGroupType::All => out.write_all(b"all")?, + } + Ok(IsNull::No) + } +} + +impl FromSql for SyntheticGroupType { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + match not_none!(bytes) { + b"unites_legales" => Ok(SyntheticGroupType::UnitesLegales), + b"etablissements" => Ok(SyntheticGroupType::Etablissements), + b"all" => Ok(SyntheticGroupType::All), + _ => Err("Unrecognized enum variant".into()), + } + } +} + +impl std::fmt::Display for SyntheticGroupType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SyntheticGroupType::UnitesLegales => write!(f, "unités légales"), + SyntheticGroupType::Etablissements => write!(f, "établissements"), + SyntheticGroupType::All => write!(f, "all"), + } + } +} + +// SQL conversion +impl ToSql for UpdateStatus { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + match *self { + UpdateStatus::Launched => out.write_all(b"launched")?, + UpdateStatus::Finished => out.write_all(b"finished")?, + UpdateStatus::Error => out.write_all(b"error")?, + } + Ok(IsNull::No) + } +} + +impl FromSql for UpdateStatus { + fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result { + match not_none!(bytes) { + b"launched" => Ok(UpdateStatus::Launched), + b"finished" => Ok(UpdateStatus::Finished), + b"error" => Ok(UpdateStatus::Error), + _ => Err("Unrecognized enum variant".into()), + } + } +} + +impl std::fmt::Display for UpdateStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UpdateStatus::Launched => write!(f, "launched"), + UpdateStatus::Finished => write!(f, "finished"), + UpdateStatus::Error => write!(f, "error"), + } + } +} diff --git a/src/models/update_metadata/error.rs b/src/models/update_metadata/error.rs new file mode 100644 index 0000000..6489649 --- /dev/null +++ b/src/models/update_metadata/error.rs @@ -0,0 +1,20 @@ +use custom_error::custom_error; + +custom_error! { pub Error + AlreadyLaunched = "Unable to launch update while another update is already running.", + UpdateNotRegistered = "Unable to register this update in database.", + LocalConnectionFailed{source: r2d2::Error} = "Unable to connect to local database ({source}).", + MetadataNotFound = "Metadata not found.", + DatabaseError{diesel_error: diesel::result::Error} = "Unable to run some operations on metadata ({diesel_error}).", +} + +impl From for Error { + fn from(error: diesel::result::Error) -> Self { + match error { + diesel::result::Error::NotFound => Error::MetadataNotFound, + _ => Error::DatabaseError { + diesel_error: error, + }, + } + } +} diff --git a/src/models/update_metadata/mod.rs b/src/models/update_metadata/mod.rs new file mode 100644 index 0000000..d1120cd --- /dev/null +++ b/src/models/update_metadata/mod.rs @@ -0,0 +1,85 @@ +pub mod common; +pub mod error; + +use super::schema::update_metadata::dsl; +use crate::connectors::Connectors; +use chrono::{DateTime, Utc}; +use common::{ + ErrorUpdateMetadata, FinishedUpdateMetadata, LaunchUpdateMetadata, SyntheticGroupType, + UpdateStatus, UpdateSummary, +}; +use diesel::prelude::*; +use error::Error; + +pub fn launch_update( + connectors: &Connectors, + synthetic_group_type: SyntheticGroupType, + force: bool, + data_only: bool, +) -> Result, Error> { + let connection = connectors.local.pool.get()?; + + let already_launched = dsl::update_metadata + .select(diesel::dsl::count(dsl::id)) + .filter(dsl::status.eq(UpdateStatus::Launched)) + .first::(&connection) + .map(|count| count > 0)?; + + if already_launched { + return Err(Error::AlreadyLaunched); + } + + let launched_timestamp = Utc::now(); + + match diesel::insert_into(dsl::update_metadata) + .values(&LaunchUpdateMetadata { + synthetic_group_type, + force, + data_only, + launched_timestamp, + }) + .execute(&connection) + { + Ok(count) => { + if count > 0 { + Ok(launched_timestamp) + } else { + Err(Error::UpdateNotRegistered) + } + } + Err(error) => Err(error.into()), + } +} + +pub fn finished_update(connectors: &Connectors, summary: UpdateSummary) -> Result { + let connection = connectors.local.pool.get()?; + let finished_timestamp = summary.finished_timestamp; + + diesel::update(dsl::update_metadata.filter(dsl::status.eq(UpdateStatus::Launched))) + .set(&FinishedUpdateMetadata { + status: UpdateStatus::Finished, + summary: summary, + finished_timestamp, + }) + .execute(&connection) + .map(|count| count > 0) + .map_err(|error| error.into()) +} + +pub fn error_update( + connectors: &Connectors, + error: String, + finished_timestamp: DateTime, +) -> Result { + let connection = connectors.local.pool.get()?; + + diesel::update(dsl::update_metadata.filter(dsl::status.eq(UpdateStatus::Launched))) + .set(&ErrorUpdateMetadata { + status: UpdateStatus::Error, + error, + finished_timestamp, + }) + .execute(&connection) + .map(|count| count > 0) + .map_err(|error| error.into()) +} diff --git a/src/update/action/clean.rs b/src/update/action/clean.rs new file mode 100644 index 0000000..ee3a8df --- /dev/null +++ b/src/update/action/clean.rs @@ -0,0 +1,67 @@ +use super::super::error::Error; +use super::common::Action; +use crate::connectors::Connectors; +use crate::models::group_metadata; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary}; +use chrono::Utc; +use std::fs::remove_file; +use std::path::PathBuf; + +pub struct CleanAction { + pub temp_folder: String, + pub file_folder: String, +} + +impl Action for CleanAction { + fn step(&self) -> Step { + Step::CleanFile + } + + fn execute( + &self, + group_type: GroupType, + connectors: &Connectors, + ) -> Result { + println!("[Clean] Cleaning {:#?}", group_type); + let started_timestamp = Utc::now(); + let mut updated = true; + let mut status_label = String::from("cleaned"); + + let metadata = group_metadata::get(connectors, group_type)?; + + // Get Zip path + let mut zip_path = PathBuf::from(self.temp_folder.clone()); + zip_path.push(metadata.file_name.clone()); + zip_path.set_extension("zip"); + + // Get CSV path + let mut csv_path = PathBuf::from(self.file_folder.clone()); + csv_path.push(metadata.file_name); + csv_path.set_extension("csv"); + + if let Err(error) = remove_file(zip_path) { + println!("[Clean] Zip not deleted ({})", error); + updated = false; + status_label = String::from("zip not deleted"); + } + + if let Err(error) = remove_file(csv_path) { + println!("[Clean] CSV not deleted ({})", error); + updated = false; + status_label = String::from("csv not deleted"); + } + + group_metadata::reset_staging_timestamps(connectors, group_type)?; + + println!("[Clean] Finished cleaning of {:#?}", group_type); + + Ok(UpdateGroupSummary { + group_type, + updated, + status_label, + started_timestamp, + finished_timestamp: Utc::now(), + }) + } +} diff --git a/src/update/action/common.rs b/src/update/action/common.rs new file mode 100644 index 0000000..d3bc3c1 --- /dev/null +++ b/src/update/action/common.rs @@ -0,0 +1,13 @@ +use super::super::error::Error; +use crate::connectors::Connectors; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary}; + +pub trait Action { + fn step(&self) -> Step; + fn execute( + &self, + group_type: GroupType, + connectors: &Connectors, + ) -> Result; +} diff --git a/src/update/action/download.rs b/src/update/action/download.rs new file mode 100644 index 0000000..8f2572b --- /dev/null +++ b/src/update/action/download.rs @@ -0,0 +1,103 @@ +use super::super::error::Error; +use super::common::Action; +use crate::connectors::Connectors; +use crate::models::group_metadata; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary}; +use chrono::{DateTime, Utc}; +use reqwest::header::LAST_MODIFIED; +use std::fs::{create_dir_all, File}; +use std::io; +use std::path::PathBuf; + +pub struct DownloadAction { + pub temp_folder: String, + pub force: bool, +} + +impl Action for DownloadAction { + fn step(&self) -> Step { + Step::DownloadFile + } + + fn execute( + &self, + group_type: GroupType, + connectors: &Connectors, + ) -> Result { + println!("[Download] Downloading {:#?}", group_type); + let started_timestamp = Utc::now(); + + let metadata = group_metadata::get(connectors, group_type)?; + + // Create temp path + create_dir_all(self.temp_folder.clone()) + .map_err(|io_error| Error::TempFolderCreationError { io_error })?; + + // Get Zip path + let mut zip_path = PathBuf::from(self.temp_folder.clone()); + zip_path.push(metadata.file_name); + zip_path.set_extension("zip"); + + // Prepare file download + let mut resp = reqwest::blocking::get(metadata.url.as_str()) + .map_err(|req_error| Error::DownloadError { req_error })?; + + // Decode Last-Modified header + let last_modified_str = resp + .headers() + .get(LAST_MODIFIED) + .ok_or(Error::MissingLastModifiedHeader)? + .to_str() + .map_err(|head_error| Error::InvalidLastModifiedHeader { head_error })?; + let last_modified = DateTime::parse_from_rfc2822(last_modified_str) + .map_err(|date_error| Error::InvalidLastModifiedDate { date_error })?; + let last_modified = last_modified.with_timezone(&Utc); + + // Test if not already imported or downloaded + if !self.force { + if let Some(last_imported_timestamp) = metadata.last_imported_timestamp { + if last_modified.le(&last_imported_timestamp) { + println!("[Download] {:#?} already imported", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already imported"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + + if let Some(staging_file_timestamp) = metadata.staging_file_timestamp { + if last_modified.le(&staging_file_timestamp) { + println!("[Download] {:#?} already downloaded", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already downloaded"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + } + + // Download data and store it on filesystem + let mut out = + File::create(zip_path).map_err(|io_error| Error::FileCreationError { io_error })?; + io::copy(&mut resp, &mut out).map_err(|io_error| Error::FileCopyError { io_error })?; + println!("[Download] Download of {:#?} finished", group_type); + + // Update staging file timestamp + group_metadata::set_staging_file_timestamp(connectors, group_type, last_modified)?; + + return Ok(UpdateGroupSummary { + group_type, + updated: true, + status_label: String::from("downloaded"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } +} diff --git a/src/update/action/insert.rs b/src/update/action/insert.rs new file mode 100644 index 0000000..d19ed38 --- /dev/null +++ b/src/update/action/insert.rs @@ -0,0 +1,106 @@ +use super::super::error::Error; +use super::common::Action; +use crate::connectors::Connectors; +use crate::models::group_metadata; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary}; +use chrono::Utc; +use std::fs::canonicalize; +use std::path::PathBuf; + +pub struct InsertAction { + pub db_folder: String, + pub force: bool, +} + +impl Action for InsertAction { + fn step(&self) -> Step { + Step::InsertData + } + + fn execute( + &self, + group_type: GroupType, + connectors: &Connectors, + ) -> Result { + println!("[Insert] Insert {:#?}", group_type); + let started_timestamp = Utc::now(); + + let metadata = group_metadata::get(connectors, group_type)?; + + // Insert only if csv file is referenced in database + let staging_csv_file_timestamp = match metadata.staging_csv_file_timestamp { + Some(staging_csv_file_timestamp) => staging_csv_file_timestamp, + None => { + println!("[Insert] Nothing to insert for {:#?}", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("nothing to insert"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + }; + + // Test if not already inserted + if !self.force { + if let Some(staging_imported_timestamp) = metadata.staging_imported_timestamp { + if let Some(last_imported_timestamp) = metadata.last_imported_timestamp { + if staging_imported_timestamp.le(&last_imported_timestamp) { + println!("[Insert] {:#?} already imported", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already imported"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + + if staging_csv_file_timestamp.le(&staging_imported_timestamp) { + println!("[Insert] {:#?} already inserted", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already inserted"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + } + + // Get CSV path + let mut csv_path = PathBuf::from(self.db_folder.clone()); + csv_path.push(metadata.file_name); + csv_path.set_extension("csv"); + let absolute_csv_path = canonicalize(csv_path) + .map_err(|io_error| Error::InvalidComponentInCSVPath { io_error })?; + let csv_path_str = absolute_csv_path + .into_os_string() + .into_string() + .map_err(|_| Error::InvalidCSVPath)?; + + group_type + .get_updatable_model() + .insert_in_staging(connectors, csv_path_str)?; + + group_metadata::set_staging_imported_timestamp( + connectors, + group_type, + staging_csv_file_timestamp, + )?; + + println!("[Insert] Finished insert of {:#?}", group_type); + + Ok(UpdateGroupSummary { + group_type, + updated: true, + status_label: String::from("inserted"), + started_timestamp, + finished_timestamp: Utc::now(), + }) + } +} diff --git a/src/update/action/mod.rs b/src/update/action/mod.rs new file mode 100644 index 0000000..a582d83 --- /dev/null +++ b/src/update/action/mod.rs @@ -0,0 +1,62 @@ +use super::common::Config; +use super::error::Error; +use crate::connectors::Connectors; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary, UpdateStepSummary}; +use chrono::Utc; +use common::Action; + +pub mod clean; +pub mod common; +pub mod download; +pub mod insert; +pub mod swap; +pub mod unzip; + +pub fn execute_step( + step: Step, + config: &Config, + groups: &Vec, + connectors: &Connectors, +) -> Result { + let started_timestamp = Utc::now(); + let mut groups_summary: Vec = vec![]; + let action = build_action(config, step); + + for group in groups { + groups_summary.push(action.execute(*group, connectors)?); + } + + Ok(UpdateStepSummary { + step: Step::DownloadFile, + updated: groups_summary.iter().find(|&g| g.updated).is_some(), + started_timestamp, + finished_timestamp: Utc::now(), + groups: groups_summary, + }) +} + +fn build_action(config: &Config, step: Step) -> Box { + match step { + Step::DownloadFile => Box::new(download::DownloadAction { + temp_folder: config.temp_folder.clone(), + force: config.force, + }), + Step::UnzipFile => Box::new(unzip::UnzipAction { + temp_folder: config.temp_folder.clone(), + file_folder: config.file_folder.clone(), + force: config.force, + }), + Step::InsertData => Box::new(insert::InsertAction { + db_folder: config.file_folder.clone(), + force: config.force, + }), + Step::SwapData => Box::new(swap::SwapAction { + force: config.force, + }), + Step::CleanFile => Box::new(clean::CleanAction { + temp_folder: config.temp_folder.clone(), + file_folder: config.file_folder.clone(), + }), + } +} diff --git a/src/update/action/swap.rs b/src/update/action/swap.rs new file mode 100644 index 0000000..699cedd --- /dev/null +++ b/src/update/action/swap.rs @@ -0,0 +1,93 @@ +use super::super::error::Error; +use super::common::Action; +use crate::connectors::Connectors; +use crate::models::group_metadata; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary}; +use chrono::Utc; + +pub struct SwapAction { + pub force: bool, +} + +impl Action for SwapAction { + fn step(&self) -> Step { + Step::SwapData + } + + fn execute( + &self, + group_type: GroupType, + connectors: &Connectors, + ) -> Result { + println!("[Insert] Swapping {:#?}", group_type); + let started_timestamp = Utc::now(); + + let metadata = group_metadata::get(connectors, group_type)?; + + // Swap only if inserted data are referenced in database + let staging_imported_timestamp = match metadata.staging_imported_timestamp { + Some(staging_imported_timestamp) => staging_imported_timestamp, + None => { + println!("[Swap] Nothing to swap for {:#?}", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("nothing to swap"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + }; + + // Test if not already swapped + if !self.force { + if let Some(last_imported_timestamp) = metadata.last_imported_timestamp { + if staging_imported_timestamp.le(&last_imported_timestamp) { + println!("[Swap] {:#?} already imported", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already imported"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + } + + let model = group_type.get_updatable_model(); + + if !self.force { + let count = model.count(connectors)? as f64; + let count_staging = model.count_staging(connectors)? as f64; + + let max_count_staging = count * 1.01; + let min_count_staging = count * 0.99; + + if count != 0.0 + && (count_staging < min_count_staging || max_count_staging < count_staging) + { + return Err(Error::SwapStoppedTooMuchDifference { group_type }); + } + } + + model.swap(connectors)?; + + group_metadata::set_last_imported_timestamp( + connectors, + group_type, + staging_imported_timestamp, + )?; + + println!("[Insert] Swap of {:#?} finished", group_type); + + Ok(UpdateGroupSummary { + group_type, + updated: true, + status_label: String::from("swapped"), + started_timestamp, + finished_timestamp: Utc::now(), + }) + } +} diff --git a/src/update/action/unzip.rs b/src/update/action/unzip.rs new file mode 100644 index 0000000..25d41fe --- /dev/null +++ b/src/update/action/unzip.rs @@ -0,0 +1,145 @@ +use super::super::error::Error; +use super::common::Action; +use crate::connectors::Connectors; +use crate::models::group_metadata; +use crate::models::group_metadata::common::GroupType; +use crate::models::update_metadata::common::{Step, UpdateGroupSummary}; +use chrono::Utc; +use std::fs::{create_dir_all, set_permissions, File, Permissions}; +use std::io; +use std::path::PathBuf; + +pub struct UnzipAction { + pub temp_folder: String, + pub file_folder: String, + pub force: bool, +} + +impl Action for UnzipAction { + fn step(&self) -> Step { + Step::UnzipFile + } + + fn execute( + &self, + group_type: GroupType, + connectors: &Connectors, + ) -> Result { + println!("[Unzip] Unzipping {:#?}", group_type); + let started_timestamp = Utc::now(); + + let metadata = group_metadata::get(connectors, group_type)?; + + // Unzip only if zip file is referenced in database + let staging_file_timestamp = match metadata.staging_file_timestamp { + Some(staging_file_timestamp) => staging_file_timestamp, + None => { + println!("[Unzip] Nothing to unzip for {:#?}", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("nothing to unzip"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + }; + + // Test if not already imported or unzipped + if !self.force { + if let Some(staging_csv_file_timestamp) = metadata.staging_csv_file_timestamp { + if let Some(last_imported_timestamp) = metadata.last_imported_timestamp { + if staging_csv_file_timestamp.le(&last_imported_timestamp) { + println!("[Unzip] {:#?} already imported", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already imported"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + + if staging_file_timestamp.le(&staging_csv_file_timestamp) { + println!("[Unzip] {:#?} already unzipped", group_type); + return Ok(UpdateGroupSummary { + group_type, + updated: false, + status_label: String::from("already unzipped"), + started_timestamp, + finished_timestamp: Utc::now(), + }); + } + } + } + + // Get Zip path + let mut zip_path = PathBuf::from(self.temp_folder.clone()); + zip_path.push(metadata.file_name.clone()); + zip_path.set_extension("zip"); + + // Get CSV path + let mut csv_path = PathBuf::from(self.file_folder.clone()); + csv_path.push(metadata.file_name); + csv_path.set_extension("csv"); + + if let Some(p) = csv_path.parent() { + if !p.exists() { + create_dir_all(&p) + .map_err(|io_error| Error::FileFolderCreationError { io_error })?; + } + } + + let zip_file = + File::open(&zip_path).map_err(|io_error| Error::ZipOpenError { io_error })?; + let mut archive = zip::ZipArchive::new(zip_file) + .map_err(|zip_error| Error::ZipDecodeError { zip_error })?; + + if archive.len() != 1 { + return Err(Error::ZipFormatError); + } + + let mut zipped_csv_file = archive + .by_index(0) + .map_err(|zip_error| Error::ZipAccessFileError { zip_error })?; + + println!( + "[Unzip] Unzipping file {:#?} extracted to \"{}\" ({} bytes)", + group_type, + csv_path.as_path().display(), + zipped_csv_file.size() + ); + + let mut csv_file = + File::create(&csv_path).map_err(|io_error| Error::FileCSVCreationError { io_error })?; + io::copy(&mut zipped_csv_file, &mut csv_file) + .map_err(|io_error| Error::FileCSVCopyError { io_error })?; + + // Get and Set permissions + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + if let Some(mode) = zipped_csv_file.unix_mode() { + set_permissions(&csv_path, Permissions::from_mode(mode)) + .map_err(|io_error| Error::FileCSVPermissionError { io_error })?; + } + } + + group_metadata::set_staging_csv_file_timestamp( + connectors, + group_type, + staging_file_timestamp, + )?; + + println!("[Unzip] Unzip of {:#?} finished", group_type); + + Ok(UpdateGroupSummary { + group_type, + updated: true, + status_label: String::from("unzipped"), + started_timestamp, + finished_timestamp: Utc::now(), + }) + } +} diff --git a/src/update/common.rs b/src/update/common.rs new file mode 100644 index 0000000..bff66fb --- /dev/null +++ b/src/update/common.rs @@ -0,0 +1,8 @@ +#[derive(Debug)] +pub struct Config { + pub force: bool, + pub data_only: bool, + pub temp_folder: String, + pub file_folder: String, + pub db_folder: String, +} diff --git a/src/commands/update/runner/error.rs b/src/update/error.rs similarity index 76% rename from src/commands/update/runner/error.rs rename to src/update/error.rs index dfcbe35..8928364 100644 --- a/src/commands/update/runner/error.rs +++ b/src/update/error.rs @@ -1,11 +1,13 @@ -use crate::models::{etablissement, metadata, unite_legale}; +use crate::models; +use crate::models::group_metadata::common::GroupType; +use crate::models::{group_metadata, update_metadata}; use custom_error::custom_error; use std::process; custom_error! { pub Error - MetadataModelError {source: metadata::error::Error} = "Error on Metadata model: {source}.", - EtablissementModelError {source: etablissement::error::Error} = "Error on Etablissement model: {source}.", - UniteLegaleModelError {source: unite_legale::error::Error} = "Error on UniteLegale model: {source}.", + MetadataModelError {source: group_metadata::error::Error} = "Error on Metadata model: {source}.", + UpdateMetadataModelError {source: update_metadata::error::Error} = "Error on UpdateMetadata model: {source}.", + UpdatableModelError {source: models::common::Error} = "Error on UpdatableModel model: {source}.", TempFolderCreationError {io_error: std::io::Error} = "Unable to create temporary folder ({io_error}).", FileFolderCreationError {io_error: std::io::Error} = "Unable to create data folder ({io_error}).", FileCreationError {io_error: std::io::Error} = "Unable to create file for download ({io_error}).", @@ -23,7 +25,7 @@ custom_error! { pub Error InvalidLastModifiedDate {date_error: chrono::format::ParseError} = "Needed header 'Last-Modified' is invalid while downloading ({date_error}).", InvalidCSVPath = "Invalid CSV path, not UTF8 compatible.", InvalidComponentInCSVPath {io_error: std::io::Error} = "Invalid component in CSV path ({io_error}).", - SwapStoppedTooMuchDifference {group_type: super::GroupType} = "Swapping stopped on {group_type}, more than 1% difference between the old values and the new ones. Use --force to override.", + SwapStoppedTooMuchDifference {group_type: GroupType} = "Swapping stopped on {group_type}, more than 1% difference between the old values and the new ones. Use --force to override.", } impl Error { diff --git a/src/update/mod.rs b/src/update/mod.rs new file mode 100644 index 0000000..1c2539a --- /dev/null +++ b/src/update/mod.rs @@ -0,0 +1,100 @@ +use crate::connectors::Connectors; +use crate::models::update_metadata; +use crate::models::update_metadata::common::{ + Step, SyntheticGroupType, UpdateStepSummary, UpdateSummary, +}; +use action::execute_step; +use chrono::Utc; +use common::Config; +use error::Error; + +pub mod action; +pub mod common; +pub mod error; + +pub fn update( + synthetic_group_type: SyntheticGroupType, + config: Config, + connectors: &Connectors, +) -> Result { + // Build and execute workflow + execute_workflow( + build_workflow(&config), + synthetic_group_type, + config, + connectors, + ) +} + +pub fn update_step( + step: Step, + synthetic_group_type: SyntheticGroupType, + config: Config, + connectors: &Connectors, +) -> Result { + // Execute step + execute_workflow(vec![step], synthetic_group_type, config, connectors) +} + +fn execute_workflow( + workflow: Vec, + synthetic_group_type: SyntheticGroupType, + config: Config, + connectors: &Connectors, +) -> Result { + // Register start + update_metadata::launch_update( + connectors, + synthetic_group_type, + config.force, + config.data_only, + )?; + + // Start + println!("[Update] Starting"); + let started_timestamp = Utc::now(); + + // Execute workflow + let result_steps: Result, Error> = workflow + .into_iter() + .map(|step| execute_step(step, &config, &synthetic_group_type.into(), connectors)) + .collect(); + + let steps = match result_steps { + Ok(s) => s, + Err(error) => { + update_metadata::error_update(connectors, error.to_string(), Utc::now())?; + return Err(error); + } + }; + + // End + println!("[Update] Finished"); + let summary = UpdateSummary { + updated: steps.iter().find(|&s| s.updated).is_some(), + started_timestamp, + finished_timestamp: Utc::now(), + steps, + }; + update_metadata::finished_update(connectors, summary.clone())?; + + Ok(summary) +} + +fn build_workflow(config: &Config) -> Vec { + let mut workflow: Vec = vec![]; + + if !config.data_only { + workflow.push(Step::DownloadFile); + workflow.push(Step::UnzipFile); + } + + workflow.push(Step::InsertData); + workflow.push(Step::SwapData); + + if !config.data_only { + workflow.push(Step::CleanFile); + } + + workflow +}