fix clippy lints for latest Rust

This commit is contained in:
Damien Elmes 2021-06-21 12:32:11 +10:00
parent 108af51abe
commit b392020798
39 changed files with 154 additions and 176 deletions

View File

@ -3,16 +3,18 @@
mod generated; mod generated;
use std::{
borrow::Cow,
sync::{Arc, Mutex},
};
use fluent::{types::FluentNumber, FluentArgs, FluentResource, FluentValue}; use fluent::{types::FluentNumber, FluentArgs, FluentResource, FluentValue};
use fluent_bundle::bundle::FluentBundle as FluentBundleOrig; use fluent_bundle::bundle::FluentBundle as FluentBundleOrig;
use generated::{KEYS_BY_MODULE, STRINGS};
use num_format::Locale; use num_format::Locale;
use serde::Serialize; use serde::Serialize;
use std::borrow::Cow;
use std::sync::{Arc, Mutex};
use unic_langid::LanguageIdentifier; use unic_langid::LanguageIdentifier;
use generated::{KEYS_BY_MODULE, STRINGS};
type FluentBundle<T> = FluentBundleOrig<T, intl_memoizer::concurrent::IntlLangMemoizer>; type FluentBundle<T> = FluentBundleOrig<T, intl_memoizer::concurrent::IntlLangMemoizer>;
pub use fluent::fluent_args as tr_args; pub use fluent::fluent_args as tr_args;
@ -26,10 +28,7 @@ impl Number for u64 {}
impl Number for usize {} impl Number for usize {}
fn remapped_lang_name(lang: &LanguageIdentifier) -> &str { fn remapped_lang_name(lang: &LanguageIdentifier) -> &str {
let region = match &lang.region { let region = lang.region.as_ref().map(|v| v.as_str());
Some(region) => Some(region.as_str()),
None => None,
};
match lang.language.as_str() { match lang.language.as_str() {
"en" => { "en" => {
match region { match region {
@ -425,13 +424,14 @@ pub struct ResourcesForJavascript {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*;
use unic_langid::langid; use unic_langid::langid;
use super::*;
#[test] #[test]
fn numbers() { fn numbers() {
assert_eq!(want_comma_as_decimal_separator(&[langid!("en-US")]), false); assert!(!want_comma_as_decimal_separator(&[langid!("en-US")]));
assert_eq!(want_comma_as_decimal_separator(&[langid!("pl-PL")]), true); assert!(want_comma_as_decimal_separator(&[langid!("pl-PL")]));
} }
#[test] #[test]

View File

@ -36,8 +36,8 @@ impl CardRenderingService for Backend {
field_text, field_text,
lang, lang,
voices, voices,
other_args,
speed, speed,
other_args,
})), })),
}, },
}) })

View File

@ -50,7 +50,7 @@ impl ToSql for SqlValue {
SqlValue::String(v) => ValueRef::Text(v.as_bytes()), SqlValue::String(v) => ValueRef::Text(v.as_bytes()),
SqlValue::Int(v) => ValueRef::Integer(*v), SqlValue::Int(v) => ValueRef::Integer(*v),
SqlValue::Double(v) => ValueRef::Real(*v), SqlValue::Double(v) => ValueRef::Real(*v),
SqlValue::Blob(v) => ValueRef::Blob(&v), SqlValue::Blob(v) => ValueRef::Blob(v),
}; };
Ok(ToSqlOutput::Borrowed(val)) Ok(ToSqlOutput::Borrowed(val))
} }

View File

@ -99,8 +99,8 @@ pub(super) fn progress_to_proto(progress: Option<Progress>, tr: &I18n) -> pb::Pr
.to_string(); .to_string();
pb::progress::Value::DatabaseCheck(pb::progress::DatabaseCheck { pb::progress::Value::DatabaseCheck(pb::progress::DatabaseCheck {
stage, stage,
stage_current,
stage_total, stage_total,
stage_current,
}) })
} }
} }

View File

