mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Fix find & replace for notes without 'field_name'
Distinguish between no 'field_name' passed and 'field_name' not on note.
This commit is contained in:
parent
9c354f5e6b
commit
b148b7b5e0
1 changed files with 21 additions and 11 deletions
|
@ -20,6 +20,12 @@ pub struct FindReplaceContext {
|
||||||
field_name: Option<String>,
|
field_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum FieldForNotetype {
|
||||||
|
Any,
|
||||||
|
Index(usize),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
impl FindReplaceContext {
|
impl FindReplaceContext {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
nids: Vec<NoteId>,
|
nids: Vec<NoteId>,
|
||||||
|
@ -62,17 +68,22 @@ impl Collection {
|
||||||
|
|
||||||
fn find_and_replace_inner(&mut self, ctx: FindReplaceContext) -> Result<usize> {
|
fn find_and_replace_inner(&mut self, ctx: FindReplaceContext) -> Result<usize> {
|
||||||
let mut last_ntid = None;
|
let mut last_ntid = None;
|
||||||
let mut field_ord = None;
|
let mut field_for_notetype = FieldForNotetype::None;
|
||||||
self.transform_notes(&ctx.nids, |note, nt| {
|
self.transform_notes(&ctx.nids, |note, nt| {
|
||||||
if last_ntid != Some(nt.id) {
|
if last_ntid != Some(nt.id) {
|
||||||
field_ord = ctx.field_name.as_ref().and_then(|n| nt.get_field_ord(n));
|
field_for_notetype = match ctx.field_name.as_ref() {
|
||||||
|
None => FieldForNotetype::Any,
|
||||||
|
Some(name) => match nt.get_field_ord(name) {
|
||||||
|
None => FieldForNotetype::None,
|
||||||
|
Some(ord) => FieldForNotetype::Index(ord),
|
||||||
|
},
|
||||||
|
};
|
||||||
last_ntid = Some(nt.id);
|
last_ntid = Some(nt.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
match field_ord {
|
match field_for_notetype {
|
||||||
None => {
|
FieldForNotetype::Any => {
|
||||||
// all fields
|
|
||||||
for txt in note.fields_mut() {
|
for txt in note.fields_mut() {
|
||||||
if let Cow::Owned(otxt) = ctx.replace_text(txt) {
|
if let Cow::Owned(otxt) = ctx.replace_text(txt) {
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -80,8 +91,7 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ord) => {
|
FieldForNotetype::Index(ord) => {
|
||||||
// single field
|
|
||||||
if let Some(txt) = note.fields_mut().get_mut(ord) {
|
if let Some(txt) = note.fields_mut().get_mut(ord) {
|
||||||
if let Cow::Owned(otxt) = ctx.replace_text(txt) {
|
if let Cow::Owned(otxt) = ctx.replace_text(txt) {
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -89,6 +99,7 @@ impl Collection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FieldForNotetype::None => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(TransformNoteOutput {
|
Ok(TransformNoteOutput {
|
||||||
|
@ -142,12 +153,11 @@ mod test {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
let out = col.find_and_replace(nids, "BBB", "ccc", Some("Front".into()))?;
|
let out = col.find_and_replace(nids, "BBB", "ccc", Some("Front".into()))?;
|
||||||
// still 2, as the caller is expected to provide only note ids that have
|
// 1, because notes without the specified field should be skipped
|
||||||
// that field, and if we can't find the field we fall back on all fields
|
assert_eq!(out.output, 1);
|
||||||
assert_eq!(out.output, 2);
|
|
||||||
|
|
||||||
let note = col.storage.get_note(note.id)?.unwrap();
|
let note = col.storage.get_note(note.id)?.unwrap();
|
||||||
// but the update should be limited to the specified field when it was available
|
// the update should be limited to the specified field when it was available
|
||||||
assert_eq!(¬e.fields()[..], &["one ccc", "two BBB"]);
|
assert_eq!(¬e.fields()[..], &["one ccc", "two BBB"]);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue