Modify default behavior of rated searches to exclude manual

This commit is contained in:
Henrik Giesel 2021-01-09 14:04:57 +01:00
parent 5f02be4943
commit 7e58660aab
3 changed files with 41 additions and 21 deletions

View file

@ -69,7 +69,7 @@ pub enum SearchNode<'a> {
NoteType(Cow<'a, str>), NoteType(Cow<'a, str>),
Rated { Rated {
days: u32, days: u32,
ease: Option<u8>, ease: EaseKind,
}, },
Tag(Cow<'a, str>), Tag(Cow<'a, str>),
Duplicates { Duplicates {
@ -118,6 +118,25 @@ pub enum TemplateKind<'a> {
Name(Cow<'a, str>), Name(Cow<'a, str>),
} }
#[derive(Debug, PartialEq, Clone)]
pub(super) enum EaseKind {
Rated(u8),
Reviewed,
All,
}
impl std::fmt::Display for EaseKind {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use EaseKind::*;
match self {
Rated(u) => write!(f, " and ease = {}", u),
Reviewed => write!(f, " and ease in (1, 2, 3, 4)"),
All => write!(f, ""),
}
}
}
/// Parse the input string into a list of nodes. /// Parse the input string into a list of nodes.
pub(super) fn parse(input: &str) -> Result<Vec<Node>> { pub(super) fn parse(input: &str) -> Result<Vec<Node>> {
let input = input.trim(); let input = input.trim();
@ -359,14 +378,17 @@ fn parse_rated(val: &str) -> ParseResult<SearchNode<'static>> {
let ease = match it.next() { let ease = match it.next() {
Some(v) => { Some(v) => {
let n: u8 = v.parse()?; let c: char = v.parse().unwrap();
if n < 5 { match c {
Some(n) '0' | '1' | '2' | '3' | '4' => {
} else { let n = c.to_digit(10).unwrap() as u8;
return Err(ParseError {}); EaseKind::Rated(n)
}
'a' => EaseKind::All,
_ => return Err(ParseError {}),
} }
} }
None => None, None => EaseKind::Reviewed,
}; };
Ok(SearchNode::Rated { days, ease }) Ok(SearchNode::Rated { days, ease })

View file

@ -1,7 +1,7 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use super::parser::{Node, PropertyKind, SearchNode, StateKind, TemplateKind}; use super::parser::{Node, PropertyKind, SearchNode, StateKind, TemplateKind, EaseKind};
use crate::{ use crate::{
card::{CardQueue, CardType}, card::{CardQueue, CardType},
collection::Collection, collection::Collection,
@ -144,7 +144,7 @@ impl SqlWriter<'_> {
write!(self.sql, "c.did = {}", did).unwrap(); write!(self.sql, "c.did = {}", did).unwrap();
} }
SearchNode::NoteType(notetype) => self.write_note_type(&norm(notetype))?, SearchNode::NoteType(notetype) => self.write_note_type(&norm(notetype))?,
SearchNode::Rated { days, ease } => self.write_rated(*days, *ease)?, SearchNode::Rated { days, ease } => self.write_rated(*days, ease)?,
SearchNode::Tag(tag) => self.write_tag(&norm(tag))?, SearchNode::Tag(tag) => self.write_tag(&norm(tag))?,
SearchNode::State(state) => self.write_state(state)?, SearchNode::State(state) => self.write_state(state)?,
@ -214,20 +214,16 @@ impl SqlWriter<'_> {
Ok(()) Ok(())
} }
fn write_rated(&mut self, days: u32, ease: Option<u8>) -> Result<()> { fn write_rated(&mut self, days: u32, ease: &EaseKind) -> Result<()> {
let today_cutoff = self.col.timing_today()?.next_day_at; let today_cutoff = self.col.timing_today()?.next_day_at;
let target_cutoff_ms = (today_cutoff - 86_400 * i64::from(days)) * 1_000; let target_cutoff_ms = (today_cutoff - 86_400 * i64::from(days)) * 1_000;
write!( write!(
self.sql, self.sql,
"c.id in (select cid from revlog where id>{}", "c.id in (select cid from revlog where id>{}{})",
target_cutoff_ms target_cutoff_ms,
ease,
) )
.unwrap(); .unwrap();
if let Some(ease) = ease {
write!(self.sql, " and ease={})", ease).unwrap();
} else {
write!(self.sql, ")").unwrap();
}
Ok(()) Ok(())
} }

View file

@ -5,7 +5,7 @@ use crate::{
decks::DeckID as DeckIDType, decks::DeckID as DeckIDType,
err::Result, err::Result,
notetype::NoteTypeID as NoteTypeIDType, notetype::NoteTypeID as NoteTypeIDType,
search::parser::{parse, Node, PropertyKind, SearchNode, StateKind, TemplateKind}, search::parser::{parse, Node, PropertyKind, SearchNode, StateKind, TemplateKind, EaseKind},
}; };
use itertools::Itertools; use itertools::Itertools;
use std::mem; use std::mem;
@ -154,10 +154,12 @@ fn write_template(template: &TemplateKind) -> String {
} }
} }
fn write_rated(days: &u32, ease: &Option<u8>) -> String { fn write_rated(days: &u32, ease: &EaseKind) -> String {
use EaseKind::*;
match ease { match ease {
Some(u) => format!("\"rated:{}:{}\"", days, u), Rated(n) => format!("\"rated:{}:{}\"", days, n),
None => format!("\"rated:{}\"", days), Reviewed => format!("\"rated:{}\"", days),
All => format!("\"rated:{}:a\"", days),
} }
} }