mirror of
https://github.com/ankitects/anki.git
synced 2026-01-12 21:44:01 -05:00
Merge branch 'main' into io-rotation-snap
This commit is contained in:
commit
3a734934f3
3 changed files with 39 additions and 22 deletions
2
.version
2
.version
|
|
@ -1 +1 @@
|
||||||
25.07.3rc1
|
25.07.3
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,7 @@ class Card(DeprecatedNamesMixin):
|
||||||
memory_state=self.memory_state,
|
memory_state=self.memory_state,
|
||||||
desired_retention=self.desired_retention,
|
desired_retention=self.desired_retention,
|
||||||
decay=self.decay,
|
decay=self.decay,
|
||||||
|
last_review_time_secs=self.last_review_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
@deprecated(info="please use col.update_card()")
|
@deprecated(info="please use col.update_card()")
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,20 @@ impl Collection {
|
||||||
.map(component_to_regex)
|
.map(component_to_regex)
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
let mut tags = vec![];
|
let mut tags = vec![];
|
||||||
|
let mut priority = vec![];
|
||||||
self.storage.get_tags_by_predicate(|tag| {
|
self.storage.get_tags_by_predicate(|tag| {
|
||||||
if tags.len() <= limit && filters_match(&filters, tag) {
|
if priority.len() + tags.len() <= limit {
|
||||||
tags.push(tag.to_string());
|
match filters_match(&filters, tag) {
|
||||||
|
Some(true) => priority.push(tag.to_string()),
|
||||||
|
Some(_) => tags.push(tag.to_string()),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// we only need the tag name
|
// we only need the tag name
|
||||||
false
|
false
|
||||||
})?;
|
})?;
|
||||||
Ok(tags)
|
priority.append(&mut tags);
|
||||||
|
Ok(priority)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,20 +33,26 @@ fn component_to_regex(component: &str) -> Result<Regex> {
|
||||||
Regex::new(&format!("(?i){}", regex::escape(component))).map_err(Into::into)
|
Regex::new(&format!("(?i){}", regex::escape(component))).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filters_match(filters: &[Regex], tag: &str) -> bool {
|
/// Returns None if tag wasn't a match, otherwise whether it was a consecutive
|
||||||
|
/// prefix match
|
||||||
|
fn filters_match(filters: &[Regex], tag: &str) -> Option<bool> {
|
||||||
let mut remaining_tag_components = tag.split("::");
|
let mut remaining_tag_components = tag.split("::");
|
||||||
|
let mut is_prefix = true;
|
||||||
'outer: for filter in filters {
|
'outer: for filter in filters {
|
||||||
loop {
|
loop {
|
||||||
if let Some(component) = remaining_tag_components.next() {
|
if let Some(component) = remaining_tag_components.next() {
|
||||||
if filter.is_match(component) {
|
if let Some(m) = filter.find(component) {
|
||||||
|
is_prefix &= m.start() == 0;
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
|
} else {
|
||||||
|
is_prefix = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
Some(is_prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -50,28 +62,32 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn matching() -> Result<()> {
|
fn matching() -> Result<()> {
|
||||||
let filters = &[component_to_regex("b")?];
|
let filters = &[component_to_regex("b")?];
|
||||||
assert!(filters_match(filters, "ABC"));
|
assert!(filters_match(filters, "ABC").is_some());
|
||||||
assert!(filters_match(filters, "ABC::def"));
|
assert!(filters_match(filters, "ABC::def").is_some());
|
||||||
assert!(filters_match(filters, "def::abc"));
|
assert!(filters_match(filters, "def::abc").is_some());
|
||||||
assert!(!filters_match(filters, "def"));
|
assert!(filters_match(filters, "def").is_none());
|
||||||
|
|
||||||
let filters = &[component_to_regex("b")?, component_to_regex("E")?];
|
let filters = &[component_to_regex("b")?, component_to_regex("E")?];
|
||||||
assert!(!filters_match(filters, "ABC"));
|
assert!(filters_match(filters, "ABC").is_none());
|
||||||
assert!(filters_match(filters, "ABC::def"));
|
assert!(filters_match(filters, "ABC::def").is_some());
|
||||||
assert!(!filters_match(filters, "def::abc"));
|
assert!(filters_match(filters, "def::abc").is_none());
|
||||||
assert!(!filters_match(filters, "def"));
|
assert!(filters_match(filters, "def").is_none());
|
||||||
|
|
||||||
let filters = &[
|
let filters = &[
|
||||||
component_to_regex("a")?,
|
component_to_regex("a")?,
|
||||||
component_to_regex("c")?,
|
component_to_regex("c")?,
|
||||||
component_to_regex("e")?,
|
component_to_regex("e")?,
|
||||||
];
|
];
|
||||||
assert!(!filters_match(filters, "ace"));
|
assert!(filters_match(filters, "ace").is_none());
|
||||||
assert!(!filters_match(filters, "a::c"));
|
assert!(filters_match(filters, "a::c").is_none());
|
||||||
assert!(!filters_match(filters, "c::e"));
|
assert!(filters_match(filters, "c::e").is_none());
|
||||||
assert!(filters_match(filters, "a::c::e"));
|
assert!(filters_match(filters, "a::c::e").is_some());
|
||||||
assert!(filters_match(filters, "a::b::c::d::e"));
|
assert!(filters_match(filters, "a::b::c::d::e").is_some());
|
||||||
assert!(filters_match(filters, "1::a::b::c::d::e::f"));
|
assert!(filters_match(filters, "1::a::b::c::d::e::f").is_some());
|
||||||
|
|
||||||
|
assert_eq!(filters_match(filters, "a1::c2::e3"), Some(true));
|
||||||
|
assert_eq!(filters_match(filters, "a1::c2::?::e4"), Some(false));
|
||||||
|
assert_eq!(filters_match(filters, "a1::c2::3e"), Some(false));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue