stateful warp controllers
This commit is contained in:
parent
61772e3552
commit
2fa3f14597
|
@ -130,6 +130,16 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.9"
|
||||
|
@ -215,6 +225,7 @@ dependencies = [
|
|||
"femme",
|
||||
"futures-util",
|
||||
"log",
|
||||
"redis",
|
||||
"tokio",
|
||||
"warp",
|
||||
]
|
||||
|
@ -696,6 +707,22 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "0.23.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f49cdc0bb3f412bf8e7d1bd90fe1d9eb10bc5c399ba90973c14662a27b3f8ba"
|
||||
dependencies = [
|
||||
"combine",
|
||||
"itoa",
|
||||
"percent-encoding",
|
||||
"ryu",
|
||||
"sha1_smol",
|
||||
"socket2 0.4.9",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
|
@ -786,6 +813,12 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1_smol"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
|
|
|
@ -12,5 +12,6 @@ dotenvy = "0.15.7"
|
|||
femme = "2.2.1"
|
||||
futures-util = "0.3.28"
|
||||
log = "0.4.20"
|
||||
redis = { version = "0.23.3", features = ["tokio"] }
|
||||
tokio = { version = "1.32.0", features = ["rt", "macros", "rt-multi-thread"] }
|
||||
warp = "0.3.6"
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
db.rs - The database adapter
|
||||
*/
|
||||
|
||||
use redis::{Client, RedisError};
|
||||
|
||||
use crate::env::Env;
|
||||
|
||||
pub fn redis_conn(env: Env) -> Result<Client, RedisError> {
|
||||
log::info!("Connecting to redis DB on {}", env.redis.host);
|
||||
redis::Client::open(format!("redis://{}:{}/", env.redis.host, env.redis.port))
|
||||
}
|
|
@ -5,9 +5,19 @@
|
|||
|
||||
use std::{env::var, net::SocketAddr};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Redis {
|
||||
pub pass: String,
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub prefix: String
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Env {
|
||||
pub logging: bool,
|
||||
pub listen: SocketAddr
|
||||
pub listen: SocketAddr,
|
||||
pub redis: Redis,
|
||||
}
|
||||
|
||||
fn get_var<T: Into<String>, O: From<String>>(name: T) -> Result<O, String> {
|
||||
|
@ -23,7 +33,13 @@ pub fn loadenv() -> Result<Env, Box<dyn std::error::Error>> {
|
|||
Ok(
|
||||
Env {
|
||||
logging: get_var::<&str, String>("APP_LOGGING")?.to_lowercase() == "true",
|
||||
listen: get_var::<&str, String>("APP_HOST")?.parse::<SocketAddr>().unwrap()
|
||||
listen: get_var::<&str, String>("APP_HOST")?.parse::<SocketAddr>().unwrap(),
|
||||
redis: Redis {
|
||||
pass: get_var("REDIS_PASS")?,
|
||||
host: get_var("REDIS_HOST")?,
|
||||
port: get_var::<&str, String>("REDIS_PORT")?.parse().unwrap(),
|
||||
prefix: get_var("REDIS_PREFIX")?
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
mod env;
|
||||
mod web;
|
||||
mod db;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use warp::{Filter, reply::{Html, Reply}, reject::Rejection, filters::multipart::FormData};
|
||||
use warp::{Filter, reply::Reply, reject::Rejection, filters::multipart::FormData};
|
||||
use futures_util::TryStreamExt;
|
||||
use bytes::BufMut;
|
||||
|
||||
pub async fn upload(form: FormData) -> Result<Box<dyn Reply>, Rejection> {
|
||||
use super::state::SharedState;
|
||||
|
||||
pub async fn upload(form: FormData, _state: SharedState) -> Result<Box<dyn Reply>, Rejection> {
|
||||
|
||||
let params: HashMap<String, String> = form.and_then(|mut field| async move {
|
||||
let mut bytes: Vec<u8> = vec![];
|
||||
|
@ -23,8 +25,10 @@ pub async fn upload(form: FormData) -> Result<Box<dyn Reply>, Rejection> {
|
|||
Ok(Box::new(warp::reply::json(¶ms)))
|
||||
}
|
||||
|
||||
pub fn get_routes() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
pub fn get_routes(state: SharedState) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
warp::post().and(
|
||||
warp::multipart::form().and_then(upload)
|
||||
warp::multipart::form()
|
||||
.and(warp::any().map(move || state.clone()))
|
||||
.and_then(upload)
|
||||
)
|
||||
}
|
|
@ -10,13 +10,16 @@ use crate::env::Env;
|
|||
|
||||
mod pages;
|
||||
mod forms;
|
||||
mod state;
|
||||
|
||||
pub fn routes() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
use state::SharedState;
|
||||
|
||||
pub fn routes(state: SharedState) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
let staticpath = current_dir().unwrap();
|
||||
let staticpath = staticpath.to_str().unwrap().to_string() + "/static";
|
||||
|
||||
pages::get_routes()
|
||||
.or(forms::get_routes())
|
||||
pages::get_routes(state.clone())
|
||||
.or(forms::get_routes(state))
|
||||
.or(warp::fs::dir(staticpath.to_string()))
|
||||
}
|
||||
|
||||
|
@ -27,5 +30,9 @@ pub async fn serve(env: Env) {
|
|||
|
||||
log::info!("Listening on {}", env.listen.to_string());
|
||||
|
||||
warp::serve(routes()).run(env.listen).await;
|
||||
let state = SharedState {
|
||||
redis_cli: crate::db::redis_conn(env.clone()).unwrap()
|
||||
};
|
||||
|
||||
warp::serve(routes(state)).run(env.listen).await;
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
use warp::{reply::{Reply, Html}, Filter, reject::Rejection};
|
||||
use askama::Template;
|
||||
|
||||
use super::state::SharedState;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template( path = "index.html" )]
|
||||
struct Index {}
|
||||
|
@ -14,7 +16,7 @@ pub fn index() -> Html<String> {
|
|||
warp::reply::html(rendered.render().unwrap())
|
||||
}
|
||||
|
||||
pub fn get_routes() -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
pub fn get_routes(_state: SharedState) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
let index_r = warp::path::end().map(index);
|
||||
|
||||
warp::any().and(index_r)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
use redis::Client;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SharedState {
|
||||
pub redis_cli: Client
|
||||
}
|
Loading…
Reference in New Issue