get this to work a slight bit more

This commit is contained in:
Schrottkatze 2024-10-07 21:12:49 +02:00
parent ed87d3fb51
commit 5160929958
Signed by: schrottkatze
SSH key fingerprint: SHA256:hXb3t1vINBFCiDCmhRABHX5ocdbLiKyCdKI4HK2Rbbc
10 changed files with 484 additions and 108 deletions

302
Cargo.lock generated
View file

@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
version = "0.24.1"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
"gimli",
]
@ -145,19 +145,20 @@ dependencies = [
[[package]]
name = "autocfg"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "axum"
version = "0.7.6"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec"
checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae"
dependencies = [
"async-trait",
"axum-core",
"axum-macros",
"base64",
"bytes",
"futures-util",
"http",
@ -176,8 +177,10 @@ dependencies = [
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sha1",
"sync_wrapper 1.0.1",
"tokio",
"tokio-tungstenite",
"tower",
"tower-layer",
"tower-service",
@ -186,9 +189,9 @@ dependencies = [
[[package]]
name = "axum-core"
version = "0.4.4"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00"
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
dependencies = [
"async-trait",
"bytes",
@ -216,6 +219,16 @@ dependencies = [
"syn",
]
[[package]]
name = "axum_static"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d134d2aeabd596bc82e44748f999c9b0e535a7b756cb36c62df0de6d2445d6e"
dependencies = [
"axum",
"tower-http",
]
[[package]]
name = "backend"
version = "0.1.0"
@ -223,15 +236,19 @@ dependencies = [
"anyhow",
"axum",
"axum-macros",
"axum_static",
"chrono",
"chrono-tz",
"dashmap",
"http",
"maud",
"rand",
"serde",
"sqlx",
"thiserror",
"tokio",
"tokio-tungstenite",
"tracing",
"tracing-subscriber",
"uuid",
]
@ -315,9 +332,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.21"
version = "1.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0"
checksum = "677207f6eaec43fcfd092a718c847fc38aa261d0e19b8ef6797e0ccbe789e738"
dependencies = [
"shlex",
]
@ -366,9 +383,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.18"
version = "4.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615"
dependencies = [
"clap_builder",
"clap_derive",
@ -376,9 +393,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.18"
version = "4.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b"
dependencies = [
"anstream",
"anstyle",
@ -519,6 +536,20 @@ dependencies = [
"typenum",
]
[[package]]
name = "dashmap"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"crossbeam-utils",
"hashbrown 0.14.5",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "data-encoding"
version = "2.6.0"
@ -635,9 +666,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
@ -645,15 +676,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
@ -673,27 +704,27 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-sink"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-util"
version = "0.3.30"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-core",
"futures-io",
@ -728,9 +759,9 @@ dependencies = [
[[package]]
name = "gimli"
version = "0.31.0"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "hashbrown"
@ -742,13 +773,19 @@ dependencies = [
"allocator-api2",
]
[[package]]
name = "hashbrown"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
[[package]]
name = "hashlink"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
dependencies = [
"hashbrown",
"hashbrown 0.14.5",
]
[[package]]
@ -831,10 +868,16 @@ dependencies = [
]
[[package]]
name = "httparse"
version = "1.9.4"
name = "http-range-header"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a"
[[package]]
name = "httparse"
version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
[[package]]
name = "httpdate"
@ -912,12 +955,12 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.5.0"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.15.0",
]
[[package]]
@ -1020,7 +1063,7 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904"
dependencies = [
"hashbrown",
"hashbrown 0.14.5",
]
[[package]]
@ -1073,6 +1116,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -1111,6 +1164,16 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
@ -1160,18 +1223,24 @@ dependencies = [
[[package]]
name = "object"
version = "0.36.4"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.19.0"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking"
@ -1412,18 +1481,18 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.6"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.10.6"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
dependencies = [
"aho-corasick",
"memchr",
@ -1433,9 +1502,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.7"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
dependencies = [
"aho-corasick",
"memchr",
@ -1444,9 +1513,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "ring"
@ -1504,9 +1573,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.13"
version = "0.23.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8"
dependencies = [
"once_cell",
"ring",
@ -1518,19 +1587,18 @@ dependencies = [
[[package]]
name = "rustls-pemfile"
version = "2.1.3"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
dependencies = [
"base64",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55"
[[package]]
name = "rustls-webpki"
@ -1637,6 +1705,15 @@ dependencies = [
"digest",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -1778,7 +1855,7 @@ dependencies = [
"futures-intrusive",
"futures-io",
"futures-util",
"hashbrown",
"hashbrown 0.14.5",
"hashlink",
"hex",
"indexmap",
@ -2004,9 +2081,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.77"
version = "2.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
dependencies = [
"proc-macro2",
"quote",
@ -2027,9 +2104,9 @@ checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
[[package]]
name = "tempfile"
version = "3.12.0"
version = "3.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
dependencies = [
"cfg-if",
"fastrand",
@ -2058,6 +2135,16 @@ dependencies = [
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tinyvec"
version = "1.8.0"
@ -2125,6 +2212,19 @@ dependencies = [
"tungstenite",
]
[[package]]
name = "tokio-util"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tower"
version = "0.5.1"
@ -2141,6 +2241,31 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower-http"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"http-range-header",
"httpdate",
"mime",
"mime_guess",
"percent-encoding",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
@ -2183,6 +2308,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"nu-ansi-term",
"sharded-slab",
"smallvec",
"thread_local",
"tracing-core",
"tracing-log",
]
[[package]]
@ -2210,10 +2361,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-bidi"
version = "0.3.15"
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
[[package]]
name = "unicode-ident"
@ -2232,9 +2392,9 @@ dependencies = [
[[package]]
name = "unicode-properties"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unicode-segmentation"
@ -2303,6 +2463,12 @@ dependencies = [
"serde",
]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"

View file

@ -5,15 +5,19 @@ edition = "2021"
[dependencies]
http = "1"
axum = { version = "0.7.5", features = [ "json", "macros" ] }
axum = { version = "0.7.5", features = [ "json", "macros", "ws" ] }
axum-macros = "0.4.1"
chrono = { version = "0.4", features = [ "serde" ] }
chrono-tz = "0.10.0"
maud = "0.26.0"
sqlx = { version = "0.8.2", features = [ "postgres", "runtime-tokio", "tls-rustls-ring", "uuid", "chrono" ] }
tokio = { version = "1.40.0", features = [ "full" ] }
tokio-tungstenite = "0.24.0"
dashmap = "6"
serde = { version = "1", features = [ "derive" ] }
thiserror = "1"
anyhow = "1"
uuid = { version = "1.10.0", features = [ "serde" ] }
rand = "0.8.5"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"
axum_static = "1.7.1"

View file

@ -6,15 +6,15 @@ use axum::{
use rand::distributions::{Alphanumeric, DistString};
use sqlx::{Pool, Postgres, QueryBuilder};
use crate::model::Chat;
use crate::{model::Chat, state::AppState};
pub fn router(pool: Pool<Postgres>) -> Router {
pub fn router(state: AppState) -> Router {
Router::new()
.route("/new/:amount", get(create))
.with_state(pool)
.with_state(state)
}
async fn create(Path(amount): Path<u8>, State(pool): State<Pool<Postgres>>) -> Json<Vec<Chat>> {
async fn create(Path(amount): Path<u8>, State(state): State<AppState>) -> Json<Vec<Chat>> {
let paths: Vec<String> = (0..amount)
.map(|_| Alphanumeric.sample_string(&mut rand::thread_rng(), 6))
.collect();
@ -25,7 +25,7 @@ async fn create(Path(amount): Path<u8>, State(pool): State<Pool<Postgres>>) -> J
})
.push("returning *")
.build_query_as()
.fetch_all(&pool)
.fetch_all(state.pool())
.await
.unwrap();

View file

@ -10,42 +10,55 @@ use axum::{
use maud::{html, Render};
use serde::{Deserialize, Serialize};
use sqlx::{Pool, Postgres};
use tracing::error;
use uuid::Uuid;
use crate::{
markup_response::{simple_error_page, MarkupResponse},
model::{Chat, Message},
state::AppState,
ADMIN_TOK,
};
pub async fn get(
Path(url_path): Path<String>,
headers: HeaderMap,
State(pool): State<Pool<Postgres>>,
State(state): State<AppState>,
) -> impl IntoResponse {
println!("headers: {headers:#?}");
let chat = sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
.fetch_one(&pool)
.await
.unwrap();
let messages = sqlx::query_as!(
Message,
r#"select * from messages where chat_id = $1"#,
chat.id
)
.fetch_all(&pool)
.await
.unwrap();
// TODO: Error handling
let chat = match state.fetch_chat_by_url_path(&url_path).await {
Ok(v) => v,
Err(err) => {
error!("Error fetching chat: {err:?}");
return simple_error_page(err.into()).into_response();
}
};
let messages = match state.fetch_messages(&chat).await {
Ok(v) => v,
Err(err) => {
error!("Error fetching messages for chat {}: {err:?}", chat.id);
return simple_error_page(err.into()).into_response();
}
};
if Some(&HeaderValue::from_static("application/json")) == headers.get(ACCEPT) {
Json(messages).into_response()
} else {
Html(
MarkupResponse::new(
html! {
template #chatmessage {
div.message {
p { }
span.timestamp { }
}
}
main {
div #history {
@for msg in &messages {
div.message.(if msg.from_admin { "from_admin" } else { "from_user" }) {
p { (msg.content) "(" (msg.timestamp) ")" }
div.message.(if msg.from_admin { "from_admin" } else { "from_user" }) #(msg.id) {
p { (msg.content) }
span.timestamp { (msg.timestamp) }
}
}
}
@ -54,24 +67,45 @@ pub async fn get(
button type="submit" { "Send!" }
}
}
}
.into_string(),
script src="/static/chat.js" {};
},
"Cursed Messenger from hell",
)
.into_response()
}
}
pub async fn poll(Path(message): Path<Uuid>, State(state): State<AppState>) -> impl IntoResponse {
let message = sqlx::query_as!(Message, r#"select * from messages where id = $1"#, message)
.fetch_one(state.pool())
.await
.unwrap();
let new_messages = sqlx::query_as!(
Message,
r#"select * from messages where chat_id = $1 and timestamp > $2;"#,
message.chat_id,
message.timestamp
)
.fetch_all(state.pool())
.await
.unwrap();
Json(new_messages)
}
// TODO:
// - validation of msg length
// - fix terrible returns lmao
pub async fn post(
Path(url_path): Path<String>,
headers: HeaderMap,
State(pool): State<Pool<Postgres>>,
State(state): State<AppState>,
Form(FormMessageBody { msgcontent: body }): Form<FormMessageBody>,
) -> impl IntoResponse {
let chat = sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
.fetch_one(&pool)
.fetch_one(state.pool())
.await
.unwrap();
@ -85,7 +119,7 @@ pub async fn post(
chat.id,
body
)
.execute(&pool)
.execute(state.pool())
.await
.unwrap();
StatusCode::OK.into_response()
@ -95,7 +129,7 @@ pub async fn post(
chat.id,
body
)
.execute(&pool)
.execute(state.pool())
.await
.unwrap();
Redirect::to(&format!("/{url_path}")).into_response()

View file

@ -1,26 +1,36 @@
use axum::{routing::get, Router};
use sqlx::{Pool, Postgres};
use state::AppState;
use tracing::Level;
use tracing_subscriber::FmtSubscriber;
const DB_URL: &str = "postgres://localhost/chatdings";
const ADMIN_TOK: &str = "meow";
mod admin;
mod chat;
mod markup_response;
mod model;
mod stat;
mod state;
mod ws;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let pool = Pool::<Postgres>::connect(DB_URL).await?;
let subscriber = FmtSubscriber::builder()
.with_max_level(Level::TRACE)
.finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
sqlx::migrate!().run(&pool).await?;
let state = AppState::init().await?;
let app = Router::new()
.route("/", get(|| async { "<h1>gay</h1>" }))
.route("/:path", get(chat::get).post(chat::post))
.with_state(pool.clone())
.nest("/stat", stat::router(pool.clone()))
.nest("/admin", admin::router(pool.clone()));
.route("/poll/:msg", get(chat::poll))
.with_state(state.clone())
.nest("/stat", stat::router(state.clone()))
.nest("/admin", admin::router(state.clone()))
.nest("/static", axum_static::static_router("static"));
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
axum::serve(listener, app).await?;

View file

@ -0,0 +1,47 @@
use axum::response::{Html, IntoResponse};
use http::StatusCode;
use maud::{html, Markup, DOCTYPE};
pub struct MarkupResponse {
title: String,
body: Markup,
}
impl MarkupResponse {
pub fn new(body: Markup, title: &str) -> Self {
Self {
title: title.to_owned(),
body,
}
}
}
impl IntoResponse for MarkupResponse {
fn into_response(self) -> axum::response::Response {
Html::from(base_page(&self.title, &self.body).into_string()).into_response()
}
}
fn base_page(title: &str, markup: &Markup) -> Markup {
html! {
(DOCTYPE)
html lang="en" {
head {
meta charset="utf-8";
meta name="viewport" content="width=device-width, initial-scale=1";
title { (title) }
// link rel="stylesheet" href="/style";
}
body { (markup) }
}
}
}
pub fn simple_error_page(status: StatusCode) -> MarkupResponse {
MarkupResponse::new(
html! {
img src=(format!("https://http.cat/{}", status.as_u16()));
},
"Error",
)
}

View file

@ -3,16 +3,16 @@ use std::sync::Arc;
use axum::{extract::State, routing::get, Json, Router};
use sqlx::{types::Uuid, Pool, Postgres};
use crate::model::Chat;
use crate::{model::Chat, state::AppState};
// TODO: /stat/* should require authentication
pub fn router(pool: Pool<Postgres>) -> Router {
Router::new().route("/chats", get(chats)).with_state(pool)
pub fn router(state: AppState) -> Router {
Router::new().route("/chats", get(chats)).with_state(state)
}
async fn chats(State(pool): State<Pool<Postgres>>) -> Json<Vec<Chat>> {
async fn chats(State(state): State<AppState>) -> Json<Vec<Chat>> {
let r = sqlx::query_as!(Chat, "select * from chats;")
.fetch_all(&pool)
.fetch_all(state.pool())
.await
.unwrap();

View file

@ -0,0 +1,74 @@
use axum::response::IntoResponse;
use http::StatusCode;
use sqlx::{Pool, Postgres};
use thiserror::Error;
use crate::model::{Chat, Message};
type Result<T> = std::result::Result<T, AppStateError>;
const DB_URL: &str = "postgres://localhost/chatdings";
#[derive(Debug, Clone)]
pub struct AppState {
pool: Pool<Postgres>,
}
impl AppState {
pub async fn init() -> Result<Self> {
let pool = Pool::<Postgres>::connect(DB_URL).await?;
sqlx::migrate!()
.run(&pool)
.await
.expect("migration should not fail");
Ok(Self { pool })
}
pub async fn fetch_chat_by_url_path(&self, url_path: &str) -> Result<Chat> {
Ok(
sqlx::query_as!(Chat, r#"select * from chats where url_path = $1"#, url_path)
.fetch_one(&self.pool)
.await?,
)
}
pub async fn fetch_messages(&self, chat: &Chat) -> Result<Vec<Message>> {
Ok(sqlx::query_as!(
Message,
r#"select * from messages where chat_id = $1"#,
chat.id
)
.fetch_all(&self.pool)
.await?)
}
pub async fn send_message(&self, chat: &Chat, content: String, from_admin: bool) -> Result<()> {
todo!()
}
pub fn pool(&self) -> &Pool<Postgres> {
&self.pool
}
}
#[derive(Error, Debug)]
pub enum AppStateError {
#[error("database error")]
Sqlx(#[from] sqlx::Error),
}
impl IntoResponse for AppStateError {
fn into_response(self) -> axum::response::Response {
todo!()
}
}
impl From<AppStateError> for StatusCode {
fn from(value: AppStateError) -> Self {
match value {
AppStateError::Sqlx(sqlx::Error::RowNotFound) => Self::NOT_FOUND,
AppStateError::Sqlx(_) => Self::INTERNAL_SERVER_ERROR,
}
}
}

15
crates/backend/src/ws.rs Normal file
View file

@ -0,0 +1,15 @@
use axum::{
extract::{ws::WebSocket, Path, State, WebSocketUpgrade},
response::Response,
};
use sqlx::{Pool, Postgres};
fn get(
Path(url_path): Path<String>,
ws: WebSocketUpgrade,
State(pool): State<Pool<Postgres>>,
) -> Response {
todo!()
}
// fn handle_socket(socket: WebSocket, pool: Pool<Postgres>)

26
static/chat.js Normal file
View file

@ -0,0 +1,26 @@
init_polling();
// terrible hack. uses polling.
function init_polling() {
let history_el = document.getElementById("history");
let msg_template = document.querySelector("#chatmessage");
setInterval(() => {
let messages = document.getElementsByClassName("message");
let last_msg_uuid = messages[messages.length - 1].id;
fetch(`/poll/${last_msg_uuid}`)
.then(data => data.text().then(bleh => {
let new_messages = JSON.parse(bleh);
for (const message of new_messages) {
const clone = msg_template.content.cloneNode(true);
let msgclone = clone.querySelector("div");
msgclone.id = message.id;
msgclone.classList.add(message.from_admin ? "from_admin" : "from_user");
let content = msgclone.querySelector("p");
content.textContent = message.content;
let ts = msgclone.querySelector(".timestamp");
ts.textContent = message.timestamp;
history_el.appendChild(msgclone);
}
}));
}, 5000)
}