| 13 | |
| 14 | #[tokio::main] |
| 15 | async fn main() -> Result<(), handle_errors::Error> { |
| 16 | let config = config::Config::new().expect("Config can't be set"); |
| 17 | |
| 18 | let log_filter = format!( |
| 19 | "handle_errors={},rust_web_dev={},warp={}", |
| 20 | config.log_level, config.log_level, config.log_level |
| 21 | ); |
| 22 | |
| 23 | let store = store::Store::new(&format!( |
| 24 | "postgres://{}:{}@{}:{}/{}", |
| 25 | config.db_user, |
| 26 | config.db_password, |
| 27 | config.db_host, |
| 28 | config.db_port, |
| 29 | config.db_name |
| 30 | )) |
| 31 | .await |
| 32 | .map_err(handle_errors::Error::DatabaseQueryError)?; |
| 33 | |
| 34 | sqlx::migrate!() |
| 35 | .run(&store.clone().connection) |
| 36 | .await |
| 37 | .map_err(handle_errors::Error::MigrationError)?; |
| 38 | |
| 39 | let store_filter = warp::any().map(move || store.clone()); |
| 40 | |
| 41 | tracing_subscriber::fmt() |
| 42 | // Use the filter we built above to determine which traces to record. |
| 43 | .with_env_filter(log_filter) |
| 44 | // Record an event when each span closes. This can be used to time our |
| 45 | // routes' durations! |
| 46 | .with_span_events(FmtSpan::CLOSE) |
| 47 | .init(); |
| 48 | |
| 49 | let cors = warp::cors() |
| 50 | .allow_any_origin() |
| 51 | .allow_header("content-type") |
| 52 | .allow_methods(&[ |
| 53 | Method::PUT, |
| 54 | Method::DELETE, |
| 55 | Method::GET, |
| 56 | Method::POST, |
| 57 | ]); |
| 58 | |
| 59 | let get_questions = warp::get() |
| 60 | .and(warp::path("questions")) |
| 61 | .and(warp::path::end()) |
| 62 | .and(warp::query()) |
| 63 | .and(store_filter.clone()) |
| 64 | .and_then(routes::question::get_questions); |
| 65 | |
| 66 | let update_question = warp::put() |
| 67 | .and(warp::path("questions")) |
| 68 | .and(warp::path::param::<i32>()) |
| 69 | .and(warp::path::end()) |
| 70 | .and(routes::authentication::auth()) |
| 71 | .and(store_filter.clone()) |
| 72 | .and(warp::body::json()) |