Skip to content

Commit ed168ee

Browse files
committed
Improve edit api
1 parent 7db47b3 commit ed168ee

File tree

4 files changed

+20
-21
lines changed

4 files changed

+20
-21
lines changed

rusqlite_migration/src/builder.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::iter::FromIterator;
1+
use std::{iter::FromIterator, mem::take};
22

33
use include_dir::Dir;
44

@@ -7,7 +7,7 @@ use crate::{loader::from_directory, MigrationHook, Result, M};
77
/// Allows to build a `Vec<M<'u>>` with additional edits.
88
#[derive(Default, Debug)]
99
pub struct MigrationsBuilder<'u> {
10-
migrations: Vec<M<'u>>,
10+
migrations: Vec<Option<M<'u>>>,
1111
}
1212

1313
impl<'u> MigrationsBuilder<'u> {
@@ -42,28 +42,25 @@ impl<'u> MigrationsBuilder<'u> {
4242
///
4343
/// Panics if no migration with the `id` provided exists.
4444
#[must_use]
45-
pub fn edit(mut self, id: usize, f: impl Fn(&mut M)) -> Self {
45+
pub fn edit(mut self, id: usize, f: impl Fn(M) -> M) -> Self {
4646
if id < 1 {
4747
panic!("id cannot be equal to 0");
4848
}
49-
f(self
50-
.migrations
51-
.get_mut(id - 1)
52-
.expect("No migration with the given index"));
49+
self.migrations[id - 1] = take(&mut self.migrations[id - 1]).map(f);
5350
self
5451
}
5552

5653
/// Finalizes the builder and creates either a [`crate::Migrations`] or a
5754
/// [`crate::AsyncMigrations`] instance.
5855
pub fn finalize<T: FromIterator<M<'u>>>(self) -> T {
59-
T::from_iter(self.migrations)
56+
T::from_iter(self.migrations.iter().flatten().cloned())
6057
}
6158
}
6259

6360
impl<'u> FromIterator<M<'u>> for MigrationsBuilder<'u> {
6461
fn from_iter<T: IntoIterator<Item = M<'u>>>(iter: T) -> Self {
6562
Self {
66-
migrations: Vec::from_iter(iter),
63+
migrations: Vec::from_iter(iter.into_iter().map(Some)),
6764
}
6865
}
6966
}
@@ -76,8 +73,9 @@ impl<'u> M<'u> {
7673
/// Use [`M::up_with_hook`] instead if you're creating a new migration.
7774
/// This method is meant for editing existing transactions
7875
/// when using the [`MigrationsBuilder`].
79-
pub fn set_up_hook(&mut self, hook: impl MigrationHook + 'static) {
76+
pub fn set_up_hook(mut self, hook: impl MigrationHook + 'static) -> Self {
8077
self.up_hook = Some(hook.clone_box());
78+
self
8179
}
8280

8381
/// Replace the `down_hook` in the given migration with the provided one.
@@ -87,7 +85,8 @@ impl<'u> M<'u> {
8785
/// Use [`M::down_with_hook`] instead if you're creating a new migration.
8886
/// This method is meant for editing existing transactions
8987
/// when using the [`MigrationsBuilder`].
90-
pub fn set_down_hook(&mut self, hook: impl MigrationHook + 'static) {
88+
pub fn set_down_hook(mut self, hook: impl MigrationHook + 'static) -> Self {
9189
self.down_hook = Some(hook.clone_box());
90+
self
9291
}
9392
}

rusqlite_migration/src/lib.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,12 @@ impl<'m> Migrations<'m> {
452452
/// or don't contain at least a valid `up.sql` file.
453453
#[cfg(feature = "from-directory")]
454454
pub fn from_directory(dir: &'static Dir<'static>) -> Result<Self> {
455-
Ok(Self {
456-
ms: from_directory(dir)?,
457-
})
455+
let migrations = from_directory(dir)?
456+
.into_iter()
457+
.collect::<Option<Vec<_>>>()
458+
.ok_or(Error::FileLoad("Could not load migrations".to_string()))?;
459+
460+
Ok(Self { ms: migrations })
458461
}
459462

460463
/// **Deprecated**: [`Migrations`] now implements [`FromIterator`], so use [`Migrations::from_iter`] instead.

rusqlite_migration/src/loader.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'u> From<&MigrationFile> for M<'u> {
9090
}
9191
}
9292

93-
pub(crate) fn from_directory(dir: &'static Dir<'static>) -> Result<Vec<M<'static>>> {
93+
pub(crate) fn from_directory(dir: &'static Dir<'static>) -> Result<Vec<Option<M<'static>>>> {
9494
let mut migrations: Vec<Option<M>> = vec![None; dir.dirs().count()];
9595

9696
for dir in dir.dirs() {
@@ -127,8 +127,5 @@ pub(crate) fn from_directory(dir: &'static Dir<'static>) -> Result<Vec<M<'static
127127
}
128128

129129
// The values are returned in the order of the keys, i.e. of IDs
130-
migrations
131-
.into_iter()
132-
.collect::<Option<Vec<_>>>()
133-
.ok_or(Error::FileLoad("Could not load migrations".to_string()))
130+
Ok(migrations)
134131
}

rusqlite_migration/src/tests/builder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ use crate::{MigrationsBuilder, M};
77
fn test_non_existing_index() {
88
let ms = vec![M::up("CREATE TABLE t(a);")];
99

10-
let _ = MigrationsBuilder::from_iter(ms.clone()).edit(100, move |_t| {});
10+
let _ = MigrationsBuilder::from_iter(ms.clone()).edit(100, move |t| t);
1111
}
1212

1313
#[test]
1414
#[should_panic]
1515
fn test_0_index() {
1616
let ms = vec![M::up("CREATE TABLE t(a);")];
1717

18-
let _ = MigrationsBuilder::from_iter(ms).edit(0, move |_t| {});
18+
let _ = MigrationsBuilder::from_iter(ms).edit(0, move |t| t);
1919
}

0 commit comments

Comments
 (0)