diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index 2fe324c77..39aea4675 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -33,7 +33,8 @@ use crate::{ sched::cutoff::local_minutes_west_for_stamp, sched::timespan::{answer_button_time, time_span}, search::{ - concatenate_searches, negate_search, normalize_search, replace_search_term, SortMode, + concatenate_searches, negate_search, normalize_search, replace_search_term, BoolSeparator, + SortMode, }, stats::studied_today, sync::{ @@ -273,6 +274,17 @@ impl From for DeckConfID { } } +impl From for BoolSeparator { + fn from(sep: i32) -> Self { + use pb::concatenate_searches_in::Separator; + match Separator::from_i32(sep) { + Some(Separator::And) => BoolSeparator::And, + Some(Separator::Or) => BoolSeparator::Or, + None => BoolSeparator::And, + } + } +} + impl BackendService for Backend { fn latest_progress(&self, _input: Empty) -> BackendResult { let progress = self.progress_state.lock().unwrap().last_progress; @@ -437,7 +449,7 @@ impl BackendService for Backend { } fn concatenate_searches(&self, input: pb::ConcatenateSearchesIn) -> Result { - Ok(concatenate_searches(input.sep, &input.searches)?.into()) + Ok(concatenate_searches(input.sep.into(), &input.searches)?.into()) } fn replace_search_term(&self, input: pb::ReplaceSearchTermIn) -> Result { diff --git a/rslib/src/search/mod.rs b/rslib/src/search/mod.rs index aed103b4d..607b9d767 100644 --- a/rslib/src/search/mod.rs +++ b/rslib/src/search/mod.rs @@ -5,4 +5,6 @@ mod sqlwriter; mod writer; pub use cards::SortMode; -pub use writer::{concatenate_searches, negate_search, normalize_search, replace_search_term}; +pub use writer::{ + concatenate_searches, negate_search, normalize_search, replace_search_term, BoolSeparator, +}; diff --git a/rslib/src/search/writer.rs b/rslib/src/search/writer.rs index 2867a64b8..ec7051893 100644 --- a/rslib/src/search/writer.rs +++ b/rslib/src/search/writer.rs @@ -2,15 +2,20 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use crate::{ - backend_proto::concatenate_searches_in::Separator, decks::DeckID as DeckIDType, - err::{AnkiError, Result}, + err::Result, notetype::NoteTypeID as NoteTypeIDType, search::parser::{parse, Node, PropertyKind, SearchNode, StateKind, TemplateKind}, }; use itertools::Itertools; use std::mem; +#[derive(Debug, PartialEq)] +pub enum BoolSeparator { + And, + Or, +} + /// Take an Anki-style search string and convert it into an equivalent /// search string with normalized syntax. pub fn normalize_search(input: &str) -> Result { @@ -38,11 +43,10 @@ pub fn negate_search(input: &str) -> Result { /// Take arbitrary Anki-style search strings and return their concatenation where they /// are separated by the provided boolean operator. /// Empty searches (whole collection) are left out. -pub fn concatenate_searches(sep: i32, searches: &[String]) -> Result { - let bool_node = vec![match Separator::from_i32(sep) { - Some(Separator::Or) => Node::Or, - Some(Separator::And) => Node::And, - None => return Err(AnkiError::SearchError(None)), +pub fn concatenate_searches(sep: BoolSeparator, searches: &[String]) -> Result { + let bool_node = vec![match sep { + BoolSeparator::And => Node::And, + BoolSeparator::Or => Node::Or, }]; Ok(write_nodes( searches @@ -221,25 +225,22 @@ mod test { fn concatenating() -> Result<()> { assert_eq!( r#""foo" AND "bar""#, - concatenate_searches( - Separator::And as i32, - &["foo".to_string(), "bar".to_string()] - ) - .unwrap() + concatenate_searches(BoolSeparator::And, &["foo".to_string(), "bar".to_string()]) + .unwrap() ); assert_eq!( r#""foo" OR "bar""#, concatenate_searches( - Separator::Or as i32, + BoolSeparator::Or, &["foo".to_string(), "".to_string(), "bar".to_string()] ) .unwrap() ); assert_eq!( "", - concatenate_searches(Separator::Or as i32, &["".to_string()]).unwrap() + concatenate_searches(BoolSeparator::Or, &["".to_string()]).unwrap() ); - assert_eq!("", concatenate_searches(Separator::Or as i32, &[]).unwrap()); + assert_eq!("", concatenate_searches(BoolSeparator::Or, &[]).unwrap()); Ok(()) }