diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index fc644ba..9187e4a 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -48,8 +48,6 @@ impl Api { let dispatch = ApiDispatch { tx }; tokio::task::spawn(async move { - let mut api = api; - loop { tokio::select! { cmd = rx.recv().fuse() => { @@ -76,7 +74,7 @@ impl Api { } #[instrument(level = "debug", skip(self), ret(Debug))] - async fn execute(&mut self, command: ApiCommand) -> Result { + async fn execute(&self, command: ApiCommand) -> Result { let (tx, rx) = oneshot::channel(); self.store.send((command, tx)).await?; let res = rx.await??; diff --git a/crates/persistence/src/json/mod.rs b/crates/persistence/src/json/mod.rs index a6fdd9e..c83a840 100644 --- a/crates/persistence/src/json/mod.rs +++ b/crates/persistence/src/json/mod.rs @@ -66,7 +66,7 @@ impl JsonStore { } impl Storage for JsonStore { - async fn add_item(&mut self, item: &Name) -> Result { + async fn add_item(&self, item: &Name) -> Result { let mut groceries = Items::from_json(&self.items)?; if groceries @@ -82,51 +82,51 @@ impl Storage for JsonStore { } } - async fn add_checklist_item(&mut self, _item: &Name) -> Result { + async fn add_checklist_item(&self, _item: &Name) -> Result { todo!() } - async fn add_list_item(&mut self, _item: &Name) -> Result { + async fn add_list_item(&self, _item: &Name) -> Result { todo!() } - async fn add_list_recipe(&mut self, _recipe: &Recipe) -> Result { + async fn add_list_recipe(&self, _recipe: &Recipe) -> Result { todo!() } async fn add_recipe( - &mut self, + &self, _recipe: &Recipe, _ingredients: &Ingredients, ) -> Result { todo!() } - async fn checklist(&mut self) -> Result { + async fn checklist(&self) -> Result { todo!() } - async fn delete_checklist_item(&mut self, _item: &Name) -> Result { + async fn delete_checklist_item(&self, _item: &Name) -> Result { todo!() } - async fn delete_recipe(&mut self, _recipe: &Recipe) -> Result { + async fn delete_recipe(&self, _recipe: &Recipe) -> Result { todo!() } - async fn items(&mut self) -> Result { + async fn items(&self) -> Result { Ok(StoreResponse::Items(Items::from_json(&self.items)?)) } - async fn list(&mut self) -> Result { + async fn list(&self) -> Result { Ok(StoreResponse::List(List::from_json(&self.list)?)) } - async fn refresh_list(&mut self) -> Result { + async fn refresh_list(&self) -> Result { todo!() } - async fn recipe_ingredients(&mut self, recipe: &Recipe) -> Result { + async fn recipe_ingredients(&self, recipe: &Recipe) -> Result { let items = Items::from_json(&self.items)?; let ingredients: Ingredients = items .recipe_ingredients(&recipe.to_string())? @@ -136,11 +136,11 @@ impl Storage for JsonStore { Ok(StoreResponse::RecipeIngredients(Some(ingredients))) } - async fn sections(&mut self) -> Result { + async fn sections(&self) -> Result { todo!() } - async fn recipes(&mut self) -> Result { + async fn recipes(&self) -> Result { let mut recipes: HashSet = HashSet::new(); { @@ -312,7 +312,7 @@ pub mod test { async fn items() -> Items { let file = test_json_file().unwrap(); - let mut store = JsonStore::new().with_items_path(file.path()); + let store = JsonStore::new().with_items_path(file.path()); let StoreResponse::Items(items) = store.items().await.unwrap() else { todo!() }; @@ -334,7 +334,7 @@ pub mod test { #[tokio::test] async fn test_save_items() -> Result<(), Box> { - let mut store = JsonStore::new().with_items_path(&PathBuf::from("test_groceries.json")); + let store = JsonStore::new().with_items_path(&PathBuf::from("test_groceries.json")); let items = Items::default(); insta::assert_json_snapshot!(items, @r#" { @@ -888,7 +888,7 @@ pub mod test { #[tokio::test] async fn test_delete_item_from_list() -> Result<(), Box> { let file = create_test_checklist_json_file().unwrap(); - let mut store = JsonStore::new().with_list_path(file.path()); + let store = JsonStore::new().with_list_path(file.path()); let StoreResponse::List(mut shopping_list) = store.list().await.unwrap() else { todo!() @@ -1119,7 +1119,7 @@ pub mod test { async fn checklist() -> List { let file = create_test_checklist_json_file().unwrap(); - let mut store = JsonStore::new().with_list_path(file.path()); + let store = JsonStore::new().with_list_path(file.path()); let StoreResponse::List(list) = store.list().await.unwrap() else { todo!() }; diff --git a/crates/persistence/src/sqlite/mod.rs b/crates/persistence/src/sqlite/mod.rs index 18d910e..6386ccc 100644 --- a/crates/persistence/src/sqlite/mod.rs +++ b/crates/persistence/src/sqlite/mod.rs @@ -102,24 +102,24 @@ pub struct SqliteStore { impl SqliteStore { pub async fn new(db_uri: DbUri) -> Result { let pool = DatabaseConnector::new(db_uri).try_connect().await?; - let mut store = Self { pool }; + let store = Self { pool }; store.run_migrations()?; Ok(store) } - pub(crate) fn run_migrations(&mut self) -> Result<(), StoreError> { + pub(crate) fn run_migrations(&self) -> Result<(), StoreError> { let mut connection = self.connection()?; connection.immediate_transaction(run_migrations) } pub(crate) fn connection( - &mut self, + &self, ) -> Result>, r2d2::Error> { self.pool.get() } fn get_or_insert_item( - &mut self, + &self, connection: &mut SqliteConnection, name: &str, ) -> Result { @@ -136,7 +136,7 @@ impl SqliteStore { } fn get_or_insert_recipe( - &mut self, + &self, connection: &mut SqliteConnection, name: &str, ) -> Result { @@ -153,7 +153,7 @@ impl SqliteStore { } fn insert_item_recipe( - &mut self, + &self, connection: &mut SqliteConnection, item_id: i32, recipe_id: i32, @@ -165,8 +165,8 @@ impl SqliteStore { Ok(()) } - async fn list_items(&mut self) -> Result { - let mut store = self.clone(); + async fn list_items(&self) -> Result { + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -186,8 +186,8 @@ impl SqliteStore { .await? } - async fn list_recipes(&mut self) -> Result, StoreError> { - let mut store = self.clone(); + async fn list_recipes(&self) -> Result, StoreError> { + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -207,7 +207,7 @@ impl SqliteStore { } fn load_item( - &mut self, + &self, connection: &mut SqliteConnection, item_id: i32, ) -> Result, StoreError> { @@ -217,7 +217,7 @@ impl SqliteStore { } fn get_recipe( - &mut self, + &self, connection: &mut SqliteConnection, recipe: &str, ) -> Result>, StoreError> { @@ -229,8 +229,8 @@ impl SqliteStore { } impl Storage for SqliteStore { - async fn add_checklist_item(&mut self, item: &Name) -> Result { - let mut store = self.clone(); + async fn add_checklist_item(&self, item: &Name) -> Result { + let store = self.clone(); let item = item.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; @@ -248,8 +248,8 @@ impl Storage for SqliteStore { .await? } - async fn add_item(&mut self, item: &Name) -> Result { - let mut store = self.clone(); + async fn add_item(&self, item: &Name) -> Result { + let store = self.clone(); let item = item.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; @@ -262,8 +262,8 @@ impl Storage for SqliteStore { .await? } - async fn add_list_item(&mut self, item: &Name) -> Result { - let mut store = self.clone(); + async fn add_list_item(&self, item: &Name) -> Result { + let store = self.clone(); let item = item.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; @@ -279,7 +279,7 @@ impl Storage for SqliteStore { .await? } - async fn add_list_recipe(&mut self, recipe: &Recipe) -> Result { + async fn add_list_recipe(&self, recipe: &Recipe) -> Result { let StoreResponse::RecipeIngredients(Some(ingredients)) = self.recipe_ingredients(recipe).await? else { @@ -287,7 +287,7 @@ impl Storage for SqliteStore { return Err(StoreError::RecipeIngredients(recipe.to_string())); }; - let mut store = self.clone(); + let store = self.clone(); let recipe = recipe.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; @@ -320,11 +320,11 @@ impl Storage for SqliteStore { } async fn add_recipe( - &mut self, + &self, recipe: &Recipe, ingredients: &Ingredients, ) -> Result { - let mut store = self.clone(); + let store = self.clone(); let recipe = recipe.clone(); let ingredients = ingredients.clone(); tokio::task::spawn_blocking(move || { @@ -346,8 +346,8 @@ impl Storage for SqliteStore { .await? } - async fn checklist(&mut self) -> Result { - let mut store = self.clone(); + async fn checklist(&self) -> Result { + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -368,7 +368,7 @@ impl Storage for SqliteStore { .await? } - async fn list(&mut self) -> Result { + async fn list(&self) -> Result { let StoreResponse::List(mut list) = self.list_items().await? else { todo!() }; @@ -380,8 +380,8 @@ impl Storage for SqliteStore { Ok(StoreResponse::List(list)) } - async fn delete_checklist_item(&mut self, item: &Name) -> Result { - let mut store = self.clone(); + async fn delete_checklist_item(&self, item: &Name) -> Result { + let store = self.clone(); let item = item.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; @@ -402,8 +402,8 @@ impl Storage for SqliteStore { .await? } - async fn delete_recipe(&mut self, recipe: &Recipe) -> Result { - let mut store = self.clone(); + async fn delete_recipe(&self, recipe: &Recipe) -> Result { + let store = self.clone(); let recipe = recipe.clone(); let StoreResponse::RecipeIngredients(ingredients) = self.recipe_ingredients(&recipe).await? @@ -440,10 +440,10 @@ impl Storage for SqliteStore { .await? } - async fn items(&mut self) -> Result { + async fn items(&self) -> Result { use schema::items::dsl::items; - let mut store = self.clone(); + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -459,8 +459,8 @@ impl Storage for SqliteStore { .await? } - async fn refresh_list(&mut self) -> Result { - let mut store = self.clone(); + async fn refresh_list(&self) -> Result { + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -471,8 +471,8 @@ impl Storage for SqliteStore { .await? } - async fn recipe_ingredients(&mut self, recipe: &Recipe) -> Result { - let mut store = self.clone(); + async fn recipe_ingredients(&self, recipe: &Recipe) -> Result { + let store = self.clone(); let recipe = recipe.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; @@ -510,9 +510,9 @@ impl Storage for SqliteStore { .await? } - async fn sections(&mut self) -> Result { + async fn sections(&self) -> Result { use schema::sections::dsl::sections; - let mut store = self.clone(); + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -528,9 +528,9 @@ impl Storage for SqliteStore { .await? } - async fn recipes(&mut self) -> Result { + async fn recipes(&self) -> Result { use schema::recipes::dsl::recipes; - let mut store = self.clone(); + let store = self.clone(); tokio::task::spawn_blocking(move || { let mut connection = store.connection()?; connection.immediate_transaction(|connection| { @@ -555,7 +555,7 @@ mod tests { async fn inmem_sqlite_store() -> SqliteStore { // Set up a connection to an in-memory SQLite database for testing let store = SqliteStore::new(DbUri::inmem()).await.unwrap(); - let mut migrations_store = store.clone(); + let migrations_store = store.clone(); tokio::task::spawn_blocking(move || { let mut connection = migrations_store.connection().unwrap(); connection.immediate_transaction(run_migrations).unwrap(); @@ -571,7 +571,7 @@ mod tests { #[tokio::test] async fn test_add_checklist_item() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let item_name = test_item(); store.add_checklist_item(&item_name).await.unwrap(); @@ -585,7 +585,7 @@ mod tests { #[tokio::test] async fn test_add_item() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let item_name = test_item(); store.add_item(&item_name).await.unwrap(); @@ -602,7 +602,7 @@ mod tests { #[tokio::test] async fn test_add_list_item() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let item_name = test_item(); store.add_list_item(&item_name).await.unwrap(); @@ -618,7 +618,7 @@ mod tests { #[tokio::test] async fn test_add_list_recipe() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let ingredients = Ingredients::from_iter(vec![Name::from("ingredient 1"), Name::from("ingredient 2")]); @@ -661,7 +661,7 @@ mod tests { #[tokio::test] async fn test_add_recipe() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let ingredients = Ingredients::from_iter(vec![Name::from("ingredient 1"), Name::from("ingredient 2")]); @@ -687,7 +687,7 @@ mod tests { #[tokio::test] async fn test_delete_checklist_item() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let item_name = test_item(); store.add_checklist_item(&item_name).await.unwrap(); @@ -709,7 +709,7 @@ mod tests { #[tokio::test] async fn test_delete_recipe() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; let ingredients = Ingredients::from_iter(vec![Name::from("ingredient 1"), Name::from("ingredient 2")]); @@ -749,7 +749,7 @@ mod tests { #[tokio::test] async fn test_refresh_list() { - let mut store = inmem_sqlite_store().await; + let store = inmem_sqlite_store().await; store.refresh_list().await.unwrap(); diff --git a/crates/persistence/src/store.rs b/crates/persistence/src/store.rs index e0f6536..c651e0f 100644 --- a/crates/persistence/src/store.rs +++ b/crates/persistence/src/store.rs @@ -107,13 +107,13 @@ impl Store { } } - pub async fn init(&mut self) -> Result { + pub async fn init(&self) -> Result { let (tx, mut rx) = mpsc::channel::<( ApiCommand, oneshot::Sender>, )>(10); - let mut store = self.clone(); + let store = self.clone(); tokio::task::spawn(async move { loop { @@ -141,7 +141,7 @@ impl Store { } async fn execute_transaction( - &mut self, + &self, command: ApiCommand, ) -> Result { match self { @@ -205,7 +205,7 @@ pub enum StoreResponse { pub(crate) trait Storage: Send + Sync + 'static { async fn execute_transaction( - &mut self, + &self, command: ApiCommand, ) -> Result { match command { @@ -218,7 +218,7 @@ pub(crate) trait Storage: Send + Sync + 'static { } } - async fn add(&mut self, cmd: Add) -> Result { + async fn add(&self, cmd: Add) -> Result { match cmd { Add::ChecklistItem(name) => self.add_checklist_item(&name).await, Add::Item { name, .. } => self.add_item(&name).await, @@ -231,7 +231,7 @@ pub(crate) trait Storage: Send + Sync + 'static { } } - async fn read(&mut self, cmd: Read) -> Result { + async fn read(&self, cmd: Read) -> Result { match cmd { Read::All => self.items().await, Read::Checklist => self.checklist().await, @@ -244,7 +244,7 @@ pub(crate) trait Storage: Send + Sync + 'static { } } - async fn update(&mut self, cmd: Update) -> Result { + async fn update(&self, cmd: Update) -> Result { match cmd { Update::Item(_name) => todo!(), Update::RefreshList => self.refresh_list().await, @@ -252,7 +252,7 @@ pub(crate) trait Storage: Send + Sync + 'static { } } - async fn delete(&mut self, cmd: Delete) -> Result { + async fn delete(&self, cmd: Delete) -> Result { match cmd { Delete::ChecklistItem(name) => self.delete_checklist_item(&name).await, Delete::ClearChecklist => todo!(), @@ -263,7 +263,7 @@ pub(crate) trait Storage: Send + Sync + 'static { } } - async fn fetch_recipe(&mut self, url: Url) -> Result { + async fn fetch_recipe(&self, url: Url) -> Result { let fetcher = Fetcher::from(url); let (recipe, ingredients) = fetcher.fetch_recipe().await?; @@ -271,8 +271,8 @@ pub(crate) trait Storage: Send + Sync + 'static { Ok(StoreResponse::FetchedRecipe((recipe, ingredients))) } - async fn migrate_json_store_to_sqlite(&mut self) -> Result { - let mut sqlite_store = SqliteStore::new(DbUri::new()).await?; + async fn migrate_json_store_to_sqlite(&self) -> Result { + let sqlite_store = SqliteStore::new(DbUri::new()).await?; let mut connection = sqlite_store.connection()?; let StoreResponse::Items(grocery_items) = self.items().await? else { todo!() @@ -292,38 +292,38 @@ pub(crate) trait Storage: Send + Sync + 'static { } // Create - async fn add_item(&mut self, item: &Name) -> Result; + async fn add_item(&self, item: &Name) -> Result; - async fn add_checklist_item(&mut self, item: &Name) -> Result; + async fn add_checklist_item(&self, item: &Name) -> Result; - async fn add_list_item(&mut self, item: &Name) -> Result; + async fn add_list_item(&self, item: &Name) -> Result; - async fn add_list_recipe(&mut self, recipe: &Recipe) -> Result; + async fn add_list_recipe(&self, recipe: &Recipe) -> Result; async fn add_recipe( - &mut self, + &self, recipe: &Recipe, ingredients: &Ingredients, ) -> Result; // Read - async fn checklist(&mut self) -> Result; + async fn checklist(&self) -> Result; - async fn list(&mut self) -> Result; + async fn list(&self) -> Result; - async fn items(&mut self) -> Result; + async fn items(&self) -> Result; - async fn recipes(&mut self) -> Result; + async fn recipes(&self) -> Result; - async fn recipe_ingredients(&mut self, recipe: &Recipe) -> Result; + async fn recipe_ingredients(&self, recipe: &Recipe) -> Result; - async fn sections(&mut self) -> Result; + async fn sections(&self) -> Result; // Update - async fn refresh_list(&mut self) -> Result; + async fn refresh_list(&self) -> Result; // Delete - async fn delete_checklist_item(&mut self, item: &Name) -> Result; + async fn delete_checklist_item(&self, item: &Name) -> Result; - async fn delete_recipe(&mut self, recipe: &Recipe) -> Result; + async fn delete_recipe(&self, recipe: &Recipe) -> Result; }