Create decks/reparent.rs

This commit is contained in:
RumovZ 2021-04-15 19:17:43 +02:00
parent 9c3671cf3f
commit 3f36db4f81
2 changed files with 61 additions and 54 deletions

View File

@ -5,6 +5,7 @@ mod counts;
mod current;
mod filtered;
mod name;
mod reparent;
mod schema11;
mod tree;
pub(crate) mod undo;
@ -32,7 +33,7 @@ use crate::{
pub(crate) use counts::DueCounts;
use name::normalize_native_name;
pub(crate) use name::{
human_deck_name_to_native, immediate_parent_name, native_deck_name_to_human, reparented_name,
human_deck_name_to_native, immediate_parent_name, native_deck_name_to_human,
};
pub use schema11::DeckSchema11;
use std::{borrow::Cow, sync::Arc};
@ -483,59 +484,6 @@ impl Collection {
deck.set_modified(usn);
self.update_single_deck_undoable(deck, original)
}
pub fn reparent_decks(
&mut self,
deck_ids: &[DeckId],
new_parent: Option<DeckId>,
) -> Result<OpOutput<usize>> {
self.transact(Op::ReparentDeck, |col| {
col.reparent_decks_inner(deck_ids, new_parent)
})
}
pub fn reparent_decks_inner(
&mut self,
deck_ids: &[DeckId],
new_parent: Option<DeckId>,
) -> Result<usize> {
let usn = self.usn()?;
let target_deck;
let mut target_name = None;
if let Some(target) = new_parent {
if let Some(target) = self.storage.get_deck(target)? {
if target.is_filtered() {
return Err(FilteredDeckError::MustBeLeafNode.into());
}
target_deck = target;
target_name = Some(target_deck.name.as_str());
}
}
let mut count = 0;
for deck in deck_ids {
if let Some(mut deck) = self.storage.get_deck(*deck)? {
if let Some(new_name) = reparented_name(&deck.name, target_name) {
count += 1;
let orig = deck.clone();
// this is basically update_deck_inner(), except:
// - we skip the normalization in prepare_for_update()
// - we skip the match_or_create_parents() step
// - we skip the final create_missing_parents(), as we don't allow parent->child
// renames
deck.set_modified(usn);
deck.name = new_name;
self.ensure_deck_name_unique(&mut deck, usn)?;
self.rename_child_decks(&orig, &deck.name, usn)?;
self.update_single_deck_undoable(&mut deck, orig)?;
}
}
}
Ok(count)
}
}
#[cfg(test)]

View File

@ -0,0 +1,59 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use super::name::reparented_name;
use crate::{error::FilteredDeckError, prelude::*};
impl Collection {
pub fn reparent_decks(
&mut self,
deck_ids: &[DeckId],
new_parent: Option<DeckId>,
) -> Result<OpOutput<usize>> {
self.transact(Op::ReparentDeck, |col| {
col.reparent_decks_inner(deck_ids, new_parent)
})
}
pub fn reparent_decks_inner(
&mut self,
deck_ids: &[DeckId],
new_parent: Option<DeckId>,
) -> Result<usize> {
let usn = self.usn()?;
let target_deck;
let mut target_name = None;
if let Some(target) = new_parent {
if let Some(target) = self.storage.get_deck(target)? {
if target.is_filtered() {
return Err(FilteredDeckError::MustBeLeafNode.into());
}
target_deck = target;
target_name = Some(target_deck.name.as_str());
}
}
let mut count = 0;
for deck in deck_ids {
if let Some(mut deck) = self.storage.get_deck(*deck)? {
if let Some(new_name) = reparented_name(&deck.name, target_name) {
count += 1;
let orig = deck.clone();
// this is basically update_deck_inner(), except:
// - we skip the normalization in prepare_for_update()
// - we skip the match_or_create_parents() step
// - we skip the final create_missing_parents(), as we don't allow parent->child
// renames
deck.set_modified(usn);
deck.name = new_name;
self.ensure_deck_name_unique(&mut deck, usn)?;
self.rename_child_decks(&orig, &deck.name, usn)?;
self.update_single_deck_undoable(&mut deck, orig)?;
}
}
}
Ok(count)
}
}