diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 00000000..ca1e776b --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,2 @@ +use_small_heuristics = "Max" +group_imports = "StdExternalCrate" diff --git a/Cargo.lock b/Cargo.lock index 5addb241..3a6a0e2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,87 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "actix-codec" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" +dependencies = [ + "bitflags", + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project 0.4.27", + "tokio 0.2.24", + "tokio-util", +] + +[[package]] +name = "actix-connect" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "derive_more", + "either", + "futures-util", + "http", + "log", + "trust-dns-proto", + "trust-dns-resolver", +] + +[[package]] +name = "actix-http" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "452299e87817ae5673910e53c243484ca38be3828db819b6011736fc6982e874" +dependencies = [ + "actix-codec", + "actix-connect", + "actix-rt", + "actix-service", + "actix-threadpool", + "actix-utils", + "base64", + "bitflags", + "brotli2", + "bytes 0.5.6", + "cookie", + "copyless", + "derive_more", + "either", + "encoding_rs", + "flate2", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "h2", + "http", + "httparse", + "indexmap", + "itoa", + "language-tags", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project 1.0.2", + "rand", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "sha-1", + "slab", + "time", +] + [[package]] name = "actix-macros" version = "0.1.3" @@ -10,6 +92,19 @@ dependencies = [ "syn", ] +[[package]] +name = "actix-router" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd1f7dbda1645bf7da33554db60891755f6c01c1b2169e2f4c492098d30c235" +dependencies = [ + "bytestring", + "http", + "log", + "regex", + "serde", +] + [[package]] name = "actix-rt" version = "1.1.1" @@ -25,6 +120,50 @@ dependencies = [ "tokio 0.2.24", ] +[[package]] +name = "actix-server" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "futures-channel", + "futures-util", + "log", + "mio 0.6.23", + "mio-uds", + "num_cpus", + "slab", + "socket2", +] + +[[package]] +name = "actix-service" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" +dependencies = [ + "futures-util", + "pin-project 0.4.27", +] + +[[package]] +name = "actix-testing" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" +dependencies = [ + "actix-macros", + "actix-rt", + "actix-server", + "actix-service", + "log", + "socket2", +] + [[package]] name = "actix-threadpool" version = "0.3.3" @@ -40,6 +179,128 @@ dependencies = [ "threadpool", ] +[[package]] +name = "actix-tls" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" +dependencies = [ + "actix-codec", + "actix-service", + "actix-utils", + "futures-util", +] + +[[package]] +name = "actix-utils" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "bitflags", + "bytes 0.5.6", + "either", + "futures-channel", + "futures-sink", + "futures-util", + "log", + "pin-project 0.4.27", + "slab", +] + +[[package]] +name = "actix-web" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-testing", + "actix-threadpool", + "actix-tls", + "actix-utils", + "actix-web-codegen", + "awc", + "bytes 0.5.6", + "derive_more", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "log", + "mime", + "pin-project 1.0.2", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "socket2", + "time", + "tinyvec", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "addr2line" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" + +[[package]] +name = "async-attributes" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "async-channel" version = "1.5.1" @@ -51,6 +312,31 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-compat" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f0bb3019d8e5ffe88594b122ba9ba37280a3bc8d94a742b56c8417457215ae4" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite 0.1.11", + "tokio 0.2.24", +] + +[[package]] +name = "async-compat" +version = "0.1.5" +source = "git+https://github.com/taiki-e/async-compat?branch=tokio1#8d87a0917ebe27e4e3caa944d2991d26b1050fb0" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite 0.2.0", + "tokio 1.0.1", +] + [[package]] name = "async-executor" version = "1.4.0" @@ -113,6 +399,7 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f9f84f1280a2b436a2c77c2582602732b6c2f4321d5494d6e799e6c367859a8" dependencies = [ + "async-attributes", "async-channel", "async-global-executor", "async-io", @@ -141,6 +428,17 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" +[[package]] +name = "async-trait" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atomic-waker" version = "1.0.0" @@ -153,12 +451,71 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "awc" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" +dependencies = [ + "actix-codec", + "actix-http", + "actix-rt", + "actix-service", + "base64", + "bytes 0.5.6", + "cfg-if 1.0.0", + "derive_more", + "futures-core", + "log", + "mime", + "percent-encoding", + "rand", + "serde", + "serde_json", + "serde_urlencoded", +] + +[[package]] +name = "backtrace" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "blocking" version = "1.0.2" @@ -173,18 +530,59 @@ dependencies = [ "once_cell", ] +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + [[package]] name = "bumpalo" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + [[package]] name = "bytes" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" +[[package]] +name = "bytes" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72" + +[[package]] +name = "bytestring" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7c05fa5172da78a62d9949d662d2ac89d4cc7355d7b49adee5163f1fb3f363" +dependencies = [ + "bytes 0.5.6", +] + [[package]] name = "cache-padded" version = "1.1.1" @@ -218,12 +616,44 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "const_fn" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826" + +[[package]] +name = "cookie" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784ad0fbab4f3e9cef09f20e0aea6000ae08d2cb98ac4c0abc53df18803d702f" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "copyless" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "crossbeam-utils" version = "0.8.1" @@ -246,12 +676,48 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "encoding_rs" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801bbab217d7f79c0062f4f7205b5d4427c6d1a7bd7aafdd1475f7c59d62b283" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "enum-as-inner" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "event-listener" version = "2.5.1" @@ -267,6 +733,24 @@ dependencies = [ "instant", ] +[[package]] +name = "flate2" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.0.0" @@ -293,6 +777,20 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "futures" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.8" @@ -300,6 +798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -341,6 +840,12 @@ dependencies = [ "syn", ] +[[package]] +name = "futures-sink" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" + [[package]] name = "futures-task" version = "0.3.8" @@ -356,16 +861,56 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", - "pin-project", + "memchr", + "pin-project 1.0.2", "pin-utils", "proc-macro-hack", "proc-macro-nested", "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" + [[package]] name = "gloo-timers" version = "0.2.1" @@ -379,6 +924,41 @@ dependencies = [ "web-sys", ] +[[package]] +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio 0.2.24", + "tokio-util", + "tracing", + "tracing-futures", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + +[[package]] +name = "heck" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.17" @@ -388,6 +968,34 @@ dependencies = [ "libc", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi 0.3.9", +] + +[[package]] +name = "http" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26" +dependencies = [ + "bytes 0.5.6", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" + [[package]] name = "idna" version = "0.2.0" @@ -399,6 +1007,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "instant" version = "0.1.9" @@ -417,6 +1035,24 @@ dependencies = [ "libc", ] +[[package]] +name = "ipconfig" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +dependencies = [ + "socket2", + "widestring", + "winapi 0.3.9", + "winreg", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + [[package]] name = "js-sys" version = "0.3.46" @@ -445,6 +1081,12 @@ dependencies = [ "log", ] +[[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" @@ -457,6 +1099,12 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" + [[package]] name = "lock_api" version = "0.4.2" @@ -475,6 +1123,21 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matches" version = "0.1.8" @@ -487,6 +1150,22 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "mio" version = "0.6.23" @@ -592,12 +1271,24 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + [[package]] name = "once_cell" version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "parking" version = "2.0.0" @@ -635,13 +1326,33 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" +dependencies = [ + "pin-project-internal 0.4.27", +] + [[package]] name = "pin-project" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7" dependencies = [ - "pin-project-internal", + "pin-project-internal 1.0.2", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -686,6 +1397,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -707,6 +1424,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.8" @@ -716,18 +1439,185 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "regex" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpuid-bool", + "digest", + "opaque-debug", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + [[package]] name = "signal-hook-registry" version = "1.3.0" @@ -773,23 +1663,109 @@ name = "sqlx-core" version = "0.6.0-pre" dependencies = [ "actix-rt", + "async-compat 0.1.4", + "async-compat 0.1.5", "async-std", + "bytes 1.0.0", + "futures-io", "futures-util", + "memchr", + "string", "tokio 0.2.24", "tokio 1.0.1", ] +[[package]] +name = "sqlx-example-quickstart" +version = "0.0.0" +dependencies = [ + "actix-web", + "anyhow", + "async-std", + "sqlx", + "tokio 1.0.1", +] + [[package]] name = "sqlx-mysql" version = "0.6.0-pre" dependencies = [ + "bitflags", + "bytes 1.0.0", "either", + "futures-io", "futures-util", + "memchr", "percent-encoding", "sqlx-core", + "string", "url", ] +[[package]] +name = "standback" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66a8cff4fa24853fdf6b51f75c6d7f8206d7c75cab4e467bcd7f25c2b1febe0" +dependencies = [ + "version_check", +] + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "string" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" + [[package]] name = "syn" version = "1.0.56" @@ -801,6 +1777,35 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "thiserror" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -810,6 +1815,44 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "time" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcdaeea317915d59b2b4cd3b5efcd156c309108664277793f5351700c02ce98b" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi 0.3.9", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", +] + [[package]] name = "tinyvec" version = "1.1.0" @@ -831,11 +1874,12 @@ version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48" dependencies = [ - "bytes", + "bytes 0.5.6", "futures-core", "iovec", "lazy_static", "libc", + "memchr", "mio 0.6.23", "mio-uds", "pin-project-lite 0.1.11", @@ -853,9 +1897,113 @@ dependencies = [ "autocfg", "libc", "mio 0.7.6", + "num_cpus", "pin-project-lite 0.2.0", + "tokio-macros", ] +[[package]] +name = "tokio-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42517d2975ca3114b22a16192634e8241dc5cc1f130be194645970cc1c371494" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project-lite 0.1.11", + "tokio 0.2.24", +] + +[[package]] +name = "tracing" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" +dependencies = [ + "cfg-if 1.0.0", + "log", + "pin-project-lite 0.2.0", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +dependencies = [ + "pin-project 0.4.27", + "tracing", +] + +[[package]] +name = "trust-dns-proto" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53861fcb288a166aae4c508ae558ed18b53838db728d4d310aad08270a7d4c2b" +dependencies = [ + "async-trait", + "backtrace", + "enum-as-inner", + "futures", + "idna", + "lazy_static", + "log", + "rand", + "smallvec", + "thiserror", + "tokio 0.2.24", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6759e8efc40465547b0dfce9500d733c65f969a4cbbfbe3ccf68daaa46ef179e" +dependencies = [ + "backtrace", + "cfg-if 0.1.10", + "futures", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "resolv-conf", + "smallvec", + "thiserror", + "tokio 0.2.24", + "trust-dns-proto", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -874,6 +2022,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -898,12 +2052,24 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + [[package]] name = "waker-fn" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +[[package]] +name = "wasi" +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.69" @@ -989,6 +2155,12 @@ dependencies = [ "cc", ] +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + [[package]] name = "winapi" version = "0.2.8" @@ -1023,6 +2195,15 @@ 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.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index c7e3334c..a084688a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ members = [ "sqlx-core", "sqlx-mysql", "sqlx", + "examples/quickstart" ] diff --git a/examples/quickstart/Cargo.lock b/examples/quickstart/Cargo.lock new file mode 100644 index 00000000..fe4c024e --- /dev/null +++ b/examples/quickstart/Cargo.lock @@ -0,0 +1,2188 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "actix-codec" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" +dependencies = [ + "bitflags", + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project 0.4.27", + "tokio 0.2.24", + "tokio-util", +] + +[[package]] +name = "actix-connect" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "derive_more", + "either", + "futures-util", + "http", + "log", + "trust-dns-proto", + "trust-dns-resolver", +] + +[[package]] +name = "actix-http" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "452299e87817ae5673910e53c243484ca38be3828db819b6011736fc6982e874" +dependencies = [ + "actix-codec", + "actix-connect", + "actix-rt", + "actix-service", + "actix-threadpool", + "actix-utils", + "base64", + "bitflags", + "brotli2", + "bytes 0.5.6", + "cookie", + "copyless", + "derive_more", + "either", + "encoding_rs", + "flate2", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "h2", + "http", + "httparse", + "indexmap", + "itoa", + "language-tags", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project 1.0.2", + "rand", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "sha-1", + "slab", + "time", +] + +[[package]] +name = "actix-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd1f7dbda1645bf7da33554db60891755f6c01c1b2169e2f4c492098d30c235" +dependencies = [ + "bytestring", + "http", + "log", + "regex", + "serde", +] + +[[package]] +name = "actix-rt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" +dependencies = [ + "actix-macros", + "actix-threadpool", + "copyless", + "futures-channel", + "futures-util", + "smallvec", + "tokio 0.2.24", +] + +[[package]] +name = "actix-server" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "futures-channel", + "futures-util", + "log", + "mio 0.6.23", + "mio-uds", + "num_cpus", + "slab", + "socket2", +] + +[[package]] +name = "actix-service" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" +dependencies = [ + "futures-util", + "pin-project 0.4.27", +] + +[[package]] +name = "actix-testing" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" +dependencies = [ + "actix-macros", + "actix-rt", + "actix-server", + "actix-service", + "log", + "socket2", +] + +[[package]] +name = "actix-threadpool" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" +dependencies = [ + "derive_more", + "futures-channel", + "lazy_static", + "log", + "num_cpus", + "parking_lot", + "threadpool", +] + +[[package]] +name = "actix-tls" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" +dependencies = [ + "actix-codec", + "actix-service", + "actix-utils", + "futures-util", +] + +[[package]] +name = "actix-utils" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "bitflags", + "bytes 0.5.6", + "either", + "futures-channel", + "futures-sink", + "futures-util", + "log", + "pin-project 0.4.27", + "slab", +] + +[[package]] +name = "actix-web" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-testing", + "actix-threadpool", + "actix-tls", + "actix-utils", + "actix-web-codegen", + "awc", + "bytes 0.5.6", + "derive_more", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "log", + "mime", + "pin-project 1.0.2", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "socket2", + "time", + "tinyvec", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "addr2line" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479" + +[[package]] +name = "async-attributes" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "async-channel" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compat" +version = "0.1.5" +source = "git+https://github.com/taiki-e/async-compat?branch=tokio1#8d87a0917ebe27e4e3caa944d2991d26b1050fb0" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite 0.2.0", + "tokio 1.0.1", +] + +[[package]] +name = "async-executor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "vec-arena", +] + +[[package]] +name = "async-global-executor" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04" +dependencies = [ + "async-executor", + "async-io", + "futures-lite", + "num_cpus", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd" +dependencies = [ + "concurrent-queue", + "fastrand", + "futures-lite", + "libc", + "log", + "nb-connect", + "once_cell", + "parking", + "polling", + "vec-arena", + "waker-fn", + "winapi 0.3.9", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-std" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9f84f1280a2b436a2c77c2582602732b6c2f4321d5494d6e799e6c367859a8" +dependencies = [ + "async-attributes", + "async-channel", + "async-global-executor", + "async-io", + "async-mutex", + "blocking", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite 0.2.0", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" + +[[package]] +name = "async-trait" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "awc" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" +dependencies = [ + "actix-codec", + "actix-http", + "actix-rt", + "actix-service", + "base64", + "bytes 0.5.6", + "cfg-if 1.0.0", + "derive_more", + "futures-core", + "log", + "mime", + "percent-encoding", + "rand", + "serde", + "serde_json", + "serde_urlencoded", +] + +[[package]] +name = "backtrace" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base-x" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + +[[package]] +name = "bumpalo" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + +[[package]] +name = "bytes" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72" + +[[package]] +name = "bytestring" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7c05fa5172da78a62d9949d662d2ac89d4cc7355d7b49adee5163f1fb3f363" +dependencies = [ + "bytes 0.5.6", +] + +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + +[[package]] +name = "cc" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "const_fn" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826" + +[[package]] +name = "cookie" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784ad0fbab4f3e9cef09f20e0aea6000ae08d2cb98ac4c0abc53df18803d702f" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "copyless" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" + +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "derive_more" +version = "0.99.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "encoding_rs" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801bbab217d7f79c0062f4f7205b5d4427c6d1a7bd7aafdd1475f7c59d62b283" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "enum-as-inner" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + +[[package]] +name = "fastrand" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" +dependencies = [ + "instant", +] + +[[package]] +name = "flate2" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "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" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748" + +[[package]] +name = "futures-io" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb" + +[[package]] +name = "futures-lite" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite 0.2.0", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d" + +[[package]] +name = "futures-task" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d" +dependencies = [ + "once_cell", +] + +[[package]] +name = "futures-util" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project 1.0.2", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" + +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio 0.2.24", + "tokio-util", + "tracing", + "tracing-futures", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + +[[package]] +name = "heck" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +dependencies = [ + "libc", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi 0.3.9", +] + +[[package]] +name = "http" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26" +dependencies = [ + "bytes 0.5.6", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" + +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipconfig" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +dependencies = [ + "socket2", + "widestring", + "winapi 0.3.9", + "winreg", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175" +dependencies = [ + "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", + "winapi-build", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[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 = "libc" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" + +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" + +[[package]] +name = "lock_api" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +dependencies = [ + "cfg-if 0.1.10", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.2", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7" +dependencies = [ + "libc", + "log", + "miow 0.3.6", + "ntapi", + "winapi 0.3.9", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +dependencies = [ + "iovec", + "libc", + "mio 0.6.23", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "miow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +dependencies = [ + "socket2", + "winapi 0.3.9", +] + +[[package]] +name = "nb-connect" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + +[[package]] +name = "once_cell" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + +[[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.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" +dependencies = [ + "pin-project-internal 0.4.27", +] + +[[package]] +name = "pin-project" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7" +dependencies = [ + "pin-project-internal 1.0.2", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" + +[[package]] +name = "pin-project-lite" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "polling" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "log", + "wepoll-sys", + "winapi 0.3.9", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "regex" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce3cdf1b5e620a498ee6f2a171885ac7e22f0e12089ec4b3d22b84921792507c" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpuid-bool", + "digest", + "opaque-debug", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "signal-hook-registry" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + +[[package]] +name = "smallvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75" + +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "sqlx" +version = "0.6.0-pre" +dependencies = [ + "sqlx-core", + "sqlx-mysql", +] + +[[package]] +name = "sqlx-core" +version = "0.6.0-pre" +dependencies = [ + "async-compat", + "bytes 1.0.0", + "futures-io", + "futures-util", + "tokio 1.0.1", +] + +[[package]] +name = "sqlx-example-quickstart" +version = "0.0.0" +dependencies = [ + "actix-web", + "anyhow", + "async-std", + "sqlx", + "tokio 1.0.1", +] + +[[package]] +name = "sqlx-mysql" +version = "0.6.0-pre" +dependencies = [ + "bytes 1.0.0", + "either", + "futures-io", + "futures-util", + "memchr", + "percent-encoding", + "sqlx-core", + "url", +] + +[[package]] +name = "standback" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf906c8b8fc3f6ecd1046e01da1d8ddec83e48c8b08b84dcc02b585a6bedf5a8" +dependencies = [ + "version_check", +] + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "syn" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9802ddde94170d186eeee5005b798d9c159fa970403f1be19976d0cfb939b72" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "thiserror" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcdaeea317915d59b2b4cd3b5efcd156c309108664277793f5351700c02ce98b" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi 0.3.9", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio 0.6.23", + "mio-uds", + "pin-project-lite 0.1.11", + "signal-hook-registry", + "slab", + "winapi 0.3.9", +] + +[[package]] +name = "tokio" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258221f566b6c803c7b4714abadc080172b272090cdc5e244a6d4dd13c3a6bd" +dependencies = [ + "autocfg", + "libc", + "mio 0.7.7", + "num_cpus", + "pin-project-lite 0.2.0", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42517d2975ca3114b22a16192634e8241dc5cc1f130be194645970cc1c371494" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project-lite 0.1.11", + "tokio 0.2.24", +] + +[[package]] +name = "tracing" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" +dependencies = [ + "cfg-if 1.0.0", + "log", + "pin-project-lite 0.2.0", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c" +dependencies = [ + "pin-project 0.4.27", + "tracing", +] + +[[package]] +name = "trust-dns-proto" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53861fcb288a166aae4c508ae558ed18b53838db728d4d310aad08270a7d4c2b" +dependencies = [ + "async-trait", + "backtrace", + "enum-as-inner", + "futures", + "idna", + "lazy_static", + "log", + "rand", + "smallvec", + "thiserror", + "tokio 0.2.24", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.19.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6759e8efc40465547b0dfce9500d733c65f969a4cbbfbe3ccf68daaa46ef179e" +dependencies = [ + "backtrace", + "cfg-if 0.1.10", + "futures", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "resolv-conf", + "smallvec", + "thiserror", + "tokio 0.2.24", + "trust-dns-proto", +] + +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "url" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "vec-arena" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "wasi" +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.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fe9756085a84584ee9457a002b7cdfe0bfff169f45d2591d8be1345a6780e35" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158" + +[[package]] +name = "web-sys" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wepoll-sys" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" +dependencies = [ + "cc", +] + +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-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-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.9", +] + +[[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", + "winapi-build", +] diff --git a/examples/quickstart/Cargo.toml b/examples/quickstart/Cargo.toml new file mode 100644 index 00000000..7642bb76 --- /dev/null +++ b/examples/quickstart/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sqlx-example-quickstart" +version = "0.0.0" +license = "MIT OR Apache-2.0" +edition = "2018" +authors = [ + "LaunchBadge " +] + +[dependencies] +actix-web = "3.3.2" +anyhow = "1.0.36" +async-std = { version = "1.8.0", features = ["attributes"] } +#sqlx = { path = "../../sqlx", features = ["tokio", "mysql", "blocking", "async-std", "actix"] } +sqlx = { path = "../../sqlx", features = ["tokio", "mysql"] } +tokio = { version = "1.0.1", features = ["rt", "rt-multi-thread", "macros"] } diff --git a/examples/quickstart/src/main.rs b/examples/quickstart/src/main.rs new file mode 100644 index 00000000..1a9e40a7 --- /dev/null +++ b/examples/quickstart/src/main.rs @@ -0,0 +1,35 @@ +// #[async_std::main] +// async fn main() -> anyhow::Result<()> { +// let _stream = AsyncStd::connect_tcp("localhost", 5432).await?; +// +// Ok(()) +// } + +use sqlx::mysql::MySqlConnectOptions; +use sqlx::prelude::*; + +// #[tokio::main] +// async fn main() -> anyhow::Result<()> { +// let mut conn = ::connect("mysql://").await?; +// +// Ok(()) +// } +// + +// #[async_std::main] +// async fn main() -> anyhow::Result<()> { +// let mut conn = ::builder() +// .host("loca%x91lhost") +// .port(20) +// .connect() +// .await?; +// +// Ok(()) +// } + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let mut conn = ::new().host("localhost").port(3306).connect().await?; + + Ok(()) +} diff --git a/sqlx-core/Cargo.toml b/sqlx-core/Cargo.toml index 8bad07d2..8aeebde6 100644 --- a/sqlx-core/Cargo.toml +++ b/sqlx-core/Cargo.toml @@ -26,16 +26,22 @@ blocking = [] # abstract async feature # not meant to be used directly # activates several crates used in all async runtimes -async = ["futures-util"] +async = ["futures-util", "futures-io"] # async runtimes async-std = ["async", "_async-std"] -actix = ["async", "actix-rt", "tokio_02"] -tokio = ["async", "_tokio"] +actix = ["async", "actix-rt", "tokio_02", "async-compat_02"] +tokio = ["async", "_tokio", "async-compat"] [dependencies] -actix-rt = { version = "1.1.1", optional = true } -_async-std = { version = "1.8.0", optional = true, package = "async-std" } -futures-util = { version = "0.3.8", optional = true } -_tokio = { version = "1.0.1", optional = true, package = "tokio", features = ["net"] } -tokio_02 = { version = "0.2.24", optional = true, package = "tokio", features = ["net"] } +actix-rt = { version = "1.1", optional = true } +_async-std = { version = "1.8", optional = true, package = "async-std" } +futures-util = { version = "0.3", optional = true, features = ["io"] } +_tokio = { version = "1.0", optional = true, package = "tokio", features = ["net"] } +tokio_02 = { version = "0.2", optional = true, package = "tokio", features = ["net"] } +async-compat = { version = "*", git = "https://github.com/taiki-e/async-compat", branch = "tokio1", optional = true } +async-compat_02 = { version = "0.1", optional = true, package = "async-compat" } +futures-io = { version = "0.3", optional = true } +bytes = "1.0" +string = { version = "0.2.1", default-features = false } +memchr = "2.3" diff --git a/sqlx-core/src/blocking.rs b/sqlx-core/src/blocking.rs index e0287831..26237780 100644 --- a/sqlx-core/src/blocking.rs +++ b/sqlx-core/src/blocking.rs @@ -10,9 +10,8 @@ pub use options::ConnectOptions; pub use runtime::{Blocking, Runtime}; pub mod prelude { - pub use crate::Database as _; - pub use super::ConnectOptions as _; pub use super::Connection as _; pub use super::Runtime as _; + pub use crate::Database as _; } diff --git a/sqlx-core/src/blocking/connection.rs b/sqlx-core/src/blocking/connection.rs index 3e6b4d07..e14d6302 100644 --- a/sqlx-core/src/blocking/connection.rs +++ b/sqlx-core/src/blocking/connection.rs @@ -20,8 +20,7 @@ where where Self: Sized, { - url.parse::<>::Options>()? - .connect() + url.parse::<>::Options>()?.connect() } /// Explicitly close this database connection. diff --git a/sqlx-core/src/connection.rs b/sqlx-core/src/connection.rs index 09e530fe..94f0813f 100644 --- a/sqlx-core/src/connection.rs +++ b/sqlx-core/src/connection.rs @@ -1,8 +1,8 @@ -use crate::{ConnectOptions, Database, DefaultRuntime, Runtime}; - #[cfg(feature = "async")] use futures_util::future::BoxFuture; +use crate::{ConnectOptions, Database, DefaultRuntime, Runtime}; + /// A unique connection (session) with a specific database. /// /// With a client/server model, this is equivalent to a network connection @@ -49,7 +49,8 @@ where fn connect(url: &str) -> BoxFuture<'_, crate::Result> where Self: Sized, - Rt: crate::Async, + Rt: crate::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin, { let options = url.parse::(); Box::pin(async move { options?.connect().await }) @@ -64,7 +65,8 @@ where #[cfg(feature = "async")] fn close(self) -> BoxFuture<'static, crate::Result<()>> where - Rt: crate::Async; + Rt: crate::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin; /// Checks if a connection to the database is still valid. /// @@ -76,5 +78,6 @@ where #[cfg(feature = "async")] fn ping(&mut self) -> BoxFuture<'_, crate::Result<()>> where - Rt: crate::Async; + Rt: crate::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin; } diff --git a/sqlx-core/src/error.rs b/sqlx-core/src/error.rs index e36f4212..8e147c8b 100644 --- a/sqlx-core/src/error.rs +++ b/sqlx-core/src/error.rs @@ -7,10 +7,7 @@ pub type Result = std::result::Result; #[derive(Debug)] #[non_exhaustive] pub enum Error { - Configuration { - message: Cow<'static, str>, - source: Option>, - }, + Configuration { message: Cow<'static, str>, source: Option> }, Network(std::io::Error), } @@ -21,18 +18,12 @@ impl Error { message: impl Into>, source: impl Into>, ) -> Self { - Self::Configuration { - message: message.into(), - source: Some(source.into()), - } + Self::Configuration { message: message.into(), source: Some(source.into()) } } #[doc(hidden)] pub fn configuration_msg(message: impl Into>) -> Self { - Self::Configuration { - message: message.into(), - source: None, - } + Self::Configuration { message: message.into(), source: None } } } @@ -41,15 +32,11 @@ impl Display for Error { match self { Self::Network(source) => write!(f, "network: {}", source), - Self::Configuration { - message, - source: None, - } => write!(f, "configuration: {}", message), + Self::Configuration { message, source: None } => { + write!(f, "configuration: {}", message) + } - Self::Configuration { - message, - source: Some(source), - } => { + Self::Configuration { message, source: Some(source) } => { write!(f, "configuration: {}: {}", message, source) } } @@ -59,10 +46,7 @@ impl Display for Error { impl StdError for Error { fn source(&self) -> Option<&(dyn StdError + 'static)> { match self { - Self::Configuration { - source: Some(source), - .. - } => Some(&**source), + Self::Configuration { source: Some(source), .. } => Some(&**source), Self::Network(source) => Some(source), @@ -76,3 +60,9 @@ impl From for Error { Error::Network(error) } } + +impl From for Error { + fn from(error: std::io::ErrorKind) -> Self { + Error::Network(error.into()) + } +} diff --git a/sqlx-core/src/io.rs b/sqlx-core/src/io.rs new file mode 100644 index 00000000..2b63f59c --- /dev/null +++ b/sqlx-core/src/io.rs @@ -0,0 +1,11 @@ +mod buf; +mod write; +mod buf_stream; +mod deserialize; +mod serialize; + +pub use buf::BufExt; +pub use write::WriteExt; +pub use buf_stream::BufStream; +pub use deserialize::Deserialize; +pub use serialize::Serialize; diff --git a/sqlx-core/src/io/buf.rs b/sqlx-core/src/io/buf.rs new file mode 100644 index 00000000..269395af --- /dev/null +++ b/sqlx-core/src/io/buf.rs @@ -0,0 +1,72 @@ +use std::io; + +use bytes::{Bytes, Buf}; +use memchr::memchr; +use string::String; + +// UNSAFE: _unchecked string methods +// intended for use when the protocol is *known* to always produce +// valid UTF-8 data + +pub trait BufExt: Buf { + #[allow(unsafe_code)] + unsafe fn get_str_unchecked(&mut self, n: usize) -> String; + + #[allow(unsafe_code)] + unsafe fn get_str_nul_unchecked(&mut self) -> io::Result>; +} + +impl BufExt for Bytes { + #[allow(unsafe_code)] + unsafe fn get_str_unchecked(&mut self, n: usize) -> String { + String::from_utf8_unchecked(self.split_to(n)) + } + + #[allow(unsafe_code)] + unsafe fn get_str_nul_unchecked(&mut self) -> io::Result> { + let nul = memchr(b'\0', self).ok_or(io::ErrorKind::InvalidData)?; + + Ok(String::from_utf8_unchecked(self.split_to(nul + 1).slice(..nul))) + } +} + +#[cfg(test)] +mod tests { + use std::io; + use bytes::{Bytes, Buf}; + use super::BufExt; + + #[test] + fn test_get_str() { + let mut buf = Bytes::from_static(b"Hello World\0"); + + #[allow(unsafe_code)] + let s = unsafe { buf.get_str_unchecked(5) }; + + buf.advance(1); + + #[allow(unsafe_code)] + let s2 = unsafe { buf.get_str_unchecked(5) }; + + assert_eq!(&s, "Hello"); + assert_eq!(&s2, "World"); + } + + #[test] + fn test_get_str_nul() -> io::Result<()> { + let mut buf = Bytes::from_static(b"Hello\0 World\0"); + + #[allow(unsafe_code)] + let s = unsafe { buf.get_str_nul_unchecked()? }; + + buf.advance(1); + + #[allow(unsafe_code)] + let s2 = unsafe { buf.get_str_nul_unchecked()? }; + + assert_eq!(&s, "Hello"); + assert_eq!(&s2, "World"); + + Ok(()) + } +} diff --git a/sqlx-core/src/io/buf_stream.rs b/sqlx-core/src/io/buf_stream.rs new file mode 100644 index 00000000..50387f26 --- /dev/null +++ b/sqlx-core/src/io/buf_stream.rs @@ -0,0 +1,92 @@ +#[cfg(feature = "blocking")] +use std::io::{Read, Write}; +use std::slice::from_raw_parts_mut; + +use bytes::{BufMut, Bytes, BytesMut}; +#[cfg(feature = "async")] +use futures_io::{AsyncRead, AsyncWrite}; +#[cfg(feature = "async")] +use futures_util::{AsyncReadExt, AsyncWriteExt}; + +/// Wraps a stream and buffers input and output to and from it. +/// +/// It can be excessively inefficient to work directly with a `Read` or `Write`. For example, +/// every call to `read` or `write` on `TcpStream` results in a system call (leading to +/// a network interaction). `BufStream` keeps a read and write buffer with infrequent calls +/// to `read` and `write` on the underlying stream. +/// +pub struct BufStream { + stream: S, + + // (r)ead buffer + rbuf: BytesMut, + + // (w)rite buffer + wbuf: Vec, + + // offset into [wbuf] that a previous write operation has written into + wbuf_offset: usize, +} + +impl BufStream { + pub fn with_capacity(stream: S, read: usize, write: usize) -> Self { + Self { + stream, + rbuf: BytesMut::with_capacity(read), + wbuf: Vec::with_capacity(write), + wbuf_offset: 0, + } + } + + pub fn get(&self, offset: usize, n: usize) -> &[u8] { + &(self.rbuf.as_ref())[offset..(offset + n)] + } + + pub fn take(&mut self, n: usize) -> Bytes { + self.rbuf.split_to(n).freeze() + } + + pub fn consume(&mut self, n: usize) { + let _ = self.take(n); + } +} + +#[cfg(feature = "async")] +impl BufStream +where + S: AsyncRead + AsyncWrite + Unpin, +{ + pub async fn read_async(&mut self, n: usize) -> crate::Result<()> { + // // before waiting to receive data + // // ensure that the write buffer is flushed + // if !self.wbuf.is_empty() { + // self.flush().await?; + // } + + // while our read buffer is too small to satisfy the requested amount + while self.rbuf.len() < n { + // ensure that there is room in the read buffer + self.rbuf.reserve(n.max(128)); + + #[allow(unsafe_code)] + unsafe { + // prepare a chunk of uninitialized memory to write to + // this is UB if the Read impl of the stream reads from the write buffer + let b = self.rbuf.chunk_mut(); + let b = from_raw_parts_mut(b.as_mut_ptr(), b.len()); + + // read as much as we can and return when the stream or our buffer is exhausted + let n = self.stream.read(b).await?; + + // [!] read more than the length of our buffer + debug_assert!(n <= b.len()); + + // update the len of the read buffer to let the safe world that its okay + // to look at these bytes now + self.rbuf.advance_mut(n); + } + } + + Ok(()) + } +} diff --git a/sqlx-core/src/io/deserialize.rs b/sqlx-core/src/io/deserialize.rs new file mode 100644 index 00000000..93be7384 --- /dev/null +++ b/sqlx-core/src/io/deserialize.rs @@ -0,0 +1,13 @@ +use bytes::Bytes; + +pub trait Deserialize<'de, Cx = ()>: Sized { + #[inline] + fn deserialize(buf: Bytes) -> crate::Result + where + Self: Deserialize<'de, ()>, + { + Self::deserialize_with(buf, ()) + } + + fn deserialize_with(buf: Bytes, context: Cx) -> crate::Result; +} diff --git a/sqlx-core/src/io/serialize.rs b/sqlx-core/src/io/serialize.rs new file mode 100644 index 00000000..ffda265e --- /dev/null +++ b/sqlx-core/src/io/serialize.rs @@ -0,0 +1,11 @@ +pub trait Serialize<'ser, Cx = ()>: Sized { + #[inline] + fn serialize(&self, buf: &mut Vec) -> crate::Result<()> + where + Self: Serialize<'ser, ()>, + { + self.serialize_with(buf, ()) + } + + fn serialize_with(&self, buf: &mut Vec, context: Cx) -> crate::Result<()>; +} diff --git a/sqlx-core/src/io/write.rs b/sqlx-core/src/io/write.rs new file mode 100644 index 00000000..272d978b --- /dev/null +++ b/sqlx-core/src/io/write.rs @@ -0,0 +1,34 @@ +pub trait WriteExt { + fn write_str_nul(&mut self, s: &str); + fn write_maybe_str_nul(&mut self, s: Option<&str>); +} + +impl WriteExt for Vec { + fn write_str_nul(&mut self, s: &str) { + self.reserve(s.len() + 1); + self.extend_from_slice(s.as_bytes()); + self.push(0); + } + + fn write_maybe_str_nul(&mut self, s: Option<&str>) { + if let Some(s) = s { + self.reserve(s.len() + 1); + self.extend_from_slice(s.as_bytes()); + } + + self.push(0); + } +} + +#[cfg(test)] +mod tests { + use super::WriteExt; + + #[test] + fn write_str() { + let mut buf = Vec::new(); + buf.write_str_nul("this is a random dice roll"); + + assert_eq!(&buf, b"this is a random dice roll\0"); + } +} diff --git a/sqlx-core/src/lib.rs b/sqlx-core/src/lib.rs index cbe6089a..9cfc4701 100644 --- a/sqlx-core/src/lib.rs +++ b/sqlx-core/src/lib.rs @@ -33,6 +33,9 @@ mod error; mod options; mod runtime; +#[doc(hidden)] +pub mod io; + #[cfg(feature = "blocking")] pub mod blocking; @@ -40,19 +43,15 @@ pub use connection::Connection; pub use database::{Database, HasOutput}; pub use error::{Error, Result}; pub use options::ConnectOptions; -pub use runtime::Runtime; - -#[cfg(feature = "async-std")] -pub use runtime::AsyncStd; - -#[cfg(feature = "tokio")] -pub use runtime::Tokio; - #[cfg(feature = "actix")] pub use runtime::Actix; - #[cfg(feature = "async")] -pub use runtime::Async; +pub use runtime::AsyncRuntime; +#[cfg(feature = "async-std")] +pub use runtime::AsyncStd; +pub use runtime::Runtime; +#[cfg(feature = "tokio")] +pub use runtime::Tokio; // pick a default runtime // this is so existing applications in SQLx pre 0.6 work and to @@ -78,11 +77,10 @@ pub type DefaultRuntime = blocking::Blocking; pub type DefaultRuntime = (); pub mod prelude { + #[cfg(all(not(feature = "async"), feature = "blocking"))] + pub use super::blocking::prelude::*; pub use super::ConnectOptions as _; pub use super::Connection as _; pub use super::Database as _; pub use super::Runtime as _; - - #[cfg(all(not(feature = "async"), feature = "blocking"))] - pub use super::blocking::prelude::*; } diff --git a/sqlx-core/src/options.rs b/sqlx-core/src/options.rs index cf9cfe8b..414bc5ce 100644 --- a/sqlx-core/src/options.rs +++ b/sqlx-core/src/options.rs @@ -17,5 +17,6 @@ where fn connect(&self) -> futures_util::future::BoxFuture<'_, crate::Result> where Self::Connection: Sized, - Rt: crate::Async; + Rt: crate::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin; } diff --git a/sqlx-core/src/runtime.rs b/sqlx-core/src/runtime.rs index 383424a6..3d1f6b77 100644 --- a/sqlx-core/src/runtime.rs +++ b/sqlx-core/src/runtime.rs @@ -7,41 +7,35 @@ mod actix; #[cfg(feature = "tokio")] mod tokio; -#[cfg(feature = "async-std")] -pub use self::async_std::AsyncStd; - -#[cfg(feature = "tokio")] -pub use self::tokio::Tokio; - #[cfg(feature = "actix")] pub use self::actix::Actix; +#[cfg(feature = "async-std")] +pub use self::async_std::AsyncStd; +#[cfg(feature = "tokio")] +pub use self::tokio::Tokio; /// Describes a set of types and functions used to open and manage /// resources within SQLx. pub trait Runtime: 'static + Send + Sync { type TcpStream: Send; +} +#[cfg(feature = "async")] +pub trait AsyncRuntime: Runtime +where + Self::TcpStream: futures_io::AsyncRead, +{ /// Opens a TCP connection to a remote host at the specified port. - #[cfg(feature = "async")] - #[allow(unused_variables)] fn connect_tcp( host: &str, port: u16, - ) -> futures_util::future::BoxFuture<'_, std::io::Result> - where - Self: Async, - { - // re-implemented for async runtimes - // for sync runtimes, this cannot be implemented but the compiler - // with guarantee it won't be called - // see: https://github.com/rust-lang/rust/issues/48214 - unimplemented!() - } + ) -> futures_util::future::BoxFuture<'_, std::io::Result>; } -/// Marker trait that identifies a `Runtime` as supporting asynchronous I/O. #[cfg(feature = "async")] -pub trait Async: Runtime {} +pub trait AsyncRead { + fn read(&mut self, buf: &mut [u8]) -> futures_util::future::BoxFuture<'_, u64>; +} // when the async feature is not specified, this is an empty trait // we implement `()` for it to allow the lib to still compile diff --git a/sqlx-core/src/runtime/actix.rs b/sqlx-core/src/runtime/actix.rs index cdc6ad30..0fbe6545 100644 --- a/sqlx-core/src/runtime/actix.rs +++ b/sqlx-core/src/runtime/actix.rs @@ -1,9 +1,10 @@ use std::io; use actix_rt::net::TcpStream; +use async_compat_02::Compat; use futures_util::{future::BoxFuture, FutureExt}; -use crate::{Async, Runtime}; +use crate::{AsyncRuntime, Runtime}; /// Actix SQLx runtime. Uses [`actix-rt`][actix_rt] to provide [`Runtime`]. /// @@ -15,12 +16,15 @@ use crate::{Async, Runtime}; #[derive(Debug)] pub struct Actix; -impl Async for Actix {} - impl Runtime for Actix { - type TcpStream = TcpStream; + type TcpStream = Compat; +} +impl AsyncRuntime for Actix +where + Self::TcpStream: futures_io::AsyncRead, +{ fn connect_tcp(host: &str, port: u16) -> BoxFuture<'_, io::Result> { - TcpStream::connect((host, port)).boxed() + TcpStream::connect((host, port)).map_ok(Compat::new).boxed() } } diff --git a/sqlx-core/src/runtime/async_std.rs b/sqlx-core/src/runtime/async_std.rs index b4dcec53..8c6e473a 100644 --- a/sqlx-core/src/runtime/async_std.rs +++ b/sqlx-core/src/runtime/async_std.rs @@ -3,18 +3,18 @@ use std::io; use async_std::{net::TcpStream, task::block_on}; use futures_util::{future::BoxFuture, FutureExt}; -use crate::{Async, Runtime}; +use crate::{AsyncRuntime, Runtime}; /// [`async-std`](async_std) implementation of [`Runtime`]. #[cfg_attr(doc_cfg, doc(cfg(feature = "async-std")))] #[derive(Debug)] pub struct AsyncStd; -impl Async for AsyncStd {} - impl Runtime for AsyncStd { type TcpStream = TcpStream; +} +impl AsyncRuntime for AsyncStd { fn connect_tcp(host: &str, port: u16) -> BoxFuture<'_, io::Result> { TcpStream::connect((host, port)).boxed() } @@ -23,6 +23,6 @@ impl Runtime for AsyncStd { #[cfg(feature = "blocking")] impl crate::blocking::Runtime for AsyncStd { fn connect_tcp(host: &str, port: u16) -> io::Result { - block_on(::connect_tcp(host, port)) + block_on(::connect_tcp(host, port)) } } diff --git a/sqlx-core/src/runtime/tokio.rs b/sqlx-core/src/runtime/tokio.rs index 3ccba2ed..05f6ba1e 100644 --- a/sqlx-core/src/runtime/tokio.rs +++ b/sqlx-core/src/runtime/tokio.rs @@ -1,9 +1,10 @@ use std::io; -use futures_util::{future::BoxFuture, FutureExt}; +use async_compat::Compat; +use futures_util::{future::BoxFuture, FutureExt, TryFutureExt}; use tokio::net::TcpStream; -use crate::{Async, Runtime}; +use crate::{AsyncRuntime, Runtime}; /// Tokio SQLx runtime. Uses [`tokio`] to provide [`Runtime`]. /// @@ -13,12 +14,12 @@ use crate::{Async, Runtime}; #[derive(Debug)] pub struct Tokio; -impl Async for Tokio {} - impl Runtime for Tokio { - type TcpStream = TcpStream; + type TcpStream = Compat; +} +impl AsyncRuntime for Tokio { fn connect_tcp(host: &str, port: u16) -> BoxFuture<'_, io::Result> { - TcpStream::connect((host, port)).boxed() + TcpStream::connect((host, port)).map_ok(Compat::new).boxed() } } diff --git a/sqlx-mysql/Cargo.toml b/sqlx-mysql/Cargo.toml index e7b00adb..24709462 100644 --- a/sqlx-mysql/Cargo.toml +++ b/sqlx-mysql/Cargo.toml @@ -24,7 +24,7 @@ blocking = ["sqlx-core/blocking"] # async runtime # not meant to be used directly -async = ["futures-util", "sqlx-core/async"] +async = ["futures-util", "sqlx-core/async", "futures-io"] [dependencies] sqlx-core = { version = "0.6.0-pre", path = "../sqlx-core" } @@ -32,3 +32,8 @@ futures-util = { version = "0.3.8", optional = true } either = "1.6.1" url = "2.2.0" percent-encoding = "2.1.0" +futures-io = { version = "0.3", optional = true } +bytes = "1.0" +memchr = "2.3" +bitflags = "1.2" +string = { version = "0.2.1", default-features = false } diff --git a/sqlx-mysql/src/blocking/options.rs b/sqlx-mysql/src/blocking/options.rs index 124f71b2..3f8f4177 100644 --- a/sqlx-mysql/src/blocking/options.rs +++ b/sqlx-mysql/src/blocking/options.rs @@ -9,8 +9,9 @@ where Self::Connection: sqlx_core::Connection + Connection, { fn connect(&self) -> Result> { - let stream = ::connect_tcp(self.get_host(), self.get_port())?; - - Ok(MySqlConnection { stream }) + // let stream = ::connect_tcp(self.get_host(), self.get_port())?; + // + // Ok(MySqlConnection { stream }) + todo!() } } diff --git a/sqlx-mysql/src/connection.rs b/sqlx-mysql/src/connection.rs index 37af485b..72106ca7 100644 --- a/sqlx-mysql/src/connection.rs +++ b/sqlx-mysql/src/connection.rs @@ -1,14 +1,46 @@ use std::fmt::{self, Debug, Formatter}; +use sqlx_core::io::BufStream; use sqlx_core::{Connection, DefaultRuntime, Runtime}; +use crate::protocol::Capabilities; use crate::{MySql, MySqlConnectOptions}; +#[cfg(feature = "async")] +pub(crate) mod establish; + pub struct MySqlConnection where Rt: Runtime, { - pub(crate) stream: Rt::TcpStream, + stream: BufStream, + connection_id: u32, + capabilities: Capabilities, +} + +impl MySqlConnection +where + Rt: Runtime, +{ + pub(crate) fn new(stream: Rt::TcpStream) -> Self { + Self { + stream: BufStream::with_capacity(stream, 4096, 1024), + connection_id: 0, + capabilities: Capabilities::LONG_PASSWORD + | Capabilities::LONG_FLAG + | Capabilities::IGNORE_SPACE + | Capabilities::TRANSACTIONS + | Capabilities::SECURE_CONNECTION + | Capabilities::MULTI_STATEMENTS + | Capabilities::MULTI_RESULTS + | Capabilities::PS_MULTI_RESULTS + | Capabilities::PLUGIN_AUTH + | Capabilities::PLUGIN_AUTH_LENENC_DATA + | Capabilities::CAN_HANDLE_EXPIRED_PASSWORDS + | Capabilities::SESSION_TRACK + | Capabilities::DEPRECATE_EOF, + } + } } impl Debug for MySqlConnection @@ -31,7 +63,8 @@ where #[cfg(feature = "async")] fn close(self) -> futures_util::future::BoxFuture<'static, sqlx_core::Result<()>> where - Rt: sqlx_core::Async, + Rt: sqlx_core::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin, { unimplemented!() } @@ -39,7 +72,8 @@ where #[cfg(feature = "async")] fn ping(&mut self) -> futures_util::future::BoxFuture<'_, sqlx_core::Result<()>> where - Rt: sqlx_core::Async, + Rt: sqlx_core::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin, { unimplemented!() } diff --git a/sqlx-mysql/src/connection/establish.rs b/sqlx-mysql/src/connection/establish.rs new file mode 100644 index 00000000..e0a8b077 --- /dev/null +++ b/sqlx-mysql/src/connection/establish.rs @@ -0,0 +1,56 @@ +use bytes::Buf; +use futures_io::{AsyncRead, AsyncWrite}; +use sqlx_core::io::{BufStream, Deserialize}; +use sqlx_core::{AsyncRuntime, Result, Runtime}; + +use crate::protocol::Handshake; +use crate::{MySqlConnectOptions, MySqlConnection}; + +// https://dev.mysql.com/doc/internals/en/connection-phase.html + +// the connection phase (establish) performs these tasks: +// - exchange the capabilities of client and server +// - setup SSL communication channel if requested +// - authenticate the client against the server + +// the server may immediately send an ERR packet and finish the handshake +// or send a [InitialHandshake] + +impl MySqlConnection +where + Rt: AsyncRuntime, + ::TcpStream: Unpin + AsyncWrite + AsyncRead, +{ + pub(crate) async fn establish_async(options: &MySqlConnectOptions) -> Result { + let stream = Rt::connect_tcp(options.get_host(), options.get_port()).await?; + let mut self_ = Self::new(stream); + + // FIXME: Handle potential ERR packet here + let handshake = self_.read_packet_async::().await?; + println!("{:#?}", handshake); + + Ok(self_) + } + + async fn read_packet_async<'de, T>(&'de mut self) -> Result + where + T: Deserialize<'de>, + { + // https://dev.mysql.com/doc/internals/en/mysql-packet.html + self.stream.read_async(4).await?; + + let payload_len: usize = self.stream.get(0, 3).get_int_le(3) as usize; + + // FIXME: handle split packets + assert_ne!(payload_len, 0xFF_FF_FF); + + let _seq_no = self.stream.get(3, 1).get_i8(); + + self.stream.read_async(4 + payload_len).await?; + + self.stream.consume(4); + let payload = self.stream.take(payload_len); + + T::deserialize(payload) + } +} diff --git a/sqlx-mysql/src/io.rs b/sqlx-mysql/src/io.rs new file mode 100644 index 00000000..b32a8d0f --- /dev/null +++ b/sqlx-mysql/src/io.rs @@ -0,0 +1,5 @@ +mod write; +mod buf; + +pub(crate) use write::MySqlWriteExt; +pub(crate) use buf::MySqlBufExt; diff --git a/sqlx-mysql/src/io/buf.rs b/sqlx-mysql/src/io/buf.rs new file mode 100644 index 00000000..57f5a7e6 --- /dev/null +++ b/sqlx-mysql/src/io/buf.rs @@ -0,0 +1,49 @@ +use bytes::{Bytes, Buf}; +use string::String; +use sqlx_core::io::BufExt; + +// UNSAFE: _unchecked string methods +// intended for use when the protocol is *known* to always produce +// valid UTF-8 data + +pub(crate) trait MySqlBufExt: BufExt { + fn get_uint_lenenc(&mut self) -> u64; + + #[allow(unsafe_code)] + unsafe fn get_str_lenenc_unchecked(&mut self) -> String; + + fn get_bytes_lenenc(&mut self) -> Bytes; +} + +impl MySqlBufExt for Bytes { + fn get_uint_lenenc(&mut self) -> u64 { + // https://dev.mysql.com/doc/internals/en/integer.html#packet-Protocol::LengthEncodedInteger + + match self.get_u8() { + // NOTE: 0xFB represents NULL in TextResultRow + 0xfb => unreachable!("unexpected 0xFB (NULL) in `get_uint_lenenc`"), + + 0xfc => u64::from(self.get_u16_le()), + 0xfd => self.get_uint_le(3), + 0xfe => self.get_u64_le(), + + // NOTE: 0xFF may be the first byte of an ERR packet + 0xff => unreachable!("unexpected 0xFF (undefined) in `get_uint_lenenc`"), + + value => u64::from(value) + } + } + + #[allow(unsafe_code)] + unsafe fn get_str_lenenc_unchecked(&mut self) -> String { + let len = self.get_uint_lenenc() as usize; + + self.get_str_unchecked(len) + } + + fn get_bytes_lenenc(&mut self) -> Bytes { + let len = self.get_uint_lenenc() as usize; + + self.split_to(len) + } +} diff --git a/sqlx-mysql/src/io/write.rs b/sqlx-mysql/src/io/write.rs new file mode 100644 index 00000000..b631610e --- /dev/null +++ b/sqlx-mysql/src/io/write.rs @@ -0,0 +1,137 @@ +pub(crate) trait MySqlWriteExt: sqlx_core::io::WriteExt { + fn write_uint_lenenc(&mut self, value: u64); + + fn write_str_lenenc(&mut self, value: &str); + + fn write_bytes_lenenc(&mut self, value: &[u8]); +} + +impl MySqlWriteExt for Vec { + fn write_uint_lenenc(&mut self, value: u64) { + // https://dev.mysql.com/doc/internals/en/integer.html + // https://mariadb.com/kb/en/library/protocol-data-types/#length-encoded-integers + + if value < 251 { + // if the value is < 251, it is stored as a 1-byte integer + self.push(value as u8); + } else if value < 0x1_00_00 { + // if the value is ≥ 251 and < (2 ** 16), it is stored as fc + 2-byte integer + self.reserve(3); + self.push(0xfc); + self.extend_from_slice(&(value as u16).to_le_bytes()); + } else if value < 0x1_00_00_00 { + // if the value is ≥ (2 ** 16) and < (2 ** 24), it is stored as fd + 3-byte integer + self.reserve(4); + self.push(0xfd); + self.extend_from_slice(&(value as u32).to_le_bytes()[..3]); + } else { + // if the value is ≥ (2 ** 24) and < (2 ** 64) it is stored as fe + 8-byte integer + self.reserve(9); + self.push(0xfe); + self.extend_from_slice(&value.to_le_bytes()); + } + } + + #[inline] + fn write_str_lenenc(&mut self, value: &str) { + self.write_bytes_lenenc(value.as_bytes()); + } + + fn write_bytes_lenenc(&mut self, value: &[u8]) { + self.write_uint_lenenc(value.len() as u64); + self.extend_from_slice(value); + } +} + +#[cfg(test)] +mod tests { + use super::MySqlWriteExt; + + #[test] + fn write_int_lenenc_u8() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFA as u64); + + assert_eq!(&buf[..], b"\xFA"); + } + + #[test] + fn write_int_lenenc_u16() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(std::u16::MAX as u64); + + assert_eq!(&buf[..], b"\xFC\xFF\xFF"); + } + + #[test] + fn write_int_lenenc_u24() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFF_FF_FF as u64); + + assert_eq!(&buf[..], b"\xFD\xFF\xFF\xFF"); + } + + #[test] + fn write_int_lenenc_u64() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(std::u64::MAX); + + assert_eq!(&buf[..], b"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); + } + + #[test] + fn write_int_lenenc_fb() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFB as u64); + + assert_eq!(&buf[..], b"\xFC\xFB\x00"); + } + + #[test] + fn write_int_lenenc_fc() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFC as u64); + + assert_eq!(&buf[..], b"\xFC\xFC\x00"); + } + + #[test] + fn write_int_lenenc_fd() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFD as u64); + + assert_eq!(&buf[..], b"\xFC\xFD\x00"); + } + + #[test] + fn write_int_lenenc_fe() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFE as u64); + + assert_eq!(&buf[..], b"\xFC\xFE\x00"); + } + + #[test] + fn write_int_lenenc_ff() { + let mut buf = Vec::new(); + buf.write_uint_lenenc(0xFF as u64); + + assert_eq!(&buf[..], b"\xFC\xFF\x00"); + } + + #[test] + fn write_string_lenenc() { + let mut buf = Vec::new(); + buf.write_str_lenenc("random_string"); + + assert_eq!(&buf[..], b"\x0Drandom_string"); + } + + #[test] + fn write_byte_lenenc() { + let mut buf = Vec::new(); + buf.write_bytes_lenenc(b"random_string"); + + assert_eq!(&buf[..], b"\x0Drandom_string"); + } +} diff --git a/sqlx-mysql/src/lib.rs b/sqlx-mysql/src/lib.rs index 09e15b51..41ec4ec0 100644 --- a/sqlx-mysql/src/lib.rs +++ b/sqlx-mysql/src/lib.rs @@ -21,7 +21,9 @@ mod connection; mod database; +mod io; mod options; +mod protocol; #[cfg(feature = "blocking")] mod blocking; diff --git a/sqlx-mysql/src/options.rs b/sqlx-mysql/src/options.rs index c20107e2..d08afc17 100644 --- a/sqlx-mysql/src/options.rs +++ b/sqlx-mysql/src/options.rs @@ -83,20 +83,12 @@ where { /// Returns the hostname of the database server. pub fn get_host(&self) -> &str { - self.address - .as_ref() - .left() - .map(|(host, _)| &**host) - .unwrap_or(default::HOST) + self.address.as_ref().left().map(|(host, _)| &**host).unwrap_or(default::HOST) } /// Returns the TCP port number of the database server. pub fn get_port(&self) -> u16 { - self.address - .as_ref() - .left() - .map(|(_, port)| *port) - .unwrap_or(default::PORT) + self.address.as_ref().left().map(|(_, port)| *port).unwrap_or(default::PORT) } /// Returns the path to the Unix domain socket, if one is configured. @@ -140,12 +132,9 @@ where fn connect(&self) -> futures_util::future::BoxFuture<'_, sqlx_core::Result> where Self::Connection: Sized, - Rt: sqlx_core::Async, + Rt: sqlx_core::AsyncRuntime, + ::TcpStream: futures_io::AsyncRead + futures_io::AsyncWrite + Unpin, { - futures_util::FutureExt::boxed(async move { - let stream = Rt::connect_tcp(self.get_host(), self.get_port()).await?; - - Ok(MySqlConnection { stream }) - }) + futures_util::FutureExt::boxed(MySqlConnection::establish_async(self)) } } diff --git a/sqlx-mysql/src/options/parse.rs b/sqlx-mysql/src/options/parse.rs index 44cba3cf..d210f27e 100644 --- a/sqlx-mysql/src/options/parse.rs +++ b/sqlx-mysql/src/options/parse.rs @@ -13,9 +13,7 @@ where type Err = Error; fn from_str(s: &str) -> Result { - let url: Url = s - .parse() - .map_err(|error| Error::configuration("database url", error))?; + let url: Url = s.parse().map_err(|error| Error::configuration("database url", error))?; if !matches!(url.scheme(), "mysql") { return Err(Error::configuration_msg(format!( @@ -36,17 +34,11 @@ where let username = url.username(); if !username.is_empty() { - options.username(percent_decode_str_utf8( - username, - "username in database url", - )?); + options.username(percent_decode_str_utf8(username, "username in database url")?); } if let Some(password) = url.password() { - options.password(percent_decode_str_utf8( - password, - "password in database url", - )?); + options.password(percent_decode_str_utf8(password, "password in database url")?); } let mut path = url.path(); @@ -113,11 +105,12 @@ fn percent_decode_str_utf8(value: &str, context: &str) -> Result #[cfg(test)] mod tests { - use super::MySqlConnectOptions; use std::path::Path; + use super::MySqlConnectOptions; + #[test] - fn it_should_parse() { + fn parse() { let url = "mysql://user:password@hostname:5432/database?timezone=system&charset=utf8"; let options: MySqlConnectOptions = url.parse().unwrap(); @@ -131,7 +124,7 @@ mod tests { } #[test] - fn it_should_parse_with_defaults() { + fn parse_with_defaults() { let url = "mysql://"; let options: MySqlConnectOptions = url.parse().unwrap(); @@ -145,21 +138,18 @@ mod tests { } #[test] - fn it_should_parse_socket_from_query() { + fn parse_socket_from_query() { let url = "mysql://user:password@localhost/database?socket=/var/run/mysqld/mysqld.sock"; let options: MySqlConnectOptions = url.parse().unwrap(); assert_eq!(options.get_username(), Some("user")); assert_eq!(options.get_password(), Some("password")); assert_eq!(options.get_database(), Some("database")); - assert_eq!( - options.get_socket(), - Some(Path::new("/var/run/mysqld/mysqld.sock")) - ); + assert_eq!(options.get_socket(), Some(Path::new("/var/run/mysqld/mysqld.sock"))); } #[test] - fn it_should_parse_socket_from_host() { + fn parse_socket_from_host() { // socket path in host requires URL encoding – but does work let url = "mysql://user:password@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/database"; let options: MySqlConnectOptions = url.parse().unwrap(); @@ -167,21 +157,18 @@ mod tests { assert_eq!(options.get_username(), Some("user")); assert_eq!(options.get_password(), Some("password")); assert_eq!(options.get_database(), Some("database")); - assert_eq!( - options.get_socket(), - Some(Path::new("/var/run/mysqld/mysqld.sock")) - ); + assert_eq!(options.get_socket(), Some(Path::new("/var/run/mysqld/mysqld.sock"))); } #[test] #[should_panic] - fn it_should_fail_to_parse_non_mysql() { + fn fail_to_parse_non_mysql() { let url = "postgres://user:password@hostname:5432/database?timezone=system&charset=utf8"; let _: MySqlConnectOptions = url.parse().unwrap(); } #[test] - fn it_should_parse_username_with_at_sign() { + fn parse_username_with_at_sign() { let url = "mysql://user@hostname:password@hostname:5432/database"; let options: MySqlConnectOptions = url.parse().unwrap(); @@ -189,7 +176,7 @@ mod tests { } #[test] - fn it_should_parse_password_with_non_ascii_chars() { + fn parse_password_with_non_ascii_chars() { let url = "mysql://username:p@ssw0rd@hostname:5432/database"; let options: MySqlConnectOptions = url.parse().unwrap(); diff --git a/sqlx-mysql/src/protocol.rs b/sqlx-mysql/src/protocol.rs new file mode 100644 index 00000000..fb96dba0 --- /dev/null +++ b/sqlx-mysql/src/protocol.rs @@ -0,0 +1,9 @@ +mod capabilities; +mod handshake; +mod handshake_response; +mod status; + +pub(crate) use capabilities::Capabilities; +pub(crate) use handshake::Handshake; +pub(crate) use handshake_response::HandshakeResponse; +pub(crate) use status::ServerStatus; diff --git a/sqlx-mysql/src/protocol/capabilities.rs b/sqlx-mysql/src/protocol/capabilities.rs new file mode 100644 index 00000000..8e47ed7b --- /dev/null +++ b/sqlx-mysql/src/protocol/capabilities.rs @@ -0,0 +1,80 @@ +// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags +// https://dev.mysql.com/doc/dev/mysql-server/8.0.12/group__group__cs__capabilities__flags.html +// https://mariadb.com/kb/en/library/connection/#capabilities +bitflags::bitflags! { + pub struct Capabilities: u64 { + // use the improved version of "old password auth" + // assumed to be set since 4.1 + const LONG_PASSWORD = 0x00000001; + + // send found (read: matched) rows instead of affected rows in the EOF packet + const FOUND_ROWS = 0x00000002; + + // longer flags for column metadata + // not used if PROTOCOL_41 is used (long flags are always received) + const LONG_FLAG = 0x00000004; + + // database (schema) name can be specified on connect in Handshake Response Packet + const CONNECT_WITH_DB = 0x00000008; + + // do not permit `database.table.column` + const NO_SCHEMA = 0x00000010; + + // compression protocol supported + // todo: expose in MySqlConnectOptions + const COMPRESS = 0x00000020; + + // legacy flag to enable special ODBC handling + // no handling since MySQL v3.22 + const ODBC = 0x00000040; + + // enable LOAD DATA LOCAL + const LOCAL_FILES = 0x00000080; + + // SQL parser can ignore spaces before '(' + const IGNORE_SPACE = 0x00000100; + + // uses the 4.1+ protocol + const PROTOCOL_41 = 0x00000200; + + // this is an interactive client + // wait_timeout versus wait_interactive_timeout. + const INTERACTIVE = 0x00000400; + + // use SSL encryption for this session + const SSL = 0x00000800; + + // EOF packets will contain transaction status flags + const TRANSACTIONS = 0x00002000; + + // support native 4.1+ authentication + const SECURE_CONNECTION = 0x00008000; + + // can handle multiple statements in COM_QUERY and COM_STMT_PREPARE + const MULTI_STATEMENTS = 0x00010000; + + // can send multiple result sets for COM_QUERY + const MULTI_RESULTS = 0x00020000; + + // can send multiple result sets for COM_STMT_EXECUTE + const PS_MULTI_RESULTS = 0x00040000; + + // supports authentication plugins + const PLUGIN_AUTH = 0x00080000; + + // permits connection attributes + const CONNECT_ATTRS = 0x00100000; + + // enable authentication response packet to be larger than 255 bytes. + const PLUGIN_AUTH_LENENC_DATA = 0x00200000; + + // can handle connection for a user account with expired passwords + const CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000; + + // capable of handling server state change information in an OK packet + const SESSION_TRACK = 0x00800000; + + // client no longer needs EOF_Packet and will use OK_Packet instead. + const DEPRECATE_EOF = 0x01000000; + } +} diff --git a/sqlx-mysql/src/protocol/handshake.rs b/sqlx-mysql/src/protocol/handshake.rs new file mode 100644 index 00000000..12f09960 --- /dev/null +++ b/sqlx-mysql/src/protocol/handshake.rs @@ -0,0 +1,429 @@ +use bytes::buf::Chain; +use bytes::{Buf, Bytes}; +use memchr::memchr; +use sqlx_core::io::{BufExt, Deserialize}; +use sqlx_core::Result; + +use crate::protocol::{Capabilities, ServerStatus}; + +// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeV10 +// https://mariadb.com/kb/en/connection/#initial-handshake-packet + +#[derive(Debug)] +pub(crate) struct Handshake { + // (0x0a) protocol version + pub(crate) protocol_version: u8, + + // human-readable server version + pub(crate) server_version: string::String, + + pub(crate) connection_id: u32, + + pub(crate) capabilities: Capabilities, + pub(crate) status: ServerStatus, + + // default server character set + pub(crate) charset: Option, + + pub(crate) auth_plugin_data: Chain, + + // name of the auth_method that the auth_plugin_data belongs to + pub(crate) auth_plugin_name: Option>, +} + +impl Deserialize<'_> for Handshake { + fn deserialize_with(mut buf: Bytes, _: ()) -> Result { + println!("{:?}", buf); + + let protocol_version = buf.get_u8(); + + // UNSAFE: server version is known to be ASCII + #[allow(unsafe_code)] + let server_version = unsafe { buf.get_str_nul_unchecked()? }; + + let connection_id = buf.get_u32_le(); + + // first 8 bytes of the auth-plugin data + let auth_plugin_data_1 = buf.split_to(8); + + buf.advance(1); // filler [00] + + let mut capabilities = Capabilities::from_bits_truncate(buf.get_u16_le().into()); + + // from this point on, all additional packet fields are **optional** + // the packet payload can end at any time + + let charset = if buf.is_empty() { None } else { Some(buf.get_u8()) }; + + let status = if buf.is_empty() { + ServerStatus::empty() + } else { + ServerStatus::from_bits_truncate(buf.get_u16_le()) + }; + + if !buf.is_empty() { + // upper 2 bytes of the capabilities flags + capabilities |= Capabilities::from_bits_truncate(u64::from(buf.get_u16_le()) << 16); + } + + let auth_plugin_data_len = if capabilities.contains(Capabilities::PLUGIN_AUTH) { + buf.get_u8() + } else { + // a single 0 byte, if present + if !buf.is_empty() { + buf.advance(1); + } + + 0 + }; + + if buf.len() >= 10 { + // reserved (10, 0 bytes) + buf.advance(10); + } + + let mut auth_plugin_data_2 = Bytes::new(); + let mut auth_plugin_name = None; + + if capabilities.contains(Capabilities::SECURE_CONNECTION) { + let len = (if auth_plugin_data_len > 8 { auth_plugin_data_len - 8 } else { 0 }).max(13); + + auth_plugin_data_2 = buf.split_to(len as usize); + + if capabilities.contains(Capabilities::PLUGIN_AUTH) { + // due to Bug#59453 the auth-plugin-name is missing the terminating NUL-char + // in versions prior to 5.5.10 and 5.6.2 + + // ref: https://bugs.mysql.com/bug.php?id=59453 + + // read to NUL or read to the end if we can't find a NUL + + let auth_plugin_name_end = + memchr(b'\0', &buf).map(|end| end - 1).unwrap_or(buf.len()); + + // UNSAFE: auth plugin names are known to be ASCII + #[allow(unsafe_code)] + let auth_plugin_name_ = + unsafe { Some(buf.get_str_unchecked(auth_plugin_name_end)) }; + + auth_plugin_name = auth_plugin_name_; + } + } + + Ok(Self { + protocol_version, + server_version, + connection_id, + charset, + capabilities, + status, + auth_plugin_data: auth_plugin_data_1.chain(auth_plugin_data_2), + auth_plugin_name, + }) + } +} + +#[cfg(test)] +mod tests { + use bytes::Buf; + use sqlx_core::io::Deserialize; + + use super::{Capabilities, Handshake, ServerStatus}; + + #[test] + fn handshake_mysql_8_0_18() { + const HANDSHAKE_MYSQL_8_0_18: &[u8] = b"\n8.0.18\x00\x19\x00\x00\x00\x114aB0c\x06g\x00\xff\xff\xff\x02\x00\xff\xc7\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tL\x03s\x0f[4\rl4. \x00caching_sha2_password\x00"; + + let mut h = Handshake::deserialize(HANDSHAKE_MYSQL_8_0_18.into()).unwrap(); + + assert_eq!(h.protocol_version, 10); + + assert_eq!( + h.capabilities, + Capabilities::LONG_PASSWORD + | Capabilities::FOUND_ROWS + | Capabilities::LONG_FLAG + | Capabilities::CONNECT_WITH_DB + | Capabilities::NO_SCHEMA + | Capabilities::COMPRESS + | Capabilities::ODBC + | Capabilities::LOCAL_FILES + | Capabilities::IGNORE_SPACE + | Capabilities::PROTOCOL_41 + | Capabilities::INTERACTIVE + | Capabilities::SSL + | Capabilities::TRANSACTIONS + | Capabilities::SECURE_CONNECTION + | Capabilities::MULTI_STATEMENTS + | Capabilities::MULTI_RESULTS + | Capabilities::PS_MULTI_RESULTS + | Capabilities::PLUGIN_AUTH + | Capabilities::CONNECT_ATTRS + | Capabilities::PLUGIN_AUTH_LENENC_DATA + | Capabilities::CAN_HANDLE_EXPIRED_PASSWORDS + | Capabilities::SESSION_TRACK + | Capabilities::DEPRECATE_EOF, + ); + + assert_eq!(h.charset, Some(255)); + assert_eq!(h.status, ServerStatus::AUTOCOMMIT); + assert_eq!(h.auth_plugin_name.as_deref(), Some("caching_sha2_password")); + + assert_eq!( + &*h.auth_plugin_data.copy_to_bytes(h.auth_plugin_data.remaining()), + &[17, 52, 97, 66, 48, 99, 6, 103, 116, 76, 3, 115, 15, 91, 52, 13, 108, 52, 46, 32, 0] + ); + } + + #[test] + fn handshake_mariadb_10_4_7() { + const HANDSHAKE_MARIA_DB_10_4_7: &[u8] = b"\n5.5.5-10.4.7-MariaDB-1:10.4.7+maria~bionic\x00\x0b\x00\x00\x00t6L\\j\"dS\x00\xfe\xf7\x08\x02\x00\xff\x81\x15\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00U14Oph9\"hr&`3{55H\0mysql_native_password\0"; + + let mut h = Handshake::deserialize(HANDSHAKE_MARIA_DB_10_5_8.into()).unwrap(); + + assert_eq!(h.protocol_version, 10); + assert_eq!(&*h.server_version, "5.5.5-10.5.8-MariaDB-1:10.5.8+maria~focal"); + + assert_eq!( + h.capabilities, + Capabilities::FOUND_ROWS + | Capabilities::LONG_FLAG + | Capabilities::CONNECT_WITH_DB + | Capabilities::NO_SCHEMA + | Capabilities::COMPRESS + | Capabilities::ODBC + | Capabilities::LOCAL_FILES + | Capabilities::IGNORE_SPACE + | Capabilities::PROTOCOL_41 + | Capabilities::INTERACTIVE + | Capabilities::TRANSACTIONS + | Capabilities::SECURE_CONNECTION + | Capabilities::MULTI_STATEMENTS + | Capabilities::MULTI_RESULTS + | Capabilities::PS_MULTI_RESULTS + | Capabilities::PLUGIN_AUTH + | Capabilities::CONNECT_ATTRS + | Capabilities::PLUGIN_AUTH_LENENC_DATA + | Capabilities::CAN_HANDLE_EXPIRED_PASSWORDS + | Capabilities::SESSION_TRACK + | Capabilities::DEPRECATE_EOF + ); + + assert_eq!(h.charset, Some(45)); + assert_eq!(h.status, ServerStatus::AUTOCOMMIT); + assert_eq!(h.auth_plugin_name.as_deref(), Some("mysql_native_password")); + + assert_eq!( + &*h.auth_plugin_data.copy_to_bytes(h.auth_plugin_data.remaining()), + &[ + 39, 80, 66, 57, 52, 57, 99, 102, 85, 89, 62, 104, 114, 38, 96, 51, 123, 53, 53, 72, + 0 + ] + ); + } + + #[test] + fn handshake_mysql_5_6_50() { + const HANDSHAKE_MYSQL_5_6_50: &[u8] = b"\n5.6.50\0\x01\0\0\0-VLYZ:Pd\0\xff\xf7\x08\x02\0\x7f\x80\x15\0\0\0\0\0\0\0\0\0\0'2f+BL8nGV[G\0mysql_native_password\0"; + + let mut h = Handshake::deserialize(HANDSHAKE_MYSQL_5_6_50.into()).unwrap(); + + assert_eq!(h.protocol_version, 10); + + assert_eq!(&*h.server_version, "5.6.50"); + + assert_eq!( + h.capabilities, + Capabilities::LONG_PASSWORD + | Capabilities::FOUND_ROWS + | Capabilities::LONG_FLAG + | Capabilities::CONNECT_WITH_DB + | Capabilities::NO_SCHEMA + | Capabilities::COMPRESS + | Capabilities::ODBC + | Capabilities::LOCAL_FILES + | Capabilities::IGNORE_SPACE + | Capabilities::PROTOCOL_41 + | Capabilities::INTERACTIVE + | Capabilities::TRANSACTIONS + | Capabilities::SECURE_CONNECTION + | Capabilities::MULTI_STATEMENTS + | Capabilities::MULTI_RESULTS + | Capabilities::PS_MULTI_RESULTS + | Capabilities::PLUGIN_AUTH + | Capabilities::CONNECT_ATTRS + | Capabilities::PLUGIN_AUTH_LENENC_DATA + | Capabilities::CAN_HANDLE_EXPIRED_PASSWORDS + ); + + assert_eq!(h.charset, Some(8)); + assert_eq!(h.status, ServerStatus::AUTOCOMMIT); + assert_eq!(h.auth_plugin_name.as_deref(), Some("mysql_native_password")); + + assert_eq!( + &*h.auth_plugin_data.copy_to_bytes(h.auth_plugin_data.remaining()), + &[45, 86, 76, 89, 90, 58, 80, 100, 39, 50, 102, 43, 66, 76, 56, 110, 71, 86, 91, 71, 0] + ); + } + + #[test] + fn handshake_mysql_5_0_96() { + const HANDSHAKE_MYSQL_5_0_96: &[u8] = b"\n5.0.96\0\x03\0\0\0bs=sNiGe\0,\xa2\x08\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0IzMP)yLLx;[9\0"; + + let mut h = Handshake::deserialize(HANDSHAKE_MYSQL_5_0_96.into()).unwrap(); + + assert_eq!(h.protocol_version, 10); + assert_eq!(&*h.server_version, "5.0.96"); + + assert_eq!( + h.capabilities, + Capabilities::LONG_FLAG + | Capabilities::CONNECT_WITH_DB + | Capabilities::COMPRESS + | Capabilities::PROTOCOL_41 + | Capabilities::TRANSACTIONS + | Capabilities::SECURE_CONNECTION + ); + + assert_eq!(h.charset, Some(8)); + assert_eq!(h.status, ServerStatus::AUTOCOMMIT); + assert_eq!(h.auth_plugin_name, None); + + assert_eq!( + &*h.auth_plugin_data.copy_to_bytes(h.auth_plugin_data.remaining()), + &[ + 98, 115, 61, 115, 78, 105, 71, 101, 73, 122, 77, 80, 41, 121, 76, 76, 120, 59, 91, + 57, 0 + ] + ); + } + + #[test] + fn handshake_mysql_5_1_73() { + const HANDSHAKE_MYSQL_5_1_73: &[u8] = b"\n5.1.73\0\x01\0\0\0 { + pub(crate) database: Option<&'a str>, + pub(crate) max_packet_size: u32, + pub(crate) charset: u8, + pub(crate) username: Option<&'a str>, + pub(crate) auth_plugin_name: Option<&'a str>, + pub(crate) auth_response: Option<&'a [u8]>, +} + +impl Serialize<'_, Capabilities> for HandshakeResponse<'_> { + fn serialize_with(&self, buf: &mut Vec, capabilities: Capabilities) -> Result<()> { + buf.extend_from_slice(&(capabilities.bits() as u32).to_le_bytes()); + buf.extend_from_slice(&self.max_packet_size.to_le_bytes()); + buf.extend_from_slice(&self.charset.to_le_bytes()); + + // reserved (all 0) + buf.extend_from_slice(&[0_u8; 23]); + + buf.write_maybe_str_nul(self.username); + + let auth_response = self.auth_response.unwrap_or_default(); + + if capabilities.contains(Capabilities::PLUGIN_AUTH_LENENC_DATA) { + buf.write_bytes_lenenc(auth_response); + } else if capabilities.contains(Capabilities::SECURE_CONNECTION) { + debug_assert!(auth_response.len() <= u8::max_value().into()); + + buf.reserve(1 + auth_response.len()); + buf.push(auth_response.len() as u8); + buf.extend_from_slice(auth_response); + } else { + buf.reserve(1 + auth_response.len()); + buf.extend_from_slice(auth_response); + buf.push(b'\0'); + } + + if capabilities.contains(Capabilities::CONNECT_WITH_DB) { + buf.write_maybe_str_nul(self.database); + } + + if capabilities.contains(Capabilities::PLUGIN_AUTH) { + buf.write_maybe_str_nul(self.auth_plugin_name); + } + + Ok(()) + } +} diff --git a/sqlx-mysql/src/protocol/status.rs b/sqlx-mysql/src/protocol/status.rs new file mode 100644 index 00000000..f78534cf --- /dev/null +++ b/sqlx-mysql/src/protocol/status.rs @@ -0,0 +1,50 @@ +// https://dev.mysql.com/doc/internals/en/status-flags.html#packet-Protocol::StatusFlags +// https://dev.mysql.com/doc/dev/mysql-server/8.0.12/mysql__com_8h.html#a1d854e841086925be1883e4d7b4e8cad +// https://mariadb.com/kb/en/library/mariadb-connectorc-types-and-definitions/#server-status +bitflags::bitflags! { + pub struct ServerStatus: u16 { + // Is raised when a multi-statement transaction has been started, either explicitly, + // by means of BEGIN or COMMIT AND CHAIN, or implicitly, by the first + // transactional statement, when autocommit=off. + const IN_TRANS = 0x0001; + + // Autocommit mode is set + const AUTOCOMMIT = 0x0002; + + // Multi query - next query exists. + const MORE_RESULTS_EXISTS = 0x0008; + + const NO_GOOD_INDEX_USED = 0x0010; + const NO_INDEX_USED = 0x0020; + + // When using COM_STMT_FETCH, indicate that current cursor still has result + const CURSOR_EXISTS = 0x0040; + + // When using COM_STMT_FETCH, indicate that current cursor has finished to send results + const LAST_ROW_SENT = 0x0080; + + // Database has been dropped + const DB_DROPPED = 0x0100; + + // Current escape mode is "no backslash escape" + const NO_BACKSLASH_ESCAPES = 0x0200; + + // A DDL change did have an impact on an existing PREPARE (an automatic + // re-prepare has been executed) + const METADATA_CHANGED = 0x0400; + + // Last statement took more than the time value specified + // in server variable long_query_time. + const QUERY_WAS_SLOW = 0x0800; + + // This result-set contain stored procedure output parameter. + const PS_OUT_PARAMS = 0x1000; + + // Current transaction is a read-only transaction. + const IN_TRANS_READONLY = 0x2000; + + // This status flag, when on, implies that one of the state information has changed + // on the server because of the execution of the last statement. + const SESSION_STATE_CHANGED = 0x4000; + } +} diff --git a/sqlx/src/lib.rs b/sqlx/src/lib.rs index 1ca18446..4f22da11 100644 --- a/sqlx/src/lib.rs +++ b/sqlx/src/lib.rs @@ -16,21 +16,16 @@ #![warn(clippy::useless_let_if_seq)] #![allow(clippy::doc_markdown)] +#[cfg(feature = "blocking")] +pub use sqlx_core::blocking; +#[cfg(feature = "actix")] +pub use sqlx_core::Actix; +#[cfg(feature = "async-std")] +pub use sqlx_core::AsyncStd; +#[cfg(feature = "tokio")] +pub use sqlx_core::Tokio; pub use sqlx_core::{ prelude, ConnectOptions, Connection, Database, DefaultRuntime, Error, Result, Runtime, }; - -#[cfg(feature = "blocking")] -pub use sqlx_core::blocking; - -#[cfg(feature = "async-std")] -pub use sqlx_core::AsyncStd; - -#[cfg(feature = "tokio")] -pub use sqlx_core::Tokio; - -#[cfg(feature = "actix")] -pub use sqlx_core::Actix; - #[cfg(feature = "mysql")] pub use sqlx_mysql as mysql;