@ -150,8 +150,8 @@ impl Card {
pub fn new(note_id: NoteId, template_idx: u16, deck_id: DeckId, due: i32) -> Self { pub fn new(note_id: NoteId, template_idx: u16, deck_id: DeckId, due: i32) -> Self {
Card { Card {
note_id, note_id,
template_idx,
deck_id, deck_id,
template_idx,
due, due,
..Default::default() ..Default::default()
} }

View File

@ -82,35 +82,35 @@ mod test {
let key = BoolKey::NormalizeNoteText; let key = BoolKey::NormalizeNoteText;
// not set by default, but defaults to true // not set by default, but defaults to true
assert_eq!(col.get_config_bool(key), true); assert!(col.get_config_bool(key));
// first set adds the key // first set adds the key
col.transact(op.clone(), |col| col.set_config_bool_inner(key, false))?; col.transact(op.clone(), |col| col.set_config_bool_inner(key, false))?;
assert_eq!(col.get_config_bool(key), false); assert!(!col.get_config_bool(key));
// mutate it twice // mutate it twice
col.transact(op.clone(), |col| col.set_config_bool_inner(key, true))?; col.transact(op.clone(), |col| col.set_config_bool_inner(key, true))?;
assert_eq!(col.get_config_bool(key), true); assert!(col.get_config_bool(key));
col.transact(op.clone(), |col| col.set_config_bool_inner(key, false))?; col.transact(op.clone(), |col| col.set_config_bool_inner(key, false))?;
assert_eq!(col.get_config_bool(key), false); assert!(!col.get_config_bool(key));
// when we remove it, it goes back to its default // when we remove it, it goes back to its default
col.transact(op, |col| col.remove_config_inner(key))?; col.transact(op, |col| col.remove_config_inner(key))?;
assert_eq!(col.get_config_bool(key), true); assert!(col.get_config_bool(key));
// undo the removal // undo the removal
col.undo()?; col.undo()?;
assert_eq!(col.get_config_bool(key), false); assert!(!col.get_config_bool(key));
// undo the mutations // undo the mutations
col.undo()?; col.undo()?;
assert_eq!(col.get_config_bool(key), true); assert!(col.get_config_bool(key));
col.undo()?; col.undo()?;
assert_eq!(col.get_config_bool(key), false); assert!(!col.get_config_bool(key));
// and undo the initial add // and undo the initial add
col.undo()?; col.undo()?;
assert_eq!(col.get_config_bool(key), true); assert!(col.get_config_bool(key));
Ok(()) Ok(())
} }

View File

@ -260,7 +260,7 @@ impl Collection {
CardGenContext::new(&nt, self.get_last_deck_added_to_for_notetype(nt.id), usn) CardGenContext::new(&nt, self.get_last_deck_added_to_for_notetype(nt.id), usn)
}); });
self.update_note_inner_generating_cards( self.update_note_inner_generating_cards(
&ctx, &mut note, &original, false, norm, true, ctx, &mut note, &original, false, norm, true,
)?; )?;
} }
} }
@ -480,11 +480,9 @@ mod test {
..Default::default() ..Default::default()
} }
); );
assert_eq!( assert!(col
col.storage .storage
.db_scalar::<bool>("select ivl = lastIvl = 1 from revlog")?, .db_scalar::<bool>("select ivl = lastIvl = 1 from revlog")?);
true
);
Ok(()) Ok(())
} }
@ -625,8 +623,8 @@ mod test {
col.check_database(progress_fn)?; col.check_database(progress_fn)?;
assert_eq!(col.storage.get_tag("one")?.unwrap().expanded, true); assert!(col.storage.get_tag("one")?.unwrap().expanded);
assert_eq!(col.storage.get_tag("two")?.unwrap().expanded, false); assert!(!col.storage.get_tag("two")?.unwrap().expanded);
Ok(()) Ok(())
} }

View File

