Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve edit api #91

Merged
merged 1 commit into from
Jun 18, 2023
Merged

Improve edit api #91

merged 1 commit into from
Jun 18, 2023

Conversation

czocher
Copy link
Collaborator

@czocher czocher commented Jun 17, 2023

This PR implements my take on #86. The edit api now takes ownership of the migration it edits.

Closes #86

@czocher czocher requested a review from cljoly as a code owner June 17, 2023 21:54
Copy link
Owner

@cljoly cljoly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this!

I would like to explore other options before we consider introducing take_mut (or similar crates) as a dependency though (reasoning in inline comments).

@cljoly
Copy link
Owner

cljoly commented Jun 18, 2023

I think we can do something like this:

diff --git a/rusqlite_migration/src/builder.rs b/rusqlite_migration/src/builder.rs
index 8ecfcf6..28ccef0 100644
--- a/rusqlite_migration/src/builder.rs
+++ b/rusqlite_migration/src/builder.rs
@@ -1,4 +1,4 @@
-use std::iter::FromIterator;
+use std::{iter::FromIterator, mem};
 
 use include_dir::Dir;
 
@@ -10,6 +10,9 @@ pub struct MigrationsBuilder<'u> {
     migrations: Vec<M<'u>>,
 }
 
+// Placeholder migration used to replace and edit
+const PLACEHOLDER_M: M<'static> = M::up("");
+
 impl<'u> MigrationsBuilder<'u> {
     /// Creates a set of migrations from a given directory by scanning subdirectories with a specified name pattern.
     /// The migrations are loaded and stored in the binary.
@@ -42,14 +45,19 @@ pub fn from_directory(dir: &'static Dir<'static>) -> Result<Self> {
     ///
     /// Panics if no migration with the `id` provided exists.
     #[must_use]
-    pub fn edit(mut self, id: usize, f: impl Fn(&mut M)) -> Self {
+    pub fn edit(mut self, id: usize, f: impl Fn(M)) -> Self {
         if id < 1 {
             panic!("id cannot be equal to 0");
         }
-        f(self
-            .migrations
-            .get_mut(id - 1)
-            .expect("No migration with the given index"));
+
+        let migration_to_edit = mem::replace(
+            self.migrations
+                .get_mut(id - 1)
+                .expect("No migration with the given index"),
+            PLACEHOLDER_M.clone(),
+        );
+
+        f(migration_to_edit);
         self
     }

What do you think @czocher ?

@czocher czocher force-pushed the improved-edit-api branch from 65a5b26 to 3cfd84b Compare June 18, 2023 13:06
@czocher
Copy link
Collaborator Author

czocher commented Jun 18, 2023

What do you think @czocher ?

We still need to copy the PLACEHOLDER which is not perfect. Maybe we can implement Default for M, which would return M("") and use https://doc.rust-lang.org/std/mem/fn.take.html? I'll implement it to show you how it would look like.

@czocher czocher force-pushed the improved-edit-api branch from 3cfd84b to fe427fc Compare June 18, 2023 13:13
@cljoly
Copy link
Owner

cljoly commented Jun 18, 2023

I see two issued with implementing Default:

  1. Users of the library will be tempted to use it and maybe that’s inadvisable
  2. I’m not sure that calling M::default is cheaper than cloning a constant made up of just pointers & other small values.

If we want to avoid the cloning, we could keep a Vec<Option> inside MigrationsBuilder and then use the take method of Option. Then we put f(M) back in place.

@cljoly cljoly mentioned this pull request Jun 18, 2023
@czocher
Copy link
Collaborator Author

czocher commented Jun 18, 2023

If we want to avoid the cloning, we could keep a Vec inside MigrationsBuilder and then use the take method of Option. Then we put f(M) back in place.

That's the best case in my opinion. I'll implement it and check how it'll look like.

@cljoly
Copy link
Owner

cljoly commented Jun 18, 2023

I'll implement it and check how it'll look like.

I suspect it’ll be easier if we merge #92 first. I’m happy to approve that other PR once we discuss the points raised there.

@czocher czocher force-pushed the improved-edit-api branch from fe427fc to ae2889c Compare June 18, 2023 13:50
@czocher
Copy link
Collaborator Author

czocher commented Jun 18, 2023

I'll implement it and check how it'll look like.

I suspect it’ll be easier if we merge #92 first. I’m happy to approve that other PR once we discuss the points raised there.

Let's do that first, yes.

@czocher czocher force-pushed the improved-edit-api branch from ae2889c to ed168ee Compare June 18, 2023 14:35
@czocher czocher force-pushed the improved-edit-api branch from ed168ee to b293d85 Compare June 18, 2023 14:44
@czocher czocher merged commit 90c601d into cljoly:master Jun 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider passing owned values to the edit API
2 participants