From 2bb09cbe54bd30515edc425b548cb51717128ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net> Date: Fri, 14 Mar 2025 00:43:34 +0800 Subject: [PATCH] feat(card_db): Switch to fully-fledged diesel-based sqlite db --- .rustfmt.toml | 1 + Cargo.lock | 266 ++++++++++++++++-- Cargo.toml | 9 +- diesel.toml | 9 + flake.nix | 2 + .../2025-03-13-161839_create_cards/down.sql | 1 + .../2025-03-13-161839_create_cards/up.sql | 7 + src/components/card.rs | 2 +- src/database.rs | 2 + src/database/models.rs | 38 +++ src/database/schema.rs | 9 + src/lib.rs | 1 + src/main.rs | 4 +- src/utils/card_database.rs | 158 +++-------- 14 files changed, 361 insertions(+), 148 deletions(-) create mode 100644 .rustfmt.toml create mode 100644 diesel.toml create mode 100644 migrations/2025-03-13-161839_create_cards/down.sql create mode 100644 migrations/2025-03-13-161839_create_cards/up.sql create mode 100644 src/database.rs create mode 100644 src/database/models.rs create mode 100644 src/database/schema.rs diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..f216078 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +edition = "2024" diff --git a/Cargo.lock b/Cargo.lock index f850824..4a701ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,6 +242,41 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "dashmap" version = "6.1.0" @@ -267,6 +302,15 @@ dependencies = [ "syn", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derive-where" version = "1.2.7" @@ -278,6 +322,60 @@ dependencies = [ "syn", ] +[[package]] +name = "diesel" +version = "2.2.4" +source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361" +dependencies = [ + "diesel_derives", + "downcast-rs", + "libsqlite3-sys", + "sqlite-wasm-rs", + "time", +] + +[[package]] +name = "diesel-derive-enum" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81c5131a2895ef64741dad1d483f358c2a229a3a2d1b256778cdc5e146db64d4" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "diesel_derives" +version = "2.2.0" +source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361" +dependencies = [ + "diesel_table_macro_syntax", + "dsl_auto_type", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "diesel_migrations" +version = "2.2.0" +source = "git+https://github.com/diesel-rs/diesel.git#64b3783f5e26349ddfbf309fea9ab35c47fc7aa4" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.2.0" +source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361" +dependencies = [ + "syn", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -289,20 +387,31 @@ dependencies = [ "syn", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "draft-manager" version = "0.1.0" dependencies = [ "console_error_panic_hook", "dedent", + "diesel", + "diesel-derive-enum", + "diesel_migrations", "futures", - "idb", "leptos", "serde", "serde-wasm-bindgen", "serde_json", + "sqlite-wasm-rs", "thiserror 2.0.12", "url", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] @@ -311,6 +420,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" +[[package]] +name = "dsl_auto_type" +version = "0.1.0" +source = "git+https://github.com/diesel-rs/diesel.git#04e0503656e79bb8edcc5780ee3b7f36f0753361" +dependencies = [ + "darling", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dyn-clone" version = "1.0.19" @@ -375,6 +497,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fragile" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" + [[package]] name = "futures" version = "0.3.31" @@ -548,6 +676,18 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -707,18 +847,10 @@ dependencies = [ ] [[package]] -name = "idb" -version = "0.6.4" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afe8830d5802f769dc0be20a87f9f116798c896650cb6266eb5c19a3c109eed" -dependencies = [ - "js-sys", - "num-traits", - "thiserror 1.0.69", - "tokio", - "wasm-bindgen", - "web-sys", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" @@ -912,6 +1044,16 @@ version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +[[package]] +name = "libsqlite3-sys" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "linear-map" version = "1.2.0" @@ -969,6 +1111,25 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "migrations_internals" +version = "2.2.0" +source = "git+https://github.com/diesel-rs/diesel.git#64b3783f5e26349ddfbf309fea9ab35c47fc7aa4" +dependencies = [ + "serde", + "toml", +] + +[[package]] +name = "migrations_macros" +version = "2.2.0" +source = "git+https://github.com/diesel-rs/diesel.git#64b3783f5e26349ddfbf309fea9ab35c47fc7aa4" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1001,13 +1162,10 @@ dependencies = [ ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num_cpus" @@ -1129,6 +1287,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "prettyplease" version = "0.2.30" @@ -1516,12 +1686,35 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +[[package]] +name = "sqlite-wasm-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84473e8335ed2f167c6f8040970d976990fb66aa62292ae58735de6d61ecfb73" +dependencies = [ + "fragile", + "js-sys", + "once_cell", + "parking_lot", + "thiserror 2.0.12", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.99" @@ -1639,6 +1832,37 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "time" +version = "0.3.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" + +[[package]] +name = "time-macros" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -1769,6 +1993,12 @@ dependencies = [ "getrandom 0.3.1", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index fa8b96e..333117c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,17 @@ edition = "2021" console_error_panic_hook = "0.1.7" dedent = "0.1.1" futures = "0.3.31" -idb = "0.6.4" leptos = { version = "0.7.7", features = ["csr"] } +diesel = { git = "https://github.com/diesel-rs/diesel.git", features = ["sqlite"] } serde = { version = "1.0.219", features = ["derive"] } serde-wasm-bindgen = "0.6.5" serde_json = "1.0.140" thiserror = "2.0.12" url = "2.5.4" +wasm-bindgen = "0.2.100" +wasm-bindgen-futures = "0.4.50" +diesel-derive-enum = { version = "2.1.0", features = ["sqlite"] } +diesel_migrations = { git = "https://github.com/diesel-rs/diesel.git", features = ["sqlite"] } + +[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies] +sqlite-wasm-rs = { version = ">=0.3.0, <0.4.0" , default-features = false, features = ["precompiled"]} diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..ba651ac --- /dev/null +++ b/diesel.toml @@ -0,0 +1,9 @@ +# For documentation on how to configure this file, +# see https://diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" +custom_type_derives = ["diesel::query_builder::QueryId", "Clone"] + +[migrations_directory] +dir = "/home/tlater/Documents/Projects/draft-manager/migrations" diff --git a/flake.nix b/flake.nix index 4389845..dc2446d 100644 --- a/flake.nix +++ b/flake.nix @@ -26,6 +26,8 @@ packages = with pkgs; [ cargo clippy + diesel-cli + emscripten rustc rustfmt leptosfmt diff --git a/migrations/2025-03-13-161839_create_cards/down.sql b/migrations/2025-03-13-161839_create_cards/down.sql new file mode 100644 index 0000000..d9a93fe --- /dev/null +++ b/migrations/2025-03-13-161839_create_cards/down.sql @@ -0,0 +1 @@ +-- This file should undo anything in `up.sql` diff --git a/migrations/2025-03-13-161839_create_cards/up.sql b/migrations/2025-03-13-161839_create_cards/up.sql new file mode 100644 index 0000000..32fc4a6 --- /dev/null +++ b/migrations/2025-03-13-161839_create_cards/up.sql @@ -0,0 +1,7 @@ +CREATE TABLE cards ( + password PRIMARY KEY, + name VARCHAR NOT NULL, + description TEXT NOT NULL, + frame TEXT CHECK(frame IN ('normal', 'effect', 'ritual', 'fusion', 'synchro', 'xyz', 'link', 'normal_pendulum', 'effect_pendulum', 'ritual_pendulum', 'fusion_pendulum', 'synchro_pendulum', 'xyz_pendulum', 'spell', 'trap', 'token')) NOT NULL, + image TEXT +) diff --git a/src/components/card.rs b/src/components/card.rs index 929ec38..29fd136 100644 --- a/src/components/card.rs +++ b/src/components/card.rs @@ -1,6 +1,6 @@ use leptos::prelude::*; -use crate::utils::card_database::CardDetails; +use crate::database::models::CardDetails; #[component] pub fn Card(details: Option<CardDetails>) -> impl IntoView { diff --git a/src/database.rs b/src/database.rs new file mode 100644 index 0000000..d5cbad7 --- /dev/null +++ b/src/database.rs @@ -0,0 +1,2 @@ +pub mod models; +pub mod schema; diff --git a/src/database/models.rs b/src/database/models.rs new file mode 100644 index 0000000..f98978a --- /dev/null +++ b/src/database/models.rs @@ -0,0 +1,38 @@ +use diesel::prelude::*; +use serde::{Deserialize, Serialize}; + +use crate::database::schema::cards; + +#[derive(Clone, Debug, Serialize, Deserialize, Insertable, Selectable, Queryable)] +#[diesel(table_name = cards)] +#[diesel(check_for_backend(diesel::sqlite::Sqlite))] +pub struct CardDetails { + pub password: i32, + + pub name: String, + pub description: String, + + pub frame: FrameType, + pub image: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, diesel_derive_enum::DbEnum)] +#[serde(rename_all = "snake_case")] +pub enum FrameType { + Normal, + Effect, + Ritual, + Fusion, + Synchro, + Xyz, + Link, + NormalPendulum, + EffectPendulum, + RitualPendulum, + FusionPendulum, + SynchroPendulum, + XyzPendulum, + Spell, + Trap, + Token, +} diff --git a/src/database/schema.rs b/src/database/schema.rs new file mode 100644 index 0000000..6d77694 --- /dev/null +++ b/src/database/schema.rs @@ -0,0 +1,9 @@ +diesel::table! { + cards (password) { + password -> Integer, + name -> VarChar, + description -> Text, + frame -> crate::database::models::FrameTypeMapping, + image -> Text, + } +} diff --git a/src/lib.rs b/src/lib.rs index 17388d8..4d022bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ pub mod components; pub mod draft_list; pub mod utils; +pub mod database; diff --git a/src/main.rs b/src/main.rs index 9e3bc2f..da91295 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,8 +10,8 @@ fn main() { #[component] fn App() -> impl IntoView { let card = LocalResource::new(|| async move { - let database = CardDatabase::open().await?; - database.load_data().await?; + let mut database = CardDatabase::open()?; + database.load_data()?; database.get_card(1861629).await }); diff --git a/src/utils/card_database.rs b/src/utils/card_database.rs index 96998eb..b18dbe8 100644 --- a/src/utils/card_database.rs +++ b/src/utils/card_database.rs @@ -1,145 +1,51 @@ -use std::{cell::RefCell, rc::Rc}; - -use idb::{ - event::VersionChangeEvent, Database, DatabaseEvent, Factory, KeyPath, ObjectStoreParams, Query, - TransactionMode, -}; - -use serde::{Deserialize, Serialize}; -use serde_wasm_bindgen::Serializer; +use crate::database::{self, models::FrameType, schema::cards}; +use database::models::CardDetails; +use diesel::prelude::*; +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use thiserror::Error; -#[derive(Clone, Deserialize)] -#[serde(rename_all = "snake_case")] -pub enum FrameType { - Normal, - Effect, - Ritual, - Fusion, - Synchro, - Xyz, - Link, - NormalPendulum, - EffectPendulum, - RitualPendulum, - FusionPendulum, - SynchroPendulum, - XyzPendulum, - Spell, - Trap, - Token, -} +const DB_URL: &str = "cards.db"; +const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations"); -#[derive(Clone, Deserialize)] -pub struct CardDetails { - pub password: u32, - - pub name: String, - pub description: String, - - pub frame: FrameType, - pub image: String, -} - -pub struct CardDatabase(Database); - -const DB_VERSION: u32 = 1; +pub struct CardDatabase(SqliteConnection); impl CardDatabase { - pub async fn open() -> Result<Self> { - let factory = Factory::new()?; - let mut open_request = factory.open("cards", Some(DB_VERSION))?; - - let err = Rc::new(RefCell::new(Ok(()))); - let moved_err = err.clone(); // Will be moved inside closure - open_request.on_upgrade_needed(move |event| { - let res = Self::upgrade_database(event); - - if let Err(e) = res { - *std::cell::RefCell::<_>::borrow_mut(&moved_err) = Err(e); - drop(moved_err); - } - }); - - let database = open_request.await?; - // Get the error if there is one - note that if the Rc has a - // strong count > 1 and therefore Symbol’s value as variable is void: into_inner returns Symbol’s value as variable is void: None, - // this means that the callback was not called, and as such - // there cannot have been an error. - let res = Rc::into_inner(err).unwrap_or(Ok(()).into()).into_inner(); - - res.map(|_| Self(database)) + pub fn open() -> Result<Self> { + let mut connection = SqliteConnection::establish(DB_URL)?; + connection.run_pending_migrations(MIGRATIONS).unwrap(); + Ok(Self(connection)) } - pub async fn get_card(&self, key: u32) -> Result<Option<CardDetails>> { - let transaction = self.0.transaction(&["cards"], TransactionMode::ReadOnly)?; - let store = transaction.object_store("cards")?; - let card = store.get(Query::Key(key.into()))?.await?; - Ok(card.map(serde_wasm_bindgen::from_value).transpose()?) + pub async fn get_card(&mut self, password: i32) -> Result<Option<CardDetails>> { + match cards::dsl::cards.find(password).first(&mut self.0) { + Ok(details) => Ok(Some(details)), + Err(diesel::result::Error::NotFound) => Ok(None), + Err(other) => Err(other.into()), + } } - pub async fn load_data(&self) -> Result<()> { - let transaction = self.0.transaction(&["cards"], TransactionMode::ReadWrite)?; - let store = transaction.object_store("cards")?; - - // Add some test data for now - let decode_talker = serde_json::json!({ - "password": 1861629, - "name": "Decode Talker", - "description": "2+ Effect Monsters\r\nGains 500 ATK for each monster it points to. When your opponent activates a card or effect that targets a card(s) you control (Quick Effect): You can Tribute 1 monster this card points to; negate the activation, and if you do, destroy that card.", - "frame": "link", - "image": "https://images.ygoprodeck.com/images/cards/1861629.jpg" - }); - - store - .put( - &decode_talker.serialize(&Serializer::json_compatible())?, - None, - )? - .await?; - - transaction.commit()?.await?; - - Ok(()) - } - - /// Upgrade the database; this is called by the browser whenever - /// we try to open a newer database version. - fn upgrade_database(event: VersionChangeEvent) -> Result<()> { - let database = event.database()?; - - let upgrade_from = event.old_version()?; - match upgrade_from { - // This version number signals that the database - // hasn't been created before. - 0 => { - let mut store_params = ObjectStoreParams::new(); - store_params.key_path(Some(KeyPath::new_single("password"))); - - let store = database.create_object_store("cards", store_params)?; - - store.create_index( - "fulltext", - KeyPath::new_array(vec!["password", "name", "description"]), - None, - )?; - } - other => return Err(CardDatabaseError::UnknownDatabaseVersion(other)), + pub fn load_data(&mut self) -> Result<()> { + let decode_talker = CardDetails { + password: 1861629, + name: "Decode Talker".to_owned(), + description: "2+ Effect Monsters\r\nGains 500 ATK for each monster it points to. When your opponent activates a card or effect that targets a card(s) you control (Quick Effect): You can Tribute 1 monster this card points to; negate the activation, and if you do, destroy that card.".to_owned(), + frame: FrameType::Link, + image: "https://images.ygoprodeck.com/images/cards/1861629.jpg".to_owned() }; + diesel::insert_into(cards::table) + .values(decode_talker) + .execute(&mut self.0)?; + Ok(()) } } #[derive(Debug, Error)] pub enum CardDatabaseError { - #[error( - "unknown card database version `{0}`, please close the tab and re-open the application" - )] - UnknownDatabaseVersion(u32), - #[error("card database operation failed; does the browser support IndexedDB?")] - BrowserError(#[from] idb::Error), - #[error("invalid test data")] - SerdeError(#[from] serde_wasm_bindgen::Error), + #[error("failed to connect to database")] + DieselConnectionError(#[from] diesel::ConnectionError), + #[error("failed to query database")] + DieselQueryError(#[from] diesel::result::Error), } type Result<T> = std::result::Result<T, CardDatabaseError>;