@ -229,17 +229,14 @@ mod test {
removed_config_ids: vec![], removed_config_ids: vec![],
apply_to_children: false, apply_to_children: false,
}; };
assert_eq!( assert!(!col.update_deck_configs(input.clone())?.changes.had_change());
col.update_deck_configs(input.clone())?.changes.had_change(),
false
);
// modifying a value should update the config, but not the deck // modifying a value should update the config, but not the deck
input.configs[0].inner.new_per_day += 1; input.configs[0].inner.new_per_day += 1;
let changes = col.update_deck_configs(input.clone())?.changes.changes; let changes = col.update_deck_configs(input.clone())?.changes.changes;
assert_eq!(changes.deck, false); assert!(!changes.deck);
assert_eq!(changes.deck_config, true); assert!(changes.deck_config);
assert_eq!(changes.card, false); assert!(!changes.card);
// adding a new config will update the deck as well // adding a new config will update the deck as well
let new_config = DeckConfig { let new_config = DeckConfig {
@ -248,9 +245,9 @@ mod test {
}; };
input.configs.push(new_config); input.configs.push(new_config);
let changes = col.update_deck_configs(input.clone())?.changes.changes; let changes = col.update_deck_configs(input.clone())?.changes.changes;
assert_eq!(changes.deck, true); assert!(changes.deck);
assert_eq!(changes.deck_config, true); assert!(changes.deck_config);
assert_eq!(changes.card, false); assert!(!changes.card);
let allocated_id = col.get_deck(DeckId(1))?.unwrap().normal()?.config_id; let allocated_id = col.get_deck(DeckId(1))?.unwrap().normal()?.config_id;
assert_ne!(allocated_id, 0); assert_ne!(allocated_id, 0);
assert_ne!(allocated_id, 1); assert_ne!(allocated_id, 1);
@ -260,10 +257,7 @@ mod test {
reset_card1_pos(&mut col); reset_card1_pos(&mut col);
assert_eq!(card1_pos(&mut col), 0); assert_eq!(card1_pos(&mut col), 0);
input.configs[1].inner.new_card_insert_order = NewCardInsertOrder::Random as i32; input.configs[1].inner.new_card_insert_order = NewCardInsertOrder::Random as i32;
assert_eq!( assert!(col.update_deck_configs(input.clone())?.changes.changes.card);
col.update_deck_configs(input.clone())?.changes.changes.card,
true
);
assert_ne!(card1_pos(&mut col), 0); assert_ne!(card1_pos(&mut col), 0);
// removing the config will assign the selected config (default in this case), // removing the config will assign the selected config (default in this case),

View File

@ -271,13 +271,8 @@ impl Collection {
} }
if let Some(now) = now { if let Some(now) = now {
let limit = top_deck_id.and_then(|did| { let limit = top_deck_id
if let Some(deck) = decks_map.get(&did) { .and_then(|did| decks_map.get(&did).map(|deck| deck.name.as_native_str()));
Some(deck.name.as_native_str())
} else {
None
}
});
let days_elapsed = self.timing_for_timestamp(now)?.days_elapsed; let days_elapsed = self.timing_for_timestamp(now)?.days_elapsed;
let learn_cutoff = (now.0 as u32) + self.learn_ahead_secs(); let learn_cutoff = (now.0 as u32) + self.learn_ahead_secs();
let sched_ver = self.scheduler_version(); let sched_ver = self.scheduler_version();

View File

@ -80,7 +80,7 @@ impl AnkiError {
format!("{}<br>{}", header, details) format!("{}<br>{}", header, details)
} }
AnkiError::DbError(err) => err.localized_description(tr), AnkiError::DbError(err) => err.localized_description(tr),
AnkiError::SearchError(kind) => kind.localized_description(&tr), AnkiError::SearchError(kind) => kind.localized_description(tr),
AnkiError::InvalidInput(info) => { AnkiError::InvalidInput(info) => {
if info.is_empty() { if info.is_empty() {
tr.errors_invalid_input_empty().into() tr.errors_invalid_input_empty().into()

View File

@ -114,7 +114,7 @@ where
}; };
// make sure the filename is normalized // make sure the filename is normalized
let fname = match filename_if_normalized(&disk_fname) { let fname = match filename_if_normalized(disk_fname) {
Some(fname) => fname, Some(fname) => fname,
None => { None => {
// not normalized; skip it // not normalized; skip it

View File

@ -227,7 +227,7 @@ where
} else { } else {
match data_for_file(&self.mgr.media_folder, disk_fname)? { match data_for_file(&self.mgr.media_folder, disk_fname)? {
Some(data) => { Some(data) => {
let norm_name = self.normalize_file(ctx, &disk_fname, data)?; let norm_name = self.normalize_file(ctx, disk_fname, data)?;
out.renamed out.renamed
.insert(disk_fname.to_string(), norm_name.to_string()); .insert(disk_fname.to_string(), norm_name.to_string());
out.files.push(norm_name.into_owned()); out.files.push(norm_name.into_owned());

View File

@ -106,7 +106,7 @@ impl MediaManager {
{ {
let pre_remove_folder_mtime = mtime_as_i64(&self.media_folder)?; let pre_remove_folder_mtime = mtime_as_i64(&self.media_folder)?;
remove_files(&self.media_folder, &filenames)?; remove_files(&self.media_folder, filenames)?;
let post_remove_folder_mtime = mtime_as_i64(&self.media_folder)?; let post_remove_folder_mtime = mtime_as_i64(&self.media_folder)?;

View File

@ -260,7 +260,7 @@ where
let resp = self let resp = self
.client .client
.get(&url) .get(&url)
.query(&[("k", hkey), ("v", &sync_client_version())]) .query(&[("k", hkey), ("v", sync_client_version())])
.send() .send()
.await? .await?
.error_for_status()?; .error_for_status()?;

View File

@ -135,7 +135,7 @@ impl Note {
} }
} }
#[allow(clippy::clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) fn new_from_storage( pub(crate) fn new_from_storage(
id: NoteId, id: NoteId,
guid: String, guid: String,
@ -323,7 +323,7 @@ fn invalid_char_for_field(c: char) -> bool {
impl Collection { impl Collection {
fn canonify_note_tags(&mut self, note: &mut Note, usn: Usn) -> Result<()> { fn canonify_note_tags(&mut self, note: &mut Note, usn: Usn) -> Result<()> {
if !note.tags.is_empty() { if !note.tags.is_empty() {
let tags = std::mem::replace(&mut note.tags, vec![]); let tags = std::mem::take(&mut note.tags);
note.tags = self.canonify_tags(tags, usn)?.0; note.tags = self.canonify_tags(tags, usn)?.0;
} }
Ok(()) Ok(())
@ -337,7 +337,7 @@ impl Collection {
normalize_text: bool, normalize_text: bool,
) -> Result<()> { ) -> Result<()> {
self.canonify_note_tags(note, ctx.usn)?; self.canonify_note_tags(note, ctx.usn)?;
note.prepare_for_update(&ctx.notetype, normalize_text)?; note.prepare_for_update(ctx.notetype, normalize_text)?;
note.set_modified(ctx.usn); note.set_modified(ctx.usn);
self.add_note_only_undoable(note)?; self.add_note_only_undoable(note)?;
self.generate_cards_for_new_note(ctx, note, did)?; self.generate_cards_for_new_note(ctx, note, did)?;
@ -415,7 +415,7 @@ impl Collection {
} }
// TODO: refactor into struct // TODO: refactor into struct
#[allow(clippy::clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) fn update_note_inner_without_cards( pub(crate) fn update_note_inner_without_cards(
&mut self, &mut self,
note: &mut Note, note: &mut Note,
@ -504,7 +504,7 @@ impl Collection {
) )
}); });
self.update_note_inner_generating_cards( self.update_note_inner_generating_cards(
&ctx, ctx,
&mut note, &mut note,
&original, &original,
out.mark_modified, out.mark_modified,
@ -559,7 +559,7 @@ impl Collection {
} }
fn is_duplicate(&self, first_field: &str, note: &Note) -> Result<bool> { fn is_duplicate(&self, first_field: &str, note: &Note) -> Result<bool> {
let csum = field_checksum(&first_field); let csum = field_checksum(first_field);
Ok(self Ok(self
.storage .storage
.note_fields_by_checksum(note.notetype_id, csum)? .note_fields_by_checksum(note.notetype_id, csum)?
@ -735,7 +735,7 @@ mod test {
col.storage.db_scalar::<u32>("select count() from graves")?, col.storage.db_scalar::<u32>("select count() from graves")?,
0 0
); );
assert_eq!(col.get_next_card()?.is_some(), false); assert!(!col.get_next_card()?.is_some());
Ok(()) Ok(())
}; };
@ -746,7 +746,7 @@ mod test {
col.storage.db_scalar::<u32>("select count() from graves")?, col.storage.db_scalar::<u32>("select count() from graves")?,
0 0
); );
assert_eq!(col.get_next_card()?.is_some(), true); assert!(col.get_next_card()?.is_some());
Ok(()) Ok(())
}; };
@ -774,7 +774,7 @@ mod test {
col.storage.db_scalar::<u32>("select count() from graves")?, col.storage.db_scalar::<u32>("select count() from graves")?,
3 3
); );
assert_eq!(col.get_next_card()?.is_some(), false); assert!(!col.get_next_card()?.is_some());
Ok(()) Ok(())
}; };

View File

@ -58,7 +58,7 @@ impl CardGenContext<'_> {
CardGenContext { CardGenContext {
usn, usn,
last_deck, last_deck,
notetype: &nt, notetype: nt,
cards: nt cards: nt
.templates .templates
.iter() .iter()
@ -82,7 +82,7 @@ impl CardGenContext<'_> {
} }
}; };
template.renders_with_fields(&nonempty_fields) template.renders_with_fields(nonempty_fields)
} }
/// Returns the cards that need to be generated for the provided note. /// Returns the cards that need to be generated for the provided note.
@ -239,7 +239,7 @@ impl Collection {
target_deck_id: Option<DeckId>, target_deck_id: Option<DeckId>,
cache: &mut CardGenCache, cache: &mut CardGenCache,
) -> Result<()> { ) -> Result<()> {
let cards = ctx.new_cards_required(note, &existing, true); let cards = ctx.new_cards_required(note, existing, true);
if cards.is_empty() { if cards.is_empty() {
return Ok(()); return Ok(());
} }
@ -337,13 +337,9 @@ impl Collection {
/// If deck exists and and is a normal deck, return its ID and config /// If deck exists and and is a normal deck, return its ID and config
fn deck_conf_if_normal(&mut self, did: DeckId) -> Result<Option<(DeckId, DeckConfigId)>> { fn deck_conf_if_normal(&mut self, did: DeckId) -> Result<Option<(DeckId, DeckConfigId)>> {
Ok(self.get_deck(did)?.and_then(|d| { Ok(self
if let Some(conf_id) = d.config_id() { .get_deck(did)?
Some((did, conf_id)) .and_then(|d| d.config_id().map(|conf_id| (did, conf_id))))
} else {
None
}
}))
} }
} }

View File

@ -99,7 +99,7 @@ impl Default for Notetype {
impl Notetype { impl Notetype {
pub fn new_note(&self) -> Note { pub fn new_note(&self) -> Note {
Note::new(&self) Note::new(self)
} }
/// Return the template for the given card ordinal. Cloze notetypes /// Return the template for the given card ordinal. Cloze notetypes
@ -200,7 +200,7 @@ impl Collection {
return Err(AnkiError::NotFound); return Err(AnkiError::NotFound);
} }
let nids_node: Node = SearchNode::NoteIds(comma_separated_ids(&note_ids)).into(); let nids_node: Node = SearchNode::NoteIds(comma_separated_ids(note_ids)).into();
let note1 = self let note1 = self
.storage .storage
.get_note(*note_ids.first().unwrap())? .get_note(*note_ids.first().unwrap())?
@ -663,7 +663,7 @@ impl Collection {
// adding with existing id for old undo code, bypass undo // adding with existing id for old undo code, bypass undo
self.state.notetype_cache.remove(&notetype.id); self.state.notetype_cache.remove(&notetype.id);
self.storage self.storage
.add_or_update_notetype_with_existing_id(&notetype)?; .add_or_update_notetype_with_existing_id(notetype)?;
} }
Ok(()) Ok(())

View File

@ -56,7 +56,7 @@ impl TemplateMap {
.collect(); .collect();
let removed: Vec<_> = (0..old_template_count) let removed: Vec<_> = (0..old_template_count)
.filter(|idx| !seen.contains(&idx)) .filter(|idx| !seen.contains(idx))
.collect(); .collect();
TemplateMap { removed, remapped } TemplateMap { removed, remapped }

View File

@ -96,7 +96,7 @@ impl Collection {
let mut field_map = note.fields_map(&nt.fields); let mut field_map = note.fields_map(&nt.fields);
let card_num; let card_num;
self.add_special_fields(&mut field_map, note, card, &nt, template)?; self.add_special_fields(&mut field_map, note, card, nt, template)?;
// due to lifetime restrictions we need to add card number here // due to lifetime restrictions we need to add card number here
card_num = format!("c{}", card.template_idx + 1); card_num = format!("c{}", card.template_idx + 1);
field_map.entry(&card_num).or_insert_with(|| "1".into()); field_map.entry(&card_num).or_insert_with(|| "1".into());

View File

@ -48,7 +48,7 @@ impl TemplateOrdChanges {
} }
} }
changes.removed = removed.into_iter().filter_map(|v| v).collect(); changes.removed = removed.into_iter().flatten().collect();
changes changes
} }
@ -83,11 +83,10 @@ impl Collection {
false, false,
)?; )?;
} }
return Ok(());
} else { } else {
// nothing to do // nothing to do
return Ok(());
} }
return Ok(());
} }
// fields have changed // fields have changed
@ -192,11 +191,11 @@ mod test {
#[test] #[test]
fn ord_changes() { fn ord_changes() {
assert_eq!(ords_changed(&[Some(0), Some(1)], 2), false); assert!(!ords_changed(&[Some(0), Some(1)], 2));
assert_eq!(ords_changed(&[Some(0), Some(1)], 1), true); assert!(ords_changed(&[Some(0), Some(1)], 1));
assert_eq!(ords_changed(&[Some(1), Some(0)], 2), true); assert!(ords_changed(&[Some(1), Some(0)], 2));
assert_eq!(ords_changed(&[None, Some(1)], 2), true); assert!(ords_changed(&[None, Some(1)], 2));
assert_eq!(ords_changed(&[Some(0), Some(1), None], 2), true); assert!(ords_changed(&[Some(0), Some(1), None], 2));
} }
#[test] #[test]

View File

@ -259,9 +259,9 @@ impl Collection {
))); )));
} }
if let Some(revlog_partial) = updater.apply_study_state(current_state, answer.new_state)? { if let Some(revlog_partial) = updater.apply_study_state(current_state, answer.new_state)? {
self.add_partial_revlog(revlog_partial, usn, &answer)?; self.add_partial_revlog(revlog_partial, usn, answer)?;
} }
self.update_deck_stats_from_answer(usn, &answer, &updater, original.queue)?; self.update_deck_stats_from_answer(usn, answer, &updater, original.queue)?;
self.maybe_bury_siblings(&original, &updater.config)?; self.maybe_bury_siblings(&original, &updater.config)?;
let timing = updater.timing; let timing = updater.timing;
let mut card = updater.into_card(); let mut card = updater.into_card();

