Maybe normalize name when preparing deck update

This commit is contained in:
RumovZ 2021-04-18 09:16:43 +02:00
parent 5e3e194289
commit fece39ca74
2 changed files with 33 additions and 1 deletions

View file

@ -7,6 +7,9 @@ impl Collection {
/// Rename deck if not unique. Bumps mtime and usn if /// Rename deck if not unique. Bumps mtime and usn if
/// name was changed, but otherwise leaves it the same. /// name was changed, but otherwise leaves it the same.
pub(super) fn prepare_deck_for_update(&mut self, deck: &mut Deck, usn: Usn) -> Result<()> { pub(super) fn prepare_deck_for_update(&mut self, deck: &mut Deck, usn: Usn) -> Result<()> {
if deck.name.maybe_normalize() {
deck.set_modified(usn);
}
self.ensure_deck_name_unique(deck, usn) self.ensure_deck_name_unique(deck, usn)
} }

View file

@ -40,6 +40,20 @@ impl NativeDeckName {
self.0.split('\x1f') self.0.split('\x1f')
} }
/// Normalize the name's components if necessary. True if mutation took place.
pub(crate) fn maybe_normalize(&mut self) -> bool {
let needs_normalization = self
.components()
.any(|comp| matches!(normalized_deck_name_component(comp), Cow::Owned(_)));
if needs_normalization {
self.0 = self
.components()
.map(normalized_deck_name_component)
.join("\x1f");
}
needs_normalization
}
/// Determine name to rename a deck to, when `self` is dropped on `target`. /// Determine name to rename a deck to, when `self` is dropped on `target`.
/// `target` being unset represents a drop at the top or bottom of the deck list. /// `target` being unset represents a drop at the top or bottom of the deck list.
/// The returned name should be used to replace `self`. /// The returned name should be used to replace `self`.
@ -193,11 +207,26 @@ mod test {
assert_eq!(native_name("foo"), "foo"); assert_eq!(native_name("foo"), "foo");
assert_eq!(native_name("foo::bar"), "foo\x1fbar"); assert_eq!(native_name("foo::bar"), "foo\x1fbar");
assert_eq!(native_name("foo::::baz"), "foo\x1fblank\x1fbaz"); assert_eq!(native_name("foo::::baz"), "foo\x1fblank\x1fbaz");
// normalize // implicitly normalize
assert_eq!(native_name("fo\x1fo::ba\nr"), "foo\x1fbar"); assert_eq!(native_name("fo\x1fo::ba\nr"), "foo\x1fbar");
assert_eq!(native_name("fo\u{a}o\x1fbar"), "foobar"); assert_eq!(native_name("fo\u{a}o\x1fbar"), "foobar");
} }
#[test]
fn normalize() {
fn normalize_res(name: &str) -> (bool, String) {
let mut name = NativeDeckName::from_native_str(name);
(name.maybe_normalize(), name.0)
}
assert_eq!(normalize_res("foo\x1fbar"), (false, "foo\x1fbar".into()));
assert_eq!(
normalize_res("fo\x1fo::ba\nr"),
(true, "fo\x1fo::bar".into())
);
assert_eq!(normalize_res("fo\u{a}obar"), (true, "foobar".into()));
}
#[test] #[test]
fn drag_drop() { fn drag_drop() {
// use custom separator to make the tests easier to read // use custom separator to make the tests easier to read