From a85c1431c87c0239f13218d2be9e019b3943cef2 Mon Sep 17 00:00:00 2001 From: Philippe Loctaux Date: Mon, 27 Feb 2023 16:17:51 +0100 Subject: [PATCH] added settings crate, creating settings on web startup --- Cargo.lock | 40 +++++++++++++++--- crates/ezidam/Cargo.toml | 3 +- crates/ezidam/src/database.rs | 19 ++++++++- crates/settings/Cargo.toml | 9 +++++ crates/settings/src/lib.rs | 74 ++++++++++++++++++++++++++++++++++ logo/ezidam.png | Bin 0 -> 5245 bytes logo/readme.md | 10 +++++ 7 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 crates/settings/Cargo.toml create mode 100644 crates/settings/src/lib.rs create mode 100644 logo/ezidam.png create mode 100644 logo/readme.md diff --git a/Cargo.lock b/Cargo.lock index e85e215..b879652 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,8 +220,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", + "js-sys", "num-integer", "num-traits", + "time 0.1.45", + "wasm-bindgen", "winapi 0.3.9", ] @@ -281,7 +284,7 @@ dependencies = [ "rand", "sha2", "subtle", - "time", + "time 0.3.20", "version_check", ] @@ -523,6 +526,7 @@ dependencies = [ "rocket", "rocket_db_pools", "rocket_dyn_templates", + "settings", ] [[package]] @@ -740,7 +744,7 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -1238,7 +1242,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.45.0", ] @@ -1782,7 +1786,7 @@ dependencies = [ "serde", "state", "tempfile", - "time", + "time 0.3.20", "tokio", "tokio-stream", "tokio-util", @@ -1864,7 +1868,7 @@ dependencies = [ "smallvec", "stable-pattern", "state", - "time", + "time 0.3.20", "tokio", "uncased", ] @@ -1976,6 +1980,15 @@ dependencies = [ "serde", ] +[[package]] +name = "settings" +version = "0.0.0" +dependencies = [ + "chrono", + "database", + "thiserror", +] + [[package]] name = "sha2" version = "0.10.6" @@ -2280,6 +2293,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi 0.3.9", +] + [[package]] name = "time" version = "0.3.20" @@ -2663,6 +2687,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/crates/ezidam/Cargo.toml b/crates/ezidam/Cargo.toml index 8fb2050..4449812 100644 --- a/crates/ezidam/Cargo.toml +++ b/crates/ezidam/Cargo.toml @@ -10,4 +10,5 @@ rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] } infer = { version = "0.12.0", default-features = false } # local crates -database_pool = { path = "../database_pool" } \ No newline at end of file +database_pool = { path = "../database_pool" } +settings = { path = "../settings" } diff --git a/crates/ezidam/src/database.rs b/crates/ezidam/src/database.rs index 03a6b1f..b2d8272 100644 --- a/crates/ezidam/src/database.rs +++ b/crates/ezidam/src/database.rs @@ -2,6 +2,7 @@ use database_pool::run_migrations; use rocket::fairing::AdHoc; use rocket::{error, fairing, info, Build, Rocket}; use rocket_db_pools::{sqlx, Database as RocketDatabase}; +use settings::Settings; #[derive(RocketDatabase)] #[database("ezidam")] @@ -25,10 +26,26 @@ impl Database { match run_migrations(&db.0).await { Ok(()) => { info!("Migrations ran successfully"); - Ok(rocket) } Err(e) => { error!("Failed to run migrations: {}", e); + return Err(rocket); + } + } + + // Initialize settings + match Settings::init(&db.0).await { + Ok(insertion) => { + if insertion.is_some() { + // This should happen only once in the lifetime of the database + info!("Created settings in database"); + } else { + info!("Found existing settings in database"); + } + Ok(rocket) + } + Err(e) => { + error!("Failed to interact with settings: {}", e); Err(rocket) } } diff --git a/crates/settings/Cargo.toml b/crates/settings/Cargo.toml new file mode 100644 index 0000000..55542f7 --- /dev/null +++ b/crates/settings/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "settings" +version = "0.0.0" +edition = "2021" + +[dependencies] +database = { path = "../database" } +thiserror = { workspace = true } +chrono = { workspace = true } \ No newline at end of file diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs new file mode 100644 index 0000000..ef95367 --- /dev/null +++ b/crates/settings/src/lib.rs @@ -0,0 +1,74 @@ +use chrono::{DateTime, Utc}; +use database::sqlx::SqliteExecutor; +use database::Settings as DatabaseSettings; + +// error +#[derive(thiserror::Error)] +// the rest +#[derive(Debug)] +pub enum Error { + #[error("Database: {0}")] + Database(#[from] database::Error), +} + +// the rest +#[derive(Debug)] +pub struct Settings { + created_at: DateTime, + updated_at: DateTime, + business_name: String, + business_logo: Vec, +} + +const DEFAULT_BUSINESS_NAME: &str = "ezidam"; +const DEFAULT_BUSINESS_LOGO: &[u8] = include_bytes!("../../../logo/ezidam.png"); + +impl From for Settings { + fn from(db: DatabaseSettings) -> Self { + Self { + created_at: db.created_at, + updated_at: db.updated_at, + business_name: db + .business_name + .unwrap_or_else(|| DEFAULT_BUSINESS_NAME.into()), + business_logo: db + .business_logo + .unwrap_or_else(|| DEFAULT_BUSINESS_LOGO.to_vec()), + } + } +} + +impl Settings { + pub fn business_logo(&self) -> &[u8] { + self.business_logo.as_slice() + } +} + +impl Settings { + pub async fn init(conn: impl SqliteExecutor<'_>) -> Result, Error> { + Ok(DatabaseSettings::init(conn).await?) + } + + pub async fn get(conn: impl SqliteExecutor<'_>) -> Result { + Ok(DatabaseSettings::get(conn).await.map(Self::from)?) + } + + pub async fn set_business_name( + conn: impl SqliteExecutor<'_>, + business_name: &str, + ) -> Result<(), Error> { + DatabaseSettings::set_business_name(conn, Some(business_name)).await?; + + Ok(()) + } + + /// **Warning**: No checks are performed, make sure the bytes are safe! + pub async fn set_business_logo( + conn: impl SqliteExecutor<'_>, + business_logo: &[u8], + ) -> Result<(), Error> { + DatabaseSettings::set_business_logo(conn, Some(business_logo)).await?; + + Ok(()) + } +} diff --git a/logo/ezidam.png b/logo/ezidam.png new file mode 100644 index 0000000000000000000000000000000000000000..6f949074445636bc4ab799fe700b6a6b23d18481 GIT binary patch literal 5245 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