diff options
-rw-r--r-- | Cargo.toml | 8 | ||||
-rw-r--r-- | src/database/mod.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 50 | ||||
-rw-r--r-- | src/main.rs | 50 |
4 files changed, 93 insertions, 21 deletions
diff --git a/Cargo.toml b/Cargo.toml index 3974d9c..3f93407 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [features] default = ["util"] util = ["anyhow"] +redis = ["mobc", "mobc-redis"] [[bin]] name = "kittybox-bulk-import" @@ -16,7 +17,7 @@ required-features = ["util"] [[bin]] name = "pyindieblog-export" path = "src/bin/pyindieblog_to_kittybox.rs" -required-features = ["util"] +required-features = ["util", "redis"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dev-dependencies] @@ -39,7 +40,6 @@ lazy_static = "^1.4.0" # A macro for declaring lazily evaluated statics in log = "^0.4.14" # A lightweight logging facade for Rust markdown = "^0.3.0" # Native Rust library for parsing Markdown and (outputting HTML) markup = "^0.12.0" # HTML templating engine... ok also very funny about markdown and markup... i just realized the pun... -mobc = "^0.7.2" # A generic connection pool with async/await support newbase60 = "^0.1.3" # A library that implements Tantek Çelik's New Base 60 retainer = "^0.2.2" # Minimal async cache in Rust with support for key expirations serde_json = "^1.0.64" # A JSON serialization file format @@ -54,8 +54,12 @@ features = ["attributes", "unstable"] [dependencies.chrono] # Date and time library for Rust version = "^0.4.19" features = ["serde"] +[dependencies.mobc] # A generic connection pool with async/await support +version = "^0.7.2" +optional = true [dependencies.mobc-redis] # Redis support for the mobc connection pool version = "^0.7.0" +optional = true features = ["async-std-comp"] default-features = false [dependencies.prometheus] # Prometheus instrumentation library for Rust applications diff --git a/src/database/mod.rs b/src/database/mod.rs index e6873b0..a1f5861 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -3,10 +3,14 @@ use crate::indieauth::User; use async_trait::async_trait; use serde::{Deserialize, Serialize}; +#[cfg(redis)] mod redis; +#[cfg(redis)] pub use crate::database::redis::RedisStorage; +#[cfg(redis)] #[cfg(test)] pub use redis::tests::{get_redis_instance, RedisInstance}; + mod file; pub use crate::database::file::FileStorage; @@ -184,6 +188,7 @@ pub trait Storage: Clone + Send + Sync { #[cfg(test)] mod tests { + #[cfg(redis)] use super::redis::tests::get_redis_instance; use super::{MicropubChannel, Storage}; use serde_json::json; @@ -352,6 +357,7 @@ mod tests { macro_rules! redis_test { ($func_name:expr) => { paste! { + #[cfg(redis)] #[async_std::test] async fn [<redis_ $func_name>] () { test_logger::ensure_env_logger_initialized(); diff --git a/src/lib.rs b/src/lib.rs index 77a6c11..1c6394a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,7 @@ where app } +#[cfg(redis)] pub async fn get_app_with_redis( token_endpoint: surf::Url, authorization_endpoint: surf::Url, @@ -86,7 +87,46 @@ pub async fn get_app_with_redis( equip_app(app) } +pub async fn get_app_with_file( + token_endpoint: surf::Url, + authorization_endpoint: surf::Url, + backend_uri: String, + media_endpoint: Option<String>, + internal_token: Option<String>, +) -> App<database::FileStorage> { + let app = tide::with_state(ApplicationState { + token_endpoint, + media_endpoint, + authorization_endpoint, + internal_token, + storage: database::FileStorage::new(todo!()).await.unwrap(), + http_client: surf::Client::new(), + }); + + equip_app(app) +} + #[cfg(test)] +pub async fn get_app_with_test_file(token_endpoint: surf::Url) -> ( + tempdir::TempDir, + database::FileStorage, + App<database::FileStorage> +) { + use surf::Url; + let tempdir = tempdir::TempDir::new("file").expect("Failed to create tempdir"); + let backend = database::FileStorage::new(tempdir.path().to_path_buf()).await.unwrap(); + let app = tide::with_state(ApplicationState { + token_endpoint, + media_endpoint: None, + authorization_endpoint: Url::parse("https://indieauth.com/auth").unwrap(), + storage: backend.clone(), + internal_token: None, + http_client: surf::Client::new() + }); + (tempdir, backend, equip_app(app)) +} + +#[cfg(all(redis, test))] pub async fn get_app_with_test_redis( token_endpoint: surf::Url, ) -> ( @@ -122,18 +162,18 @@ mod tests { // Helpers async fn create_app() -> ( - database::RedisStorage, - App<database::RedisStorage>, - database::RedisInstance, + database::FileStorage, + App<database::FileStorage>, + tempdir::TempDir, ) { //get_app_with_memory_for_testing(surf::Url::parse(&*mockito::server_url()).unwrap()).await let (r, b, a) = - get_app_with_test_redis(surf::Url::parse(&*mockito::server_url()).unwrap()).await; + get_app_with_test_file(surf::Url::parse(&*mockito::server_url()).unwrap()).await; (b, a, r) } async fn post_json( - app: &App<database::RedisStorage>, + app: &App<database::FileStorage>, json: serde_json::Value, ) -> surf::Response { let request = app diff --git a/src/main.rs b/src/main.rs index 0e57ed5..e91476b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,14 +10,14 @@ async fn main() -> Result<(), std::io::Error> { info!("Starting the kittybox server..."); - let redis_uri: String; - match env::var("REDIS_URI") { + let backend_uri: String; + match env::var("BACKEND_URI") { Ok(val) => { - debug!("Redis connection: {}", val); - redis_uri = val + debug!("Backend URI: {}", val); + backend_uri = val } Err(_) => { - error!("REDIS_URI is not set, cannot find a database"); + error!("BACKEND_URI is not set, cannot find a database"); std::process::exit(1); } }; @@ -63,13 +63,35 @@ async fn main() -> Result<(), std::io::Error> { let host = env::var("SERVE_AT") .ok() .unwrap_or_else(|| "0.0.0.0:8080".to_string()); - let app = kittybox::get_app_with_redis( - token_endpoint, - authorization_endpoint, - redis_uri, - media_endpoint, - internal_token, - ) - .await; - app.listen(host).await + + if backend_uri.starts_with("redis") { + #[cfg(redis)] + { + let app = kittybox::get_app_with_redis( + token_endpoint, + authorization_endpoint, + backend_uri, + media_endpoint, + internal_token, + ).await; + app.listen(host).await + } + #[cfg(not(redis))] + { + println!("The Redis backend was disabled at build-time. Please recompile the package with --features=redis."); + std::process::exit(1); + } + } else if backend_uri.starts_with("file") { + let app = kittybox::get_app_with_file( + token_endpoint, + authorization_endpoint, + backend_uri, + media_endpoint, + internal_token + ).await; + app.listen(host).await + } else { + println!("Unknown backend, not starting."); + std::process::exit(1); + } } |