View File

@ -147,12 +147,12 @@ mod test {
let note = col.storage.get_note(nid)?.unwrap(); let note = col.storage.get_note(nid)?.unwrap();
assert_eq!(note.tags, vec!["leech".to_string()]); assert_eq!(note.tags, vec!["leech".to_string()]);
assert_eq!(col.storage.all_tags()?.is_empty(), false); assert!(!col.storage.all_tags()?.is_empty());
let deck = col.get_deck(DeckId(1))?.unwrap(); let deck = col.get_deck(DeckId(1))?.unwrap();
assert_eq!(deck.common.review_studied, 1); assert_eq!(deck.common.review_studied, 1);
assert_eq!(col.get_next_card()?.is_some(), false); assert!(!col.get_next_card()?.is_some());
Ok(()) Ok(())
}; };
@ -172,12 +172,12 @@ mod test {
// the note should no longer be tagged as a leech // the note should no longer be tagged as a leech
let note = col.storage.get_note(nid)?.unwrap(); let note = col.storage.get_note(nid)?.unwrap();
assert_eq!(note.tags.is_empty(), true); assert!(note.tags.is_empty());
assert_eq!(col.storage.all_tags()?.is_empty(), true); assert!(col.storage.all_tags()?.is_empty());
let deck = col.get_deck(DeckId(1))?.unwrap(); let deck = col.get_deck(DeckId(1))?.unwrap();
assert_eq!(deck.common.review_studied, 0); assert_eq!(deck.common.review_studied, 0);
assert_eq!(col.get_next_card()?.is_some(), true); assert!(col.get_next_card()?.is_some());
assert_eq!(col.counts(), [0, 0, 1]); assert_eq!(col.counts(), [0, 0, 1]);
Ok(()) Ok(())

View File

@ -49,8 +49,8 @@ impl CardState {
pub(crate) fn next_states(self, ctx: &StateContext) -> NextCardStates { pub(crate) fn next_states(self, ctx: &StateContext) -> NextCardStates {
match self { match self {
CardState::Normal(state) => state.next_states(&ctx), CardState::Normal(state) => state.next_states(ctx),
CardState::Filtered(state) => state.next_states(&ctx), CardState::Filtered(state) => state.next_states(ctx),
} }
} }

View File

@ -21,7 +21,7 @@ impl ReschedulingFilterState {
} }
pub(crate) fn next_states(self, ctx: &StateContext) -> NextCardStates { pub(crate) fn next_states(self, ctx: &StateContext) -> NextCardStates {
let normal = self.original_state.next_states(&ctx); let normal = self.original_state.next_states(ctx);
if ctx.in_filtered_deck { if ctx.in_filtered_deck {
NextCardStates { NextCardStates {
current: self.into(), current: self.into(),

View File

@ -237,30 +237,30 @@ mod test {
#[test] #[test]
fn leech_threshold() { fn leech_threshold() {
assert_eq!(leech_threshold_met(0, 3), false); assert!(!leech_threshold_met(0, 3));
assert_eq!(leech_threshold_met(1, 3), false); assert!(!leech_threshold_met(1, 3));
assert_eq!(leech_threshold_met(2, 3), false); assert!(!leech_threshold_met(2, 3));
assert_eq!(leech_threshold_met(3, 3), true); assert!(leech_threshold_met(3, 3));
assert_eq!(leech_threshold_met(4, 3), false); assert!(!leech_threshold_met(4, 3));
assert_eq!(leech_threshold_met(5, 3), true); assert!(leech_threshold_met(5, 3));
assert_eq!(leech_threshold_met(6, 3), false); assert!(!leech_threshold_met(6, 3));
assert_eq!(leech_threshold_met(7, 3), true); assert!(leech_threshold_met(7, 3));
assert_eq!(leech_threshold_met(7, 8), false); assert!(!leech_threshold_met(7, 8));
assert_eq!(leech_threshold_met(8, 8), true); assert!(leech_threshold_met(8, 8));
assert_eq!(leech_threshold_met(9, 8), false); assert!(!leech_threshold_met(9, 8));
assert_eq!(leech_threshold_met(10, 8), false); assert!(!leech_threshold_met(10, 8));
assert_eq!(leech_threshold_met(11, 8), false); assert!(!leech_threshold_met(11, 8));
assert_eq!(leech_threshold_met(12, 8), true); assert!(leech_threshold_met(12, 8));
assert_eq!(leech_threshold_met(13, 8), false); assert!(!leech_threshold_met(13, 8));
// 0 means off // 0 means off
assert_eq!(leech_threshold_met(0, 0), false); assert!(!leech_threshold_met(0, 0));
// no div by zero; half of 1 is 1 // no div by zero; half of 1 is 1
assert_eq!(leech_threshold_met(0, 1), false); assert!(!leech_threshold_met(0, 1));
assert_eq!(leech_threshold_met(1, 1), true); assert!(leech_threshold_met(1, 1));
assert_eq!(leech_threshold_met(2, 1), true); assert!(leech_threshold_met(2, 1));
assert_eq!(leech_threshold_met(3, 1), true); assert!(leech_threshold_met(3, 1));
} }
} }

View File

@ -705,7 +705,7 @@ fn unescape(txt: &str) -> ParseResult<String> {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r#"\\[\\":()-]"#).unwrap(); static ref RE: Regex = Regex::new(r#"\\[\\":()-]"#).unwrap();
} }
RE.replace_all(&txt, |caps: &Captures| match &caps[0] { RE.replace_all(txt, |caps: &Captures| match &caps[0] {
r"\\" => r"\\", r"\\" => r"\\",
"\\\"" => "\"", "\\\"" => "\"",
r"\:" => ":", r"\:" => ":",

View File

@ -53,7 +53,7 @@ impl SqlWriter<'_> {
) -> Result<(String, Vec<String>)> { ) -> Result<(String, Vec<String>)> {
self.table = self.table.combine(table.combine(node.required_table())); self.table = self.table.combine(table.combine(node.required_table()));
self.write_table_sql(); self.write_table_sql();
self.write_node_to_sql(&node)?; self.write_node_to_sql(node)?;
Ok((self.sql, self.args)) Ok((self.sql, self.args))
} }

View File

@ -51,7 +51,7 @@ impl super::SqliteStorage {
note.mtime, note.mtime,
note.usn, note.usn,
join_tags(&note.tags), join_tags(&note.tags),
join_fields(&note.fields()), join_fields(note.fields()),
note.sort_field.as_ref().unwrap(), note.sort_field.as_ref().unwrap(),
note.checksum.unwrap(), note.checksum.unwrap(),
note.id note.id
@ -69,7 +69,7 @@ impl super::SqliteStorage {
note.mtime, note.mtime,
note.usn, note.usn,
join_tags(&note.tags), join_tags(&note.tags),
join_fields(&note.fields()), join_fields(note.fields()),
note.sort_field.as_ref().unwrap(), note.sort_field.as_ref().unwrap(),
note.checksum.unwrap(), note.checksum.unwrap(),
])?; ])?;
@ -87,7 +87,7 @@ impl super::SqliteStorage {
note.mtime, note.mtime,
note.usn, note.usn,
join_tags(&note.tags), join_tags(&note.tags),
join_fields(&note.fields()), join_fields(note.fields()),
note.sort_field.as_ref().unwrap(), note.sort_field.as_ref().unwrap(),
note.checksum.unwrap(), note.checksum.unwrap(),
])?; ])?;

View File

@ -428,7 +428,7 @@ mod test {
syncer.set_full_sync_progress_fn(Some(Box::new(|progress, _throttle| { syncer.set_full_sync_progress_fn(Some(Box::new(|progress, _throttle| {
println!("progress {:?}", progress); println!("progress {:?}", progress);
}))); })));
syncer.full_upload(&out_path.path(), false).await?; syncer.full_upload(out_path.path(), false).await?;
Ok(()) Ok(())
} }

View File

@ -84,6 +84,6 @@ mod test {
assert_eq!(&add_to(""), " abc DEF xyz "); assert_eq!(&add_to(""), " abc DEF xyz ");
assert_eq!(&add_to("XYZ deF aaa"), " aaa abc deF XYZ "); assert_eq!(&add_to("XYZ deF aaa"), " aaa abc deF XYZ ");
assert_eq!(add_missing_tags("def xyz abc", &desired).is_none(), true); assert!(add_missing_tags("def xyz abc", &desired).is_none());
} }
} }

View File

@ -131,17 +131,17 @@ mod test {
#[test] #[test]
fn regex() -> Result<()> { fn regex() -> Result<()> {
let re = TagMatcher::new("one two")?; let re = TagMatcher::new("one two")?;
assert_eq!(re.is_match(" foo "), false); assert!(!re.is_match(" foo "));
assert_eq!(re.is_match(" foo one "), true); assert!(re.is_match(" foo one "));
assert_eq!(re.is_match(" two foo "), true); assert!(re.is_match(" two foo "));
let mut re = TagMatcher::new("foo")?; let mut re = TagMatcher::new("foo")?;
assert_eq!(re.is_match("foo"), true); assert!(re.is_match("foo"));
assert_eq!(re.is_match(" foo "), true); assert!(re.is_match(" foo "));
assert_eq!(re.is_match(" bar foo baz "), true); assert!(re.is_match(" bar foo baz "));
assert_eq!(re.is_match(" bar FOO baz "), true); assert!(re.is_match(" bar FOO baz "));
assert_eq!(re.is_match(" bar foof baz "), false); assert!(!re.is_match(" bar foof baz "));
assert_eq!(re.is_match(" barfoo "), false); assert!(!re.is_match(" barfoo "));
let mut as_xxx = |text| re.replace(text, "xxx"); let mut as_xxx = |text| re.replace(text, "xxx");

View File

@ -65,7 +65,7 @@ impl Collection {
pub(crate) fn register_tag(&mut self, tag: &mut Tag) -> Result<bool> { pub(crate) fn register_tag(&mut self, tag: &mut Tag) -> Result<bool> {
let is_new = self.prepare_tag_for_registering(tag)?; let is_new = self.prepare_tag_for_registering(tag)?;
if is_new { if is_new {
self.register_tag_undoable(&tag)?; self.register_tag_undoable(tag)?;
} }
Ok(is_new) Ok(is_new)
} }
@ -100,7 +100,7 @@ impl Collection {
impl Collection { impl Collection {
/// If parent tag(s) exist and differ in case, return a rewritten tag. /// If parent tag(s) exist and differ in case, return a rewritten tag.
fn adjusted_case_for_parents(&self, tag: &str) -> Result<Option<String>> { fn adjusted_case_for_parents(&self, tag: &str) -> Result<Option<String>> {
if let Some(parent_tag) = self.first_existing_parent_tag(&tag)? { if let Some(parent_tag) = self.first_existing_parent_tag(tag)? {
let child_split: Vec<_> = tag.split("::").collect(); let child_split: Vec<_> = tag.split("::").collect();
let parent_count = parent_tag.matches("::").count() + 1; let parent_count = parent_tag.matches("::").count() + 1;
Ok(Some(format!( Ok(Some(format!(

View File

@ -109,8 +109,8 @@ mod test {
col.set_tag_collapsed("one", false)?; col.set_tag_collapsed("one", false)?;
col.clear_unused_tags()?; col.clear_unused_tags()?;
assert_eq!(col.storage.get_tag("one")?.unwrap().expanded, true); assert!(col.storage.get_tag("one")?.unwrap().expanded);
assert_eq!(col.storage.get_tag("two")?.unwrap().expanded, false); assert!(!col.storage.get_tag("two")?.unwrap().expanded);
// tag children are also cleared when clearing their parent // tag children are also cleared when clearing their parent
col.storage.clear_all_tags()?; col.storage.clear_all_tags()?;

View File

@ -82,12 +82,8 @@ fn old_to_new_names(
.iter() .iter()
// generate resulting names and filter out invalid ones // generate resulting names and filter out invalid ones
.flat_map(|source_tag| { .flat_map(|source_tag| {
if let Some(output_name) = reparented_name(source_tag, new_parent.as_deref()) { reparented_name(source_tag, new_parent.as_deref())
Some((source_tag.as_str(), output_name)) .map(|output_name| (source_tag.as_str(), output_name))
} else {
// invalid rename, ignore this tag
None
}
}) })
.collect() .collect()
} }

View File

@ -36,7 +36,7 @@ impl Collection {
fn update_tag_inner(&mut self, tag: &mut Tag, original: Tag, usn: Usn) -> Result<()> { fn update_tag_inner(&mut self, tag: &mut Tag, original: Tag, usn: Usn) -> Result<()> {
tag.set_modified(usn); tag.set_modified(usn);
self.update_tag_undoable(&tag, original) self.update_tag_undoable(tag, original)
} }
} }

View File

@ -36,7 +36,7 @@ impl Collection {
/// Caller is responsible for setting usn. /// Caller is responsible for setting usn.
pub(super) fn register_tag_undoable(&mut self, tag: &Tag) -> Result<()> { pub(super) fn register_tag_undoable(&mut self, tag: &Tag) -> Result<()> {
self.save_undo(UndoableTagChange::Added(Box::new(tag.clone()))); self.save_undo(UndoableTagChange::Added(Box::new(tag.clone())));
self.storage.register_tag(&tag) self.storage.register_tag(tag)
} }
/// Remove a single tag from the tag list, saving an undo entry. Does not alter notes. /// Remove a single tag from the tag list, saving an undo entry. Does not alter notes.

View File

@ -656,7 +656,7 @@ impl ParsedTemplate {
/// Given a map of old to new field names, update references to the new names. /// Given a map of old to new field names, update references to the new names.
/// Returns true if any changes made. /// Returns true if any changes made.
pub(crate) fn rename_and_remove_fields(&mut self, fields: &HashMap<String, Option<String>>) { pub(crate) fn rename_and_remove_fields(&mut self, fields: &HashMap<String, Option<String>>) {
let old_nodes = std::mem::replace(&mut self.0, vec![]); let old_nodes = std::mem::take(&mut self.0);
self.0 = rename_and_remove_fields(old_nodes, fields); self.0 = rename_and_remove_fields(old_nodes, fields);
} }
} }
@ -746,12 +746,12 @@ fn nodes_to_string(buf: &mut String, nodes: &[ParsedNode]) {
} }
ParsedNode::Conditional { key, children } => { ParsedNode::Conditional { key, children } => {
write!(buf, "{{{{#{}}}}}", key).unwrap(); write!(buf, "{{{{#{}}}}}", key).unwrap();
nodes_to_string(buf, &children); nodes_to_string(buf, children);
write!(buf, "{{{{/{}}}}}", key).unwrap(); write!(buf, "{{{{/{}}}}}", key).unwrap();
} }
ParsedNode::NegatedConditional { key, children } => { ParsedNode::NegatedConditional { key, children } => {
write!(buf, "{{{{^{}}}}}", key).unwrap(); write!(buf, "{{{{^{}}}}}", key).unwrap();
nodes_to_string(buf, &children); nodes_to_string(buf, children);
write!(buf, "{{{{/{}}}}}", key).unwrap(); write!(buf, "{{{{/{}}}}}", key).unwrap();
} }
} }
@ -794,10 +794,10 @@ fn find_fields_with_filter<'a>(
} }
} }
ParsedNode::Conditional { children, .. } => { ParsedNode::Conditional { children, .. } => {
find_fields_with_filter(&children, fields, filter); find_fields_with_filter(children, fields, filter);
} }
ParsedNode::NegatedConditional { children, .. } => { ParsedNode::NegatedConditional { children, .. } => {
find_fields_with_filter(&children, fields, filter); find_fields_with_filter(children, fields, filter);
} }
} }
} }
@ -819,13 +819,13 @@ mod test {
#[test] #[test]
fn field_empty() { fn field_empty() {
assert_eq!(field_is_empty(""), true); assert!(field_is_empty(""));
assert_eq!(field_is_empty(" "), true); assert!(field_is_empty(" "));
assert_eq!(field_is_empty("x"), false); assert!(!field_is_empty("x"));
assert_eq!(field_is_empty("<BR>"), true); assert!(field_is_empty("<BR>"));
assert_eq!(field_is_empty("<div />"), true); assert!(field_is_empty("<div />"));
assert_eq!(field_is_empty(" <div> <br> </div>\n"), true); assert!(field_is_empty(" <div> <br> </div>\n"));
assert_eq!(field_is_empty(" <div>x</div>\n"), false); assert!(!field_is_empty(" <div>x</div>\n"));
} }
#[test] #[test]
@ -891,17 +891,17 @@ mod test {
fn nonempty() { fn nonempty() {
let fields = vec!["1", "3"].into_iter().collect(); let fields = vec!["1", "3"].into_iter().collect();
let mut tmpl = PT::from_text("{{2}}{{1}}").unwrap(); let mut tmpl = PT::from_text("{{2}}{{1}}").unwrap();
assert_eq!(tmpl.renders_with_fields(&fields), true); assert!(tmpl.renders_with_fields(&fields));
tmpl = PT::from_text("{{2}}").unwrap(); tmpl = PT::from_text("{{2}}").unwrap();
assert_eq!(tmpl.renders_with_fields(&fields), false); assert!(!tmpl.renders_with_fields(&fields));
tmpl = PT::from_text("{{2}}{{4}}").unwrap(); tmpl = PT::from_text("{{2}}{{4}}").unwrap();
assert_eq!(tmpl.renders_with_fields(&fields), false); assert!(!tmpl.renders_with_fields(&fields));
tmpl = PT::from_text("{{#3}}{{^2}}{{1}}{{/2}}{{/3}}").unwrap(); tmpl = PT::from_text("{{#3}}{{^2}}{{1}}{{/2}}{{/3}}").unwrap();
assert_eq!(tmpl.renders_with_fields(&fields), true); assert!(tmpl.renders_with_fields(&fields));
tmpl = PT::from_text("{{^1}}{{3}}{{/1}}").unwrap(); tmpl = PT::from_text("{{^1}}{{3}}{{/1}}").unwrap();
assert_eq!(tmpl.renders_with_fields(&fields), false); assert!(!tmpl.renders_with_fields(&fields));
assert_eq!(tmpl.renders_with_fields_for_reqs(&fields), true); assert!(tmpl.renders_with_fields_for_reqs(&fields));
} }
#[test] #[test]

View File

@ -359,7 +359,7 @@ pub(crate) fn to_custom_re<'a>(txt: &'a str, wildcard: &str) -> Cow<'a, str> {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"\\?.").unwrap(); static ref RE: Regex = Regex::new(r"\\?.").unwrap();
} }
RE.replace_all(&txt, |caps: &Captures| { RE.replace_all(txt, |caps: &Captures| {
let s = &caps[0]; let s = &caps[0];
match s { match s {
r"\\" | r"\*" => s.to_string(), r"\\" | r"\*" => s.to_string(),
@ -377,7 +377,7 @@ pub(crate) fn to_sql(txt: &str) -> Cow<str> {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"\\[\\*]|[*%]").unwrap(); static ref RE: Regex = Regex::new(r"\\[\\*]|[*%]").unwrap();
} }
RE.replace_all(&txt, |caps: &Captures| { RE.replace_all(txt, |caps: &Captures| {
let s = &caps[0]; let s = &caps[0];
match s { match s {
r"\\" => r"\\", r"\\" => r"\\",
@ -394,7 +394,7 @@ pub(crate) fn to_text(txt: &str) -> Cow<str> {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"\\(.)").unwrap(); static ref RE: Regex = Regex::new(r"\\(.)").unwrap();
} }
RE.replace_all(&txt, "$1") RE.replace_all(txt, "$1")
} }
/// Escape Anki wildcards and the backslash for escaping them: \*_ /// Escape Anki wildcards and the backslash for escaping them: \*_
@ -402,7 +402,7 @@ pub(crate) fn escape_anki_wildcards(txt: &str) -> String {
lazy_static! { lazy_static! {
static ref RE: Regex = Regex::new(r"[\\*_]").unwrap(); static ref RE: Regex = Regex::new(r"[\\*_]").unwrap();
} }
RE.replace_all(&txt, r"\$0").into() RE.replace_all(txt, r"\$0").into()
} }
/// Escape Anki wildcards unless it's _* /// Escape Anki wildcards unless it's _*

View File

@ -498,8 +498,8 @@ mod test {
// merge subsequent changes into our restore point // merge subsequent changes into our restore point
let op = col.merge_undoable_ops(restore_point)?; let op = col.merge_undoable_ops(restore_point)?;
assert_eq!(op.changes.card, true); assert!(op.changes.card);
assert_eq!(op.changes.config, true); assert!(op.changes.config);
// the last undo action should be at the end of the step list, // the last undo action should be at the end of the step list,
// before the modtime bump // before the modtime bump
@ -535,7 +535,7 @@ mod test {
col.storage.get_collection_timestamps()?.collection_change.0, col.storage.get_collection_timestamps()?.collection_change.0,
0 0
); );
assert_eq!(out.changes.had_change(), false); assert!(!out.changes.had_change());
// if there is an undoable step, mtime should change // if there is an undoable step, mtime should change
let out = col.set_config_bool(BoolKey::AddingDefaultsToCurrentDeck, false, true)?; let out = col.set_config_bool(BoolKey::AddingDefaultsToCurrentDeck, false, true)?;
@ -543,7 +543,7 @@ mod test {
col.storage.get_collection_timestamps()?.collection_change.0, col.storage.get_collection_timestamps()?.collection_change.0,
0 0
); );
assert_eq!(out.changes.had_change(), true); assert!(out.changes.had_change());
// when skipping undo, mtime should still only be bumped on a change // when skipping undo, mtime should still only be bumped on a change
col.storage.db.execute_batch("update col set mod = 0")?; col.storage.db.execute_batch("update col set mod = 0")?;
@ -552,7 +552,7 @@ mod test {
col.storage.get_collection_timestamps()?.collection_change.0, col.storage.get_collection_timestamps()?.collection_change.0,
0 0
); );
assert_eq!(out.changes.had_change(), false); assert!(!out.changes.had_change());
// op output won't reflect changes were made // op output won't reflect changes were made
let out = col.set_config_bool(BoolKey::AddingDefaultsToCurrentDeck, true, false)?; let out = col.set_config_bool(BoolKey::AddingDefaultsToCurrentDeck, true, false)?;
@ -560,7 +560,7 @@ mod test {
col.storage.get_collection_timestamps()?.collection_change.0, col.storage.get_collection_timestamps()?.collection_change.0,
0 0
); );
assert_eq!(out.changes.had_change(), false); assert!(!out.changes.had_change());
Ok(()) Ok(())
} }