diff --git a/Cargo.lock b/Cargo.lock index 9b594b64e34572046629a754ac5b80c6b62a8f11..f96365e3b3624dfb05a370c868bc9d74e437134e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2442,11 +2442,18 @@ dependencies = [ "simple-logging", "strfmt", "structopt", + "strum", "thiserror", "url", "uuid 1.0.0-alpha.1", ] +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + [[package]] name = "ryu" version = "1.0.9" @@ -2857,6 +2864,28 @@ dependencies = [ "syn", ] +[[package]] +name = "strum" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "subtle" version = "2.4.1" diff --git a/Cargo.toml b/Cargo.toml index c516f8bad14a427a529cece4c502db96d37d5a6c..d1d90ddfd6c5935e8d7f13f3e0f704ebd53318b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ name = "rustus" [dependencies] actix-web = "^3.3.2" actix-files = "^0.5.0" -derive_more = "^0.99.9" +derive_more = { version = "^0.99.9", default-features = false, features = ["display", "from", "from_str"] } thiserror = "^1.0" async-trait = "0.1.52" structopt = { version = "^0.3" } @@ -25,6 +25,14 @@ url = "2.2.2" base64 = "^0.13.0" simple-logging = { version = "^2.0.2" } strfmt = "^0.1.6" -rbson = "2.0" -rbatis = { version = "^3.0", default-features = false, features = ["runtime-async-std-rustls", "all-database"] } -mobc-redis = { version = "0.7.0", features = ["async-std-comp"] } \ No newline at end of file +strum = { version = "0.23", features = ["derive"] } +rbson = { version = "2.0", optional = true } +rbatis = { version = "^3.0", default-features = false, features = ["runtime-async-std-rustls", "all-database"], optional = true } +mobc-redis = { version = "0.7.0", features = ["async-std-comp"], optional = true } + + +[features] +default = [] +all = ["redis_info_storage", "db_info_storage"] +redis_info_storage = ["mobc-redis"] +db_info_storage = ["rbatis", "rbson"] \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index bbb623267bcf1f2a616c116d32c5270a65f371b1..2a0a73d68d3c45bca60db7f67efb6bb8800ea86c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -54,6 +54,7 @@ pub struct InfoStoreOptions { #[structopt(long, default_value = "./data", env = "RUSTUS_INFO_DIR")] pub info_dir: PathBuf, + #[cfg(any(feature = "redis_info_storage", feature = "db_info_storage"))] #[structopt( long, required_if("info-storage", "db_info_storage"), diff --git a/src/errors.rs b/src/errors.rs index 76c022effec81e7679ecd54b3bbad5bc3a4c4bc1..30a8ef98fb48b1de97940940fa710a0ec7cb1715 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -18,10 +18,13 @@ pub enum RustusError { Unknown, #[error("Unable to serialize object")] UnableToSerialize(#[from] serde_json::Error), + #[cfg(feature = "db_info_storage")] #[error("Database error: {0}")] DatabaseError(#[from] rbatis::error::Error), + #[cfg(feature = "redis_info_storage")] #[error("Redis error: {0}")] RedisError(#[from] mobc_redis::redis::RedisError), + #[cfg(feature = "redis_info_storage")] #[error("Redis error: {0}")] MobcError(#[from] mobc_redis::mobc::Error<mobc_redis::redis::RedisError>), #[error("Unable to get file information")] diff --git a/src/info_storages/mod.rs b/src/info_storages/mod.rs index 1c9dd14709c92f2b0b9ea384d132526adf34f3b4..e444828a8c38163bacc7d3a45a76f4caee3d3de2 100644 --- a/src/info_storages/mod.rs +++ b/src/info_storages/mod.rs @@ -10,17 +10,23 @@ use crate::RustusConf; mod file_info; +use strum::{EnumIter, IntoEnumIterator}; + +#[cfg(feature = "db_info_storage")] pub mod db_info_storage; pub mod file_info_storage; +#[cfg(feature = "redis_info_storage")] pub mod redis_info_storage; -#[derive(PartialEq, From, Display, Clone, Debug)] +#[derive(PartialEq, From, Display, Clone, Debug, EnumIter)] pub enum AvailableInfoStores { - #[display(fmt = "File info storage")] + #[display(fmt = "file_info_storage")] Files, - #[display(fmt = "DB info storage")] + #[cfg(feature = "db_info_storage")] + #[display(fmt = "db_info_storage")] DB, - #[display(fmt = "Redis info storage")] + #[cfg(feature = "redis_info_storage")] + #[display(fmt = "redis_info_storage")] Redis, } @@ -28,12 +34,20 @@ impl FromStr for AvailableInfoStores { type Err = String; fn from_str(input: &str) -> Result<Self, Self::Err> { - match input { - "file_info_storage" => Ok(AvailableInfoStores::Files), - "db_info_storage" => Ok(AvailableInfoStores::DB), - "redis_info_storage" => Ok(AvailableInfoStores::Redis), - _ => Err(String::from("Unknown storage type")), + let available_stores = AvailableInfoStores::iter() + .map(|info_store| format!("\t* {}", info_store.to_string())) + .collect::<Vec<String>>() + .join("\n"); + let inp_string = String::from(input); + for store in AvailableInfoStores::iter() { + if inp_string == store.to_string() { + return Ok(store); + } } + Err(format!( + "Unknown info storage type.\n Available storages:\n{}", + available_stores + )) } } @@ -51,9 +65,11 @@ impl AvailableInfoStores { Self::Files => Ok(Box::new(file_info_storage::FileInfoStorage::new( config.clone(), ))), + #[cfg(feature = "db_info_storage")] Self::DB => Ok(Box::new( db_info_storage::DBInfoStorage::new(config.clone()).await?, )), + #[cfg(feature = "redis_info_storage")] AvailableInfoStores::Redis => Ok(Box::new( redis_info_storage::RedisStorage::new(config.clone()).await?, )),