mirror of
https://github.com/LukeMathWalker/zero-to-production.git
synced 2025-01-31 11:02:29 +00:00
Happy case test.
This commit is contained in:
parent
50e660f82d
commit
3145991669
7 changed files with 457 additions and 45 deletions
373
Cargo.lock
generated
373
Cargo.lock
generated
|
@ -7,13 +7,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project 0.4.27",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tokio 0.2.24",
|
||||
"tokio-util 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -50,7 +50,7 @@ dependencies = [
|
|||
"base64 0.13.0",
|
||||
"bitflags",
|
||||
"brotli2",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"cookie",
|
||||
"copyless",
|
||||
"derive_more",
|
||||
|
@ -61,7 +61,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-util",
|
||||
"fxhash",
|
||||
"h2",
|
||||
"h2 0.2.7",
|
||||
"http",
|
||||
"httparse",
|
||||
"indexmap",
|
||||
|
@ -117,7 +117,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-util",
|
||||
"smallvec",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -133,7 +133,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-util",
|
||||
"log",
|
||||
"mio",
|
||||
"mio 0.6.23",
|
||||
"mio-uds",
|
||||
"num_cpus",
|
||||
"slab",
|
||||
|
@ -201,7 +201,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-service",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"either",
|
||||
"futures-channel",
|
||||
"futures-sink",
|
||||
|
@ -230,7 +230,7 @@ dependencies = [
|
|||
"actix-utils",
|
||||
"actix-web-codegen",
|
||||
"awc",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"derive_more",
|
||||
"encoding_rs",
|
||||
"futures-channel",
|
||||
|
@ -311,12 +311,29 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[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-trait"
|
||||
version = "0.1.42"
|
||||
|
@ -354,7 +371,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-service",
|
||||
"base64 0.13.0",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"cfg-if 1.0.0",
|
||||
"derive_more",
|
||||
"futures-core",
|
||||
|
@ -497,15 +514,27 @@ version = "0.5.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
|
||||
|
||||
[[package]]
|
||||
name = "bytestring"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7c05fa5172da78a62d9949d662d2ac89d4cc7355d7b49adee5163f1fb3f363"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"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 = "cargo_metadata"
|
||||
version = "0.12.1"
|
||||
|
@ -558,6 +587,15 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[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 = "config"
|
||||
version = "0.10.1"
|
||||
|
@ -658,6 +696,26 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "993a608597367c6377b258c25d7120740f00ed23a2252b729b1932dd7866f908"
|
||||
|
||||
[[package]]
|
||||
name = "deadpool"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d126179d86aee4556e54f5f3c6bf6d9884e7cc52cef82f77ee6f90a7747616d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"config",
|
||||
"crossbeam-queue",
|
||||
"num_cpus",
|
||||
"serde",
|
||||
"tokio 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.11"
|
||||
|
@ -739,6 +797,12 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
|
||||
|
||||
[[package]]
|
||||
name = "fake"
|
||||
version = "2.3.0"
|
||||
|
@ -754,6 +818,15 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[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"
|
||||
|
@ -852,6 +925,21 @@ 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"
|
||||
|
@ -879,6 +967,12 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.8"
|
||||
|
@ -984,7 +1078,7 @@ version = "0.2.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -992,8 +1086,28 @@ dependencies = [
|
|||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tokio 0.2.24",
|
||||
"tokio-util 0.3.1",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b67e66362108efccd8ac053abafc8b7a8d86a37e6e48fc4f6f7485eb5e9e6a5"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio 1.0.2",
|
||||
"tokio-util 0.6.1",
|
||||
"tracing",
|
||||
"tracing-futures",
|
||||
]
|
||||
|
@ -1067,7 +1181,7 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
@ -1078,10 +1192,42 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-types"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2ab8d0085fb82859c9adf050bd53992297ecdd03a665a230dfa50c8c964bf3d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel",
|
||||
"base64 0.13.0",
|
||||
"cookie",
|
||||
"futures-lite",
|
||||
"http",
|
||||
"infer",
|
||||
"pin-project-lite 0.1.11",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_qs",
|
||||
"serde_urlencoded",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.3.4"
|
||||
|
@ -1100,19 +1246,43 @@ version = "0.13.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"h2 0.2.7",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body 0.3.1",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project 1.0.2",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12219dc884514cb4a6a03737f4413c0e01c23a1b059b0156004b23f1e19dccbe"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.0",
|
||||
"http",
|
||||
"http-body 0.4.0",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project 1.0.2",
|
||||
"socket2",
|
||||
"tokio 1.0.2",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
|
@ -1124,12 +1294,12 @@ version = "0.21.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"futures-util",
|
||||
"hyper",
|
||||
"hyper 0.13.9",
|
||||
"log",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"tokio-rustls",
|
||||
"webpki",
|
||||
]
|
||||
|
@ -1155,6 +1325,12 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.9"
|
||||
|
@ -1376,12 +1552,25 @@ dependencies = [
|
|||
"kernel32-sys",
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"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"
|
||||
|
@ -1390,7 +1579,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
|
|||
dependencies = [
|
||||
"iovec",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio 0.6.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1405,6 +1594,16 @@ dependencies = [
|
|||
"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 = "net2"
|
||||
version = "0.2.37"
|
||||
|
@ -1439,6 +1638,15 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[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-integer"
|
||||
version = "0.1.44"
|
||||
|
@ -1492,6 +1700,12 @@ 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"
|
||||
|
@ -1777,13 +1991,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"http-body 0.3.1",
|
||||
"hyper 0.13.9",
|
||||
"hyper-rustls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
|
@ -1797,7 +2011,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"tokio-rustls",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
|
@ -1966,6 +2180,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_qs"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5af82de3c6549b001bec34961ff2d6a54339a87bab37ce901b693401f27de6cb"
|
||||
dependencies = [
|
||||
"data-encoding",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.0"
|
||||
|
@ -2104,7 +2330,7 @@ dependencies = [
|
|||
"base64 0.13.0",
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"chrono",
|
||||
"crc",
|
||||
"crossbeam-channel",
|
||||
|
@ -2175,7 +2401,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-threadpool",
|
||||
"once_cell",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
|
@ -2384,14 +2610,14 @@ version = "0.2.24"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"iovec",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"mio 0.6.23",
|
||||
"mio-uds",
|
||||
"num_cpus",
|
||||
"pin-project-lite 0.1.11",
|
||||
|
@ -2401,6 +2627,20 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ca04cec6ff2474c638057b65798f60ac183e5e79d3448bb7163d36a39cff6ec"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes 1.0.1",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio 0.7.7",
|
||||
"pin-project-lite 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "0.2.6"
|
||||
|
@ -2420,22 +2660,48 @@ checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
|
|||
dependencies = [
|
||||
"futures-core",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76066865172052eb8796c686f0b441a93df8b08d40a950b062ffb9a426f00edd"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite 0.2.0",
|
||||
"tokio 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"bytes 0.5.6",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite 0.1.11",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ae4751faa60b9f96dd8344d74592e5a17c0c9a220413dbc6942d14139bbfcc"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite 0.2.0",
|
||||
"tokio 1.0.2",
|
||||
"tokio-stream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2576,7 +2842,7 @@ dependencies = [
|
|||
"rand",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -2596,7 +2862,7 @@ dependencies = [
|
|||
"resolv-conf",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"trust-dns-proto",
|
||||
]
|
||||
|
||||
|
@ -2679,6 +2945,7 @@ dependencies = [
|
|||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2718,6 +2985,12 @@ 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 = "want"
|
||||
version = "0.3.0"
|
||||
|
@ -2914,6 +3187,26 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wiremock"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9297d85d701557878bb9b768b048f464874b8c287b1426499f385f804817db1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"deadpool",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
"http-types",
|
||||
"hyper 0.14.2",
|
||||
"log",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
|
@ -2955,8 +3248,9 @@ dependencies = [
|
|||
"reqwest",
|
||||
"serde",
|
||||
"serde-aux",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tokio",
|
||||
"tokio 0.2.24",
|
||||
"tracing",
|
||||
"tracing-actix-web",
|
||||
"tracing-bunyan-formatter",
|
||||
|
@ -2966,4 +3260,5 @@ dependencies = [
|
|||
"unicode-segmentation",
|
||||
"uuid",
|
||||
"validator",
|
||||
"wiremock",
|
||||
]
|
||||
|
|
|
@ -38,3 +38,5 @@ claim = "0.4.0"
|
|||
quickcheck = "0.9.2"
|
||||
quickcheck_macros = "0.9.1"
|
||||
fake = "~2.3.0"
|
||||
wiremock = "0.4.7"
|
||||
serde_json = "1.0.61"
|
||||
|
|
|
@ -9,4 +9,6 @@ database:
|
|||
database_name: "newsletter"
|
||||
require_ssl: false
|
||||
email_client:
|
||||
base_url: "localhost"
|
||||
base_url: "localhost"
|
||||
sender_email: "test@gmail.com"
|
||||
authorization_token: "my-secret-token"
|
|
@ -1,3 +1,4 @@
|
|||
use crate::domain::SubscriberEmail;
|
||||
use serde_aux::field_attributes::deserialize_number_from_string;
|
||||
use sqlx::postgres::{PgConnectOptions, PgSslMode};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
@ -50,6 +51,14 @@ impl DatabaseSettings {
|
|||
#[derive(serde::Deserialize)]
|
||||
pub struct EmailClientSettings {
|
||||
pub base_url: String,
|
||||
pub sender_email: String,
|
||||
pub authorization_token: String,
|
||||
}
|
||||
|
||||
impl EmailClientSettings {
|
||||
pub fn sender(&self) -> Result<SubscriberEmail, String> {
|
||||
SubscriberEmail::parse(self.sender_email.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_configuration() -> Result<Settings, config::ConfigError> {
|
||||
|
|
|
@ -4,13 +4,17 @@ use reqwest::Client;
|
|||
pub struct EmailClient {
|
||||
http_client: Client,
|
||||
base_url: String,
|
||||
sender: SubscriberEmail,
|
||||
authorization_token: String,
|
||||
}
|
||||
|
||||
impl EmailClient {
|
||||
pub fn new(base_url: String) -> Self {
|
||||
pub fn new(base_url: String, sender: SubscriberEmail, authorization_token: String) -> Self {
|
||||
Self {
|
||||
http_client: Client::new(),
|
||||
base_url,
|
||||
sender,
|
||||
authorization_token,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +24,89 @@ impl EmailClient {
|
|||
subject: &str,
|
||||
html_content: &str,
|
||||
text_content: &str,
|
||||
) -> Result<(), String> {
|
||||
todo!()
|
||||
) -> Result<(), reqwest::Error> {
|
||||
let url = format!("{}/email", self.base_url);
|
||||
let request_body = SendEmailRequest {
|
||||
from: self.sender.as_ref().to_owned(),
|
||||
to: recipient.as_ref().to_owned(),
|
||||
subject: subject.into(),
|
||||
html_body: html_content.into(),
|
||||
text_body: text_content.into(),
|
||||
};
|
||||
self.http_client
|
||||
.post(&url)
|
||||
.header("X-Postmark-Server-Token", &self.authorization_token)
|
||||
.json(&request_body)
|
||||
.send()
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct SendEmailRequest {
|
||||
from: String,
|
||||
to: String,
|
||||
subject: String,
|
||||
html_body: String,
|
||||
text_body: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::domain::SubscriberEmail;
|
||||
use crate::email_client::EmailClient;
|
||||
use fake::faker::internet::en::SafeEmail;
|
||||
use fake::faker::lorem::en::{Paragraph, Sentence};
|
||||
use fake::{Fake, Faker};
|
||||
use wiremock::matchers::{header, header_exists, method, path};
|
||||
use wiremock::{Mock, MockServer, Request, ResponseTemplate};
|
||||
|
||||
struct SendEmailBodyMatcher;
|
||||
|
||||
impl wiremock::Match for SendEmailBodyMatcher {
|
||||
fn matches(&self, request: &Request) -> bool {
|
||||
let result: Result<serde_json::Value, _> = serde_json::from_slice(&request.body);
|
||||
if let Ok(body) = result {
|
||||
dbg!(&body);
|
||||
body.get("From").is_some()
|
||||
&& body.get("To").is_some()
|
||||
&& body.get("Subject").is_some()
|
||||
&& body.get("HtmlBody").is_some()
|
||||
&& body.get("TextBody").is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn send_email_fires_a_request_to_base_url() {
|
||||
// Arrange
|
||||
let mock_server = MockServer::start().await;
|
||||
let sender = SubscriberEmail::parse(SafeEmail().fake()).unwrap();
|
||||
let email_client = EmailClient::new(mock_server.uri(), sender, Faker.fake());
|
||||
|
||||
let subscriber_email = SubscriberEmail::parse(SafeEmail().fake()).unwrap();
|
||||
let subject: String = Sentence(1..2).fake();
|
||||
let content: String = Paragraph(1..10).fake();
|
||||
|
||||
Mock::given(header_exists("X-Postmark-Server-Token"))
|
||||
.and(header("Content-Type", "application/json"))
|
||||
.and(path("/email"))
|
||||
.and(method("POST"))
|
||||
.and(SendEmailBodyMatcher)
|
||||
.respond_with(ResponseTemplate::new(200))
|
||||
.expect(1)
|
||||
.mount(&mock_server)
|
||||
.await;
|
||||
|
||||
// Act
|
||||
let _ = email_client
|
||||
.send_email(subscriber_email, &subject, &content, &content)
|
||||
.await;
|
||||
|
||||
// Assert
|
||||
}
|
||||
}
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -16,7 +16,16 @@ async fn main() -> std::io::Result<()> {
|
|||
.connect_with(configuration.database.with_db())
|
||||
.await
|
||||
.expect("Failed to connect to Postgres.");
|
||||
let email_client = EmailClient::new(configuration.email_client.base_url);
|
||||
|
||||
let sender_email = configuration
|
||||
.email_client
|
||||
.sender()
|
||||
.expect("Invalid sender email address.");
|
||||
let email_client = EmailClient::new(
|
||||
configuration.email_client.base_url,
|
||||
sender_email,
|
||||
configuration.email_client.authorization_token,
|
||||
);
|
||||
|
||||
let address = format!(
|
||||
"{}:{}",
|
||||
|
|
|
@ -33,7 +33,16 @@ async fn spawn_app() -> TestApp {
|
|||
let mut configuration = get_configuration().expect("Failed to read configuration.");
|
||||
configuration.database.database_name = Uuid::new_v4().to_string();
|
||||
let connection_pool = configure_database(&configuration.database).await;
|
||||
let email_client = EmailClient::new(configuration.email_client.base_url);
|
||||
|
||||
let sender_email = configuration
|
||||
.email_client
|
||||
.sender()
|
||||
.expect("Invalid sender email address.");
|
||||
let email_client = EmailClient::new(
|
||||
configuration.email_client.base_url,
|
||||
sender_email,
|
||||
configuration.email_client.authorization_token,
|
||||
);
|
||||
|
||||
let server =
|
||||
run(listener, connection_pool.clone(), email_client).expect("Failed to bind address");
|
||||
|
|
Loading…
Reference in a new issue