/films implementation
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
.env
|
||||||
|
|||||||
424
Cargo.lock
generated
424
Cargo.lock
generated
@ -273,6 +273,58 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-bigint-dig"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82c79c15c05d4bf82b6f5ef163104cc81a760d8e874d38ac50ab67c8877b647b"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"libm",
|
||||||
|
"num-integer",
|
||||||
|
"num-iter",
|
||||||
|
"num-traits",
|
||||||
|
"rand",
|
||||||
|
"smallvec",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-iter"
|
||||||
|
version = "0.1.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
@ -320,6 +372,57 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkcs1"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||||
|
dependencies = [
|
||||||
|
"der",
|
||||||
|
"pkcs8",
|
||||||
|
"spki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkcs8"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||||
|
dependencies = [
|
||||||
|
"der",
|
||||||
|
"spki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "potential_utf"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77"
|
||||||
|
dependencies = [
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.103"
|
version = "1.0.103"
|
||||||
@ -449,6 +552,240 @@ dependencies = [
|
|||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spki"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"der",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc"
|
||||||
|
dependencies = [
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-macros",
|
||||||
|
"sqlx-mysql",
|
||||||
|
"sqlx-postgres",
|
||||||
|
"sqlx-sqlite",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-core"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"bytes",
|
||||||
|
"crc",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"either",
|
||||||
|
"event-listener",
|
||||||
|
"futures-core",
|
||||||
|
"futures-intrusive",
|
||||||
|
"futures-io",
|
||||||
|
"futures-util",
|
||||||
|
"hashbrown 0.15.5",
|
||||||
|
"hashlink",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"memchr",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
"time",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tracing",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-macros"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-macros-core",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-macros-core"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b"
|
||||||
|
dependencies = [
|
||||||
|
"dotenvy",
|
||||||
|
"either",
|
||||||
|
"heck",
|
||||||
|
"hex",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
|
"sqlx-core",
|
||||||
|
"sqlx-mysql",
|
||||||
|
"sqlx-postgres",
|
||||||
|
"sqlx-sqlite",
|
||||||
|
"syn",
|
||||||
|
"tokio",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-mysql"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526"
|
||||||
|
dependencies = [
|
||||||
|
"atoi",
|
||||||
|
"base64",
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"crc",
|
||||||
|
"digest",
|
||||||
|
"dotenvy",
|
||||||
|
"either",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
|
"futures-util",
|
||||||
|
"generic-array",
|
||||||
|
"hex",
|
||||||
|
"hkdf",
|
||||||
|
"hmac",
|
||||||
|
"itoa",
|
||||||
|
"log",
|
||||||
|
"md-5",
|
||||||
|
"memchr",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
|
"rand",
|
||||||
|
"rsa",
|
||||||
|
"serde",
|
||||||
|
"sha1",
|
||||||
|
"sha2",
|
||||||
|
"smallvec",
|
||||||
|
"sqlx-core",
|
||||||
|
"stringprep",
|
||||||
|
"thiserror",
|
||||||
|
"time",
|
||||||
|
"tracing",
|
||||||
|
"whoami",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-postgres"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46"
|
||||||
|
dependencies = [
|
||||||
|
"atoi",
|
||||||
|
"base64",
|
||||||
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
|
"crc",
|
||||||
|
"dotenvy",
|
||||||
|
"etcetera",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"hex",
|
||||||
|
"hkdf",
|
||||||
|
"hmac",
|
||||||
|
"home",
|
||||||
|
"itoa",
|
||||||
|
"log",
|
||||||
|
"md-5",
|
||||||
|
"memchr",
|
||||||
|
"once_cell",
|
||||||
|
"rand",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2",
|
||||||
|
"smallvec",
|
||||||
|
"sqlx-core",
|
||||||
|
"stringprep",
|
||||||
|
"thiserror",
|
||||||
|
"time",
|
||||||
|
"tracing",
|
||||||
|
"whoami",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sqlx-sqlite"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
|
||||||
|
dependencies = [
|
||||||
|
"atoi",
|
||||||
|
"flume",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-intrusive",
|
||||||
|
"futures-util",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"log",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sqlx-core",
|
||||||
|
"thiserror",
|
||||||
|
"time",
|
||||||
|
"tracing",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stringprep"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
"unicode-properties",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.109"
|
version = "2.0.109"
|
||||||
@ -466,6 +803,93 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"num-conv",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.48.0"
|
version = "1.48.0"
|
||||||
|
|||||||
@ -4,5 +4,9 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { "0.8.6", features = ["full"]}
|
axum = "0.8.6"
|
||||||
|
chrono = "0.4.42"
|
||||||
|
dotenvy = "0.15.7"
|
||||||
|
serde = "1.0.228"
|
||||||
|
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio", "time", "macros"] }
|
||||||
tokio = { version = "1.48.0", features = ["full"]}
|
tokio = { version = "1.48.0", features = ["full"]}
|
||||||
|
|||||||
9
compose.yaml
Normal file
9
compose.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
services:
|
||||||
|
database:
|
||||||
|
image: "docker.io/postgres:17"
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: "my-db"
|
||||||
|
POSTGRES_USER: "user"
|
||||||
|
POSTGRES_PASSWORD: "pass"
|
||||||
|
ports:
|
||||||
|
- 5463:5432
|
||||||
235
src/main.rs
235
src/main.rs
@ -1,77 +1,204 @@
|
|||||||
use axum::response::IntoResponse;
|
use axum::{
|
||||||
use axum::{Router, routing::get};
|
Json, Router,
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
extract::{Path, Query, State},
|
||||||
|
http::StatusCode,
|
||||||
|
response::IntoResponse,
|
||||||
|
routing::get,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sqlx::PgPool;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
mod router;
|
#[derive(Clone)]
|
||||||
|
struct AppState {
|
||||||
|
pool: PgPool,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() {
|
||||||
let listener = TcpListener::bind("127.0.0.1:8080").await?;
|
let _ = dotenvy::dotenv();
|
||||||
|
|
||||||
let app = Router::new()
|
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL should be set");
|
||||||
|
let pool = PgPool::connect(&database_url)
|
||||||
|
.await
|
||||||
|
.expect("Could not connect to database");
|
||||||
|
|
||||||
|
sqlx::raw_sql(
|
||||||
|
r#"
|
||||||
|
CREATE TABLE IF NOT EXISTS movie(
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
year DATE
|
||||||
|
);
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.expect("Couldn't create table");
|
||||||
|
|
||||||
|
let state = AppState { pool: pool };
|
||||||
|
|
||||||
|
let router = Router::new()
|
||||||
.route("/", get(root))
|
.route("/", get(root))
|
||||||
|
.route("/films", get(get_film).post(post_film).delete(delete_all))
|
||||||
.route(
|
.route(
|
||||||
"/films",
|
"/films/{id}",
|
||||||
get(get_film)
|
get(get_film_by_id).delete(delete_film_by_id).put(put_film),
|
||||||
.post(post_film)
|
|
||||||
.put(put_film)
|
|
||||||
.delete(delete_all),
|
|
||||||
)
|
)
|
||||||
.route("/films/{id}", get(get_film_by_id).delete(delete_film_by_id));
|
.with_state(state);
|
||||||
|
|
||||||
loop {
|
let addr = "127.0.0.1:8000";
|
||||||
let (mut socket, _) = listener.accept().await?;
|
let listener = TcpListener::bind(addr).await.unwrap();
|
||||||
|
println!("Listening at {addr}");
|
||||||
|
axum::serve(listener, router).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
tokio::spawn(async move {
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
let mut buf = [0; 1024];
|
struct Movie {
|
||||||
|
id: i32,
|
||||||
|
name: String,
|
||||||
|
year: i32,
|
||||||
|
}
|
||||||
|
|
||||||
// In a loop, read data from the socket and write the data back.
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
loop {
|
struct CreateMovie {
|
||||||
let n = match socket.read(&mut buf).await {
|
name: String,
|
||||||
// socket closed
|
year: i32,
|
||||||
Ok(0) => return,
|
}
|
||||||
Ok(n) => n,
|
|
||||||
Err(e) => {
|
|
||||||
eprintln!("failed to read from socket; err = {:?}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Write the data back
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
if let Err(e) = socket.write_all(&buf[0..n]).await {
|
struct GetMovieQuery {
|
||||||
eprintln!("failed to write to socket; err = {:?}", e);
|
name: Option<String>,
|
||||||
return;
|
year: Option<i32>,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
async fn root() {}
|
||||||
|
|
||||||
|
async fn get_film(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Query(query): Query<GetMovieQuery>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let movies = sqlx::query_as!(Movie, "SELECT id, name, year FROM movies")
|
||||||
|
.fetch_all(&state.pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let movie = match movies {
|
||||||
|
Ok(_) => Json(movies.unwrap()),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("error: {e:?}");
|
||||||
|
Json(vec![])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let movie_sorted: Vec<Movie> = movie
|
||||||
|
.to_vec()
|
||||||
|
.into_iter()
|
||||||
|
.filter(|m| query.name.as_ref().map_or(true, |n| m.name.contains(n)))
|
||||||
|
.filter(|m| query.year.map_or(true, |y| m.year == y))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Json(movie_sorted)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_film_by_id(State(state): State<AppState>, Path(id): Path<i32>) -> impl IntoResponse {
|
||||||
|
let result = sqlx::query_as!(
|
||||||
|
Movie,
|
||||||
|
"SELECT id, name, year FROM movies WHERE id = ($1)",
|
||||||
|
id
|
||||||
|
)
|
||||||
|
.fetch_optional(&state.pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let movie = match result {
|
||||||
|
Ok(_) => result.unwrap(),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("error: {e:?}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match movie {
|
||||||
|
Some(m) => Json(m).into_response(),
|
||||||
|
None => (StatusCode::NOT_FOUND, "Movie not found").into_response(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn root() {
|
async fn post_film(State(state): State<AppState>, Json(movie): Json<Movie>) -> impl IntoResponse {
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
let result = sqlx::query!(
|
||||||
|
"INSERT INTO movies(name, year) VALUES ($1, $2)",
|
||||||
|
movie.name,
|
||||||
|
movie.year
|
||||||
|
)
|
||||||
|
.execute(&state.pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => (StatusCode::CREATED, "Movie has been created").into_response(),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("error: {e:?}");
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_film() -> impl IntoResponse {
|
async fn put_film(
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
State(state): State<AppState>,
|
||||||
|
Path(id): Path<i32>,
|
||||||
|
Json(movie): Json<CreateMovie>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let result = sqlx::query!(
|
||||||
|
"UPDATE movies
|
||||||
|
SET name = $1, year = $2
|
||||||
|
WHERE id = $3",
|
||||||
|
movie.name,
|
||||||
|
movie.year,
|
||||||
|
id
|
||||||
|
)
|
||||||
|
.execute(&state.pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(res) => match res.rows_affected() {
|
||||||
|
0 => (StatusCode::NOT_FOUND, "Movie not found").into_response(),
|
||||||
|
_ => (StatusCode::CREATED, "Movie has been updated").into_response(),
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("error: {e:?}");
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn post_film() -> impl IntoResponse {
|
async fn delete_film_by_id(
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
State(state): State<AppState>,
|
||||||
|
Path(id): Path<i32>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let result = sqlx::query!("DELETE FROM movies WHERE id = $1", id)
|
||||||
|
.execute(&state.pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(res) => match res.rows_affected() {
|
||||||
|
0 => (StatusCode::NOT_FOUND, "Movie not found").into_response(),
|
||||||
|
_ => (StatusCode::NO_CONTENT, "Movie has been deleted").into_response(),
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("error: {e:?}");
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn put_film() -> impl IntoResponse {
|
async fn delete_all(State(state): State<AppState>) -> impl IntoResponse {
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
let result = sqlx::query!("DELETE FROM movies")
|
||||||
}
|
.execute(&state.pool)
|
||||||
|
.await;
|
||||||
|
|
||||||
async fn delete_all() -> impl IntoResponse {
|
match result {
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
Ok(_) => StatusCode::NOT_FOUND,
|
||||||
}
|
Err(e) => {
|
||||||
|
eprintln!("error: {e:?}");
|
||||||
async fn get_film_by_id() -> impl IntoResponse {
|
StatusCode::INTERNAL_SERVER_ERROR
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn delete_film_by_id() -> impl IntoResponse {
|
|
||||||
axum::http::StatusCode::NOT_IMPLEMENTED
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user