diff options
author | Vika <vika@fireburn.ru> | 2022-03-23 05:01:14 +0300 |
---|---|---|
committer | Vika <vika@fireburn.ru> | 2022-03-23 05:01:14 +0300 |
commit | 54914782c7632e041919746e80d3f802f6601a63 (patch) | |
tree | d54286ddb5424a16921cd0e21cb3917fa47a05a6 | |
parent | 8964a0330d77fe5a75d33c504791db601d2b0ac7 (diff) | |
download | kittybox-54914782c7632e041919746e80d3f802f6601a63.tar.zst |
Make the settings in the database a strong type
-rw-r--r-- | Cargo.lock | 10 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/database/file/mod.rs | 10 | ||||
-rw-r--r-- | src/database/memory.rs | 6 | ||||
-rw-r--r-- | src/database/mod.rs | 22 | ||||
-rw-r--r-- | src/frontend/mod.rs | 6 |
6 files changed, 42 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock index bad84b2..9a3c9c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1459,6 +1459,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "serde_variant", "sha2", "tempdir", "test-logger", @@ -2536,6 +2537,15 @@ dependencies = [ ] [[package]] +name = "serde_variant" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f988d71f968b960b45cf71e3210662f0b23906256c87820077e4f101225c494" +dependencies = [ + "serde", +] + +[[package]] name = "servo_arc" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 539f973..33f8c2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ rand = "^0.8.4" # Random number generators. retainer = "^0.2.2" # Minimal async cache in Rust with support for key expirations serde_json = "^1.0.64" # A JSON serialization file format serde_urlencoded = "^0.7.0" # `x-www-form-urlencoded` meets Serde +serde_variant = "^0.1.1" # Retrieve serde provided variant names for enum objects relative-path = "^1.5.0" # Portable relative paths for Rust sha2 = "^0.9.8" # SHA-2 series of algorithms for Rust warp-prometheus = "^0.5.0" # An afterthought of prometheus metrics for Warp diff --git a/src/database/file/mod.rs b/src/database/file/mod.rs index af07c0c..b3856a6 100644 --- a/src/database/file/mod.rs +++ b/src/database/file/mod.rs @@ -1,5 +1,5 @@ //#![warn(clippy::unwrap_used)] -use crate::database::{filter_post, ErrorKind, Result, Storage, StorageError}; +use crate::database::{filter_post, ErrorKind, Result, Storage, StorageError, Settings}; use std::fs::{File, OpenOptions}; use std::io::{ErrorKind as IOErrorKind, Seek, SeekFrom, Read, Write}; use std::time::Duration; @@ -387,6 +387,10 @@ impl Storage for FileStorage { { symlink_result = std::os::windows::fs::symlink_file(relative, link); } + #[cfg(all(not(unix), not(windows)))] + { + compile_error!("Don't know how to create symlinks on non-unix non-windows platform"); + } if let Err(e) = symlink_result { Err(e.into()) } else { @@ -596,7 +600,7 @@ impl Storage for FileStorage { } } - async fn get_setting(&self, setting: &'_ str, user: &'_ str) -> Result<String> { + async fn get_setting(&self, setting: Settings, user: &'_ str) -> Result<String> { log::debug!("User for getting settings: {}", user); let url = warp::http::Uri::try_from(user).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); @@ -626,7 +630,7 @@ impl Storage for FileStorage { )).await?.unwrap() } - async fn set_setting(&self, setting: &'_ str, user: &'_ str, value: &'_ str) -> Result<()> { + async fn set_setting(&self, setting: Settings, user: &'_ str, value: &'_ str) -> Result<()> { let url = warp::http::Uri::try_from(user).expect("Couldn't parse a URL"); let mut path = relative_path::RelativePathBuf::new(); path.push(url.authority().unwrap().to_string()); diff --git a/src/database/memory.rs b/src/database/memory.rs index df142d3..5e2ad52 100644 --- a/src/database/memory.rs +++ b/src/database/memory.rs @@ -6,7 +6,7 @@ use tokio::sync::RwLock; use futures_util::FutureExt; use serde_json::json; -use crate::database::{Storage, Result, StorageError, ErrorKind, MicropubChannel}; +use crate::database::{Storage, Result, StorageError, ErrorKind, MicropubChannel, Settings}; #[derive(Clone, Debug)] pub struct MemoryStorage { @@ -177,12 +177,12 @@ impl Storage for MemoryStorage { } #[allow(unused_variables)] - async fn get_setting(&self, setting: &'_ str, user: &'_ str) -> Result<String> { + async fn get_setting(&self, setting: Settings, user: &'_ str) -> Result<String> { todo!() } #[allow(unused_variables)] - async fn set_setting(&self, setting: &'_ str, user: &'_ str, value: &'_ str) -> Result<()> { + async fn set_setting(&self, setting: Settings, user: &'_ str, value: &'_ str) -> Result<()> { todo!() } } diff --git a/src/database/mod.rs b/src/database/mod.rs index e7baaa8..57223f8 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -39,6 +39,20 @@ pub enum ErrorKind { Other, } +/// Enum representing settings that might be stored in the site's database. +#[derive(Serialize, Debug, Clone, Copy)] +#[serde(rename_all = "snake_case")] +pub enum Settings { + /// The name of the website -- displayed in the header and the browser titlebar. + SiteName, +} + +impl std::string::ToString for Settings { + fn to_string(&self) -> String { + serde_variant::to_variant_name(self).unwrap().to_string() + } +} + /// Error signalled from the database. #[derive(Debug)] pub struct StorageError { @@ -239,10 +253,10 @@ pub trait Storage: std::fmt::Debug + Clone + Send + Sync { async fn delete_post(&self, url: &'_ str) -> Result<()>; /// Gets a setting from the setting store and passes the result. - async fn get_setting(&self, setting: &'_ str, user: &'_ str) -> Result<String>; + async fn get_setting(&self, setting: Settings, user: &'_ str) -> Result<String>; /// Commits a setting to the setting store. - async fn set_setting(&self, setting: &'_ str, user: &'_ str, value: &'_ str) -> Result<()>; + async fn set_setting(&self, setting: Settings, user: &'_ str, value: &'_ str) -> Result<()>; } #[cfg(test)] @@ -399,12 +413,12 @@ mod tests { async fn test_backend_settings<Backend: Storage>(backend: Backend) { backend - .set_setting("site_name", "https://fireburn.ru/", "Vika's Hideout") + .set_setting(crate::database::Settings::SiteName, "https://fireburn.ru/", "Vika's Hideout") .await .unwrap(); assert_eq!( backend - .get_setting("site_name", "https://fireburn.ru/") + .get_setting(crate::database::Settings::SiteName, "https://fireburn.ru/") .await .unwrap(), "Vika's Hideout" diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index b594fc6..1069b92 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -270,7 +270,7 @@ pub fn homepage<D: Storage>(db: D, endpoints: IndiewebEndpoints) -> impl Filter< .and(warp::any().map(inject_db)) .then(|content: (Option<serde_json::Value>, Option<serde_json::Value>, StatusCode), endpoints: IndiewebEndpoints, host: Authority, db: D| async move { let owner = format!("https://{}/", host.as_str()); - let blog_name = db.get_setting("site_name", &owner).await + let blog_name = db.get_setting(crate::database::Settings::SiteName, &owner).await .unwrap_or_else(|_| "Kitty Box!".to_string()); let feeds = db.get_channels(&owner).await.unwrap_or_default(); match content { @@ -323,7 +323,7 @@ pub fn onboarding<D: Storage, T: hyper::client::connect::Connect + Clone + Send if body.user["type"][0] != "h-card" || body.first_post["type"][0] != "h-entry" { return Err(FrontendError::with_code(StatusCode::BAD_REQUEST, "user and first_post should be an h-card and an h-entry").into()); } - db.set_setting("site_name", user.me.as_str(), &body.blog_name) + db.set_setting(crate::database::Settings::SiteName, user.me.as_str(), &body.blog_name) .await .map_err(FrontendError::from)?; @@ -401,7 +401,7 @@ pub fn catchall<D: Storage>(db: D, endpoints: IndiewebEndpoints) -> impl Filter< .and(warp::any().map(inject_db)) .then(|content: (String, String, StatusCode), endpoints: IndiewebEndpoints, host: Authority, db: D| async move { let owner = format!("https://{}/", host.as_str()); - let blog_name = db.get_setting("site_name", &owner).await + let blog_name = db.get_setting(crate::database::Settings::SiteName, &owner).await .unwrap_or_else(|_| "Kitty Box!".to_string()); let feeds = db.get_channels(&owner).await.unwrap_or_default(); let (title, content, code) = content; |