diff --git a/.gitignore b/.gitignore index ea8c4bf..4c8088d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +ttc_test* diff --git a/.sqlx/query-f17495d023bac377869af665478b21bb962599df4bf7f59dd8336dc538f5a8fb.json b/.sqlx/query-f17495d023bac377869af665478b21bb962599df4bf7f59dd8336dc538f5a8fb.json new file mode 100644 index 0000000..c9fbd99 --- /dev/null +++ b/.sqlx/query-f17495d023bac377869af665478b21bb962599df4bf7f59dd8336dc538f5a8fb.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "SELECT pronouns \n FROM pronouns \n WHERE username == ?", + "describe": { + "columns": [ + { + "name": "pronouns", + "ordinal": 0, + "type_info": "Text" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false + ] + }, + "hash": "f17495d023bac377869af665478b21bb962599df4bf7f59dd8336dc538f5a8fb" +} diff --git a/Cargo.lock b/Cargo.lock index 39d17bd..5eb7b87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,7 @@ checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", + "axum-macros", "bitflags 1.3.2", "bytes", "futures-util", @@ -110,6 +111,18 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-macros" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.23", +] + [[package]] name = "backtrace" version = "0.3.68" diff --git a/Cargo.toml b/Cargo.toml index 7106258..8bc851f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axum = "0.6.18" +axum ={ version = "0.6.18", features = ["macros"] } tokio = { version = "1.29.1", features = ["full"] } rand = { version = "0.8.5", features = ["std"] } sqlx = { version = "0.7.1", features = ["runtime-tokio", "sqlite"] } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..7609593 --- /dev/null +++ b/build.rs @@ -0,0 +1,5 @@ +// generated by `sqlx migrate build-script` +fn main() { + // trigger recompilation when a new migration is added + println!("cargo:rerun-if-changed=migrations"); +} \ No newline at end of file diff --git a/migrations/0001_ttc_db.sql b/migrations/0001_ttc_db.sql new file mode 100644 index 0000000..fe47659 --- /dev/null +++ b/migrations/0001_ttc_db.sql @@ -0,0 +1,6 @@ +CREATE TABLE pronouns ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT NOT NULL, + pronouns TEXT NOT NULL +); + diff --git a/src/main.rs b/src/main.rs index 11bfe0a..af6fdb5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,36 +1,51 @@ -use std::{sync::Arc, env}; +use std::env; use axum::{ routing::get, Router, - extract::Path, + extract::{Path, State}, http::StatusCode, }; +use rand::{ thread_rng, seq::IteratorRandom }; use sqlx::{SqlitePool, sqlite::SqlitePoolOptions}; -struct AppState { - pub db_pool: SqlitePool, -} async fn user_pronouns( + State(pool): State, Path(user): Path, - ) -> String { - user + ) -> Result { + let res = sqlx::query!("SELECT pronouns + FROM pronouns + WHERE username == ?", + user) + .fetch_one(&pool) + .await + .map_err(|err| match err { + sqlx::Error::RowNotFound => StatusCode::NOT_FOUND, + _ => StatusCode::INTERNAL_SERVER_ERROR + })?; + res.pronouns + .split(';') + .choose(&mut thread_rng()) + .map(ToOwned::to_owned) + .ok_or(StatusCode::NOT_FOUND) } #[tokio::main] async fn main() { + let pool = SqlitePoolOptions::new() + .max_connections(5) + .connect(env::var("TTC_DATABASE_URL") + .unwrap_or("sqlite:ttc.db".into()) + .as_ref()) + .await + .unwrap(); + + sqlx::migrate!("./migrations").run(&pool).await.unwrap(); + let app = Router::new() .route("/api/ttc/hello", get(|| async { "hello world!" })) .route("/api/ttc/pronouns/:user", get(user_pronouns)) - .with_state(Arc::new(AppState { - db_pool: SqlitePoolOptions::new() - .max_connections(5) - .connect(env::var("TTC_DATABASE_URL") - .unwrap_or("sqlite:ttc.db".into()) - .as_ref()) - .await - .unwrap() - })); + .with_state(pool); axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service())