diff --git a/rslib/backend.proto b/rslib/backend.proto index fbe7ea66b..8b37fbda8 100644 --- a/rslib/backend.proto +++ b/rslib/backend.proto @@ -108,7 +108,6 @@ enum ServiceIndex { SERVICE_INDEX_I18N = 12; SERVICE_INDEX_COLLECTION = 13; SERVICE_INDEX_CARDS = 14; - SERVICE_INDEX_BROWSER_ROWS = 15; } service SchedulingService { @@ -241,6 +240,7 @@ service SearchService { rpc JoinSearchNodes(JoinSearchNodesIn) returns (String); rpc ReplaceSearchNode(ReplaceSearchNodeIn) returns (String); rpc FindAndReplace(FindAndReplaceIn) returns (OpChangesWithCount); + rpc BrowserRowForCard(CardID) returns (BrowserRow); } service StatsService { @@ -283,10 +283,6 @@ service CardsService { rpc SetFlag(SetFlagIn) returns (OpChanges); } -service BrowserRowsService { - rpc BrowserRowForCard(CardID) returns (BrowserRow); -} - // Protobuf stored in .anki2 files // These should be moved to a separate file in the future /////////////////////////////////////////////////////////// diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index aacdbc8d1..7c1521260 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -2,7 +2,6 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html mod adding; -mod browser_rows; mod card; mod cardrendering; mod collection; @@ -25,7 +24,6 @@ mod sync; mod tags; use self::{ - browser_rows::BrowserRowsService, card::CardsService, cardrendering::CardRenderingService, collection::CollectionService, @@ -139,9 +137,6 @@ impl Backend { pb::ServiceIndex::I18n => I18nService::run_method(self, method, input), pb::ServiceIndex::Collection => CollectionService::run_method(self, method, input), pb::ServiceIndex::Cards => CardsService::run_method(self, method, input), - pb::ServiceIndex::BrowserRows => { - BrowserRowsService::run_method(self, method, input) - } }) .map_err(|err| { let backend_err = anki_error_to_proto_error(err, &self.i18n); diff --git a/rslib/src/backend/browser_rows.rs b/rslib/src/backend/search/browser_row.rs similarity index 79% rename from rslib/src/backend/browser_rows.rs rename to rslib/src/backend/search/browser_row.rs index 42ddb0967..d985cabb3 100644 --- a/rslib/src/backend/browser_rows.rs +++ b/rslib/src/backend/search/browser_row.rs @@ -1,15 +1,7 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::Backend; -use crate::{backend_proto as pb, browser_rows, prelude::*}; -pub(super) use pb::browserrows_service::Service as BrowserRowsService; - -impl BrowserRowsService for Backend { - fn browser_row_for_card(&self, input: pb::CardId) -> Result { - self.with_col(|col| col.browser_row_for_card(input.cid.into()).map(Into::into)) - } -} +use crate::{backend_proto as pb, browser_rows}; impl From for pb::BrowserRow { fn from(row: browser_rows::Row) -> Self { diff --git a/rslib/src/backend/search/mod.rs b/rslib/src/backend/search/mod.rs new file mode 100644 index 000000000..e52948567 --- /dev/null +++ b/rslib/src/backend/search/mod.rs @@ -0,0 +1,129 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +mod browser_row; +mod search_node; + +use std::convert::TryInto; + +use super::Backend; +use crate::{ + backend_proto as pb, + backend_proto::{ + sort_order::builtin::Kind as SortKindProto, sort_order::Value as SortOrderProto, + }, + config::SortKind, + prelude::*, + search::{concatenate_searches, replace_search_node, write_nodes, Node, SortMode}, +}; +pub(super) use pb::search_service::Service as SearchService; + +impl SearchService for Backend { + fn build_search_string(&self, input: pb::SearchNode) -> Result { + let node: Node = input.try_into()?; + Ok(write_nodes(&node.into_node_list()).into()) + } + + fn search_cards(&self, input: pb::SearchCardsIn) -> Result { + self.with_col(|col| { + let order = input.order.unwrap_or_default().value.into(); + let cids = col.search_cards(&input.search, order)?; + Ok(pb::SearchCardsOut { + card_ids: cids.into_iter().map(|v| v.0).collect(), + }) + }) + } + + fn search_notes(&self, input: pb::SearchNotesIn) -> Result { + self.with_col(|col| { + let nids = col.search_notes(&input.search)?; + Ok(pb::SearchNotesOut { + note_ids: nids.into_iter().map(|v| v.0).collect(), + }) + }) + } + + fn join_search_nodes(&self, input: pb::JoinSearchNodesIn) -> Result { + let sep = input.joiner().into(); + let existing_nodes = { + let node: Node = input.existing_node.unwrap_or_default().try_into()?; + node.into_node_list() + }; + let additional_node = input.additional_node.unwrap_or_default().try_into()?; + Ok(concatenate_searches(sep, existing_nodes, additional_node).into()) + } + + fn replace_search_node(&self, input: pb::ReplaceSearchNodeIn) -> Result { + let existing = { + let node = input.existing_node.unwrap_or_default().try_into()?; + if let Node::Group(nodes) = node { + nodes + } else { + vec![node] + } + }; + let replacement = input.replacement_node.unwrap_or_default().try_into()?; + Ok(replace_search_node(existing, replacement).into()) + } + + fn find_and_replace(&self, input: pb::FindAndReplaceIn) -> Result { + let mut search = if input.regex { + input.search + } else { + regex::escape(&input.search) + }; + if !input.match_case { + search = format!("(?i){}", search); + } + let nids = input.nids.into_iter().map(NoteID).collect(); + let field_name = if input.field_name.is_empty() { + None + } else { + Some(input.field_name) + }; + let repl = input.replacement; + self.with_col(|col| { + col.find_and_replace(nids, &search, &repl, field_name) + .map(Into::into) + }) + } + + fn browser_row_for_card(&self, input: pb::CardId) -> Result { + self.with_col(|col| col.browser_row_for_card(input.cid.into()).map(Into::into)) + } +} + +impl From for SortKind { + fn from(kind: SortKindProto) -> Self { + match kind { + SortKindProto::NoteCreation => SortKind::NoteCreation, + SortKindProto::NoteMod => SortKind::NoteMod, + SortKindProto::NoteField => SortKind::NoteField, + SortKindProto::NoteTags => SortKind::NoteTags, + SortKindProto::NoteType => SortKind::NoteType, + SortKindProto::CardMod => SortKind::CardMod, + SortKindProto::CardReps => SortKind::CardReps, + SortKindProto::CardDue => SortKind::CardDue, + SortKindProto::CardEase => SortKind::CardEase, + SortKindProto::CardLapses => SortKind::CardLapses, + SortKindProto::CardInterval => SortKind::CardInterval, + SortKindProto::CardDeck => SortKind::CardDeck, + SortKindProto::CardTemplate => SortKind::CardTemplate, + } + } +} + +impl From> for SortMode { + fn from(order: Option) -> Self { + use pb::sort_order::Value as V; + match order.unwrap_or(V::FromConfig(pb::Empty {})) { + V::None(_) => SortMode::NoOrder, + V::Custom(s) => SortMode::Custom(s), + V::FromConfig(_) => SortMode::FromConfig, + V::Builtin(b) => SortMode::Builtin { + kind: b.kind().into(), + reverse: b.reverse, + }, + } + } +} diff --git a/rslib/src/backend/search.rs b/rslib/src/backend/search/search_node.rs similarity index 59% rename from rslib/src/backend/search.rs rename to rslib/src/backend/search/search_node.rs index ed4c7d497..991487478 100644 --- a/rslib/src/backend/search.rs +++ b/rslib/src/backend/search/search_node.rs @@ -4,92 +4,15 @@ use itertools::Itertools; use std::convert::{TryFrom, TryInto}; -use super::Backend; use crate::{ backend_proto as pb, - backend_proto::{ - sort_order::builtin::Kind as SortKindProto, sort_order::Value as SortOrderProto, - }, - config::SortKind, prelude::*, search::{ - concatenate_searches, parse_search, replace_search_node, write_nodes, BoolSeparator, Node, - PropertyKind, RatingKind, SearchNode, SortMode, StateKind, TemplateKind, + parse_search, BoolSeparator, Node, PropertyKind, RatingKind, SearchNode, StateKind, + TemplateKind, }, text::escape_anki_wildcards, }; -pub(super) use pb::search_service::Service as SearchService; - -impl SearchService for Backend { - fn build_search_string(&self, input: pb::SearchNode) -> Result { - let node: Node = input.try_into()?; - Ok(write_nodes(&node.into_node_list()).into()) - } - - fn search_cards(&self, input: pb::SearchCardsIn) -> Result { - self.with_col(|col| { - let order = input.order.unwrap_or_default().value.into(); - let cids = col.search_cards(&input.search, order)?; - Ok(pb::SearchCardsOut { - card_ids: cids.into_iter().map(|v| v.0).collect(), - }) - }) - } - - fn search_notes(&self, input: pb::SearchNotesIn) -> Result { - self.with_col(|col| { - let nids = col.search_notes(&input.search)?; - Ok(pb::SearchNotesOut { - note_ids: nids.into_iter().map(|v| v.0).collect(), - }) - }) - } - - fn join_search_nodes(&self, input: pb::JoinSearchNodesIn) -> Result { - let sep = input.joiner().into(); - let existing_nodes = { - let node: Node = input.existing_node.unwrap_or_default().try_into()?; - node.into_node_list() - }; - let additional_node = input.additional_node.unwrap_or_default().try_into()?; - Ok(concatenate_searches(sep, existing_nodes, additional_node).into()) - } - - fn replace_search_node(&self, input: pb::ReplaceSearchNodeIn) -> Result { - let existing = { - let node = input.existing_node.unwrap_or_default().try_into()?; - if let Node::Group(nodes) = node { - nodes - } else { - vec![node] - } - }; - let replacement = input.replacement_node.unwrap_or_default().try_into()?; - Ok(replace_search_node(existing, replacement).into()) - } - - fn find_and_replace(&self, input: pb::FindAndReplaceIn) -> Result { - let mut search = if input.regex { - input.search - } else { - regex::escape(&input.search) - }; - if !input.match_case { - search = format!("(?i){}", search); - } - let nids = input.nids.into_iter().map(NoteID).collect(); - let field_name = if input.field_name.is_empty() { - None - } else { - Some(input.field_name) - }; - let repl = input.replacement; - self.with_col(|col| { - col.find_and_replace(nids, &search, &repl, field_name) - .map(Into::into) - }) - } -} impl TryFrom for Node { type Error = AnkiError; @@ -229,38 +152,3 @@ impl pb::search_node::IdList { .join(",") } } - -impl From for SortKind { - fn from(kind: SortKindProto) -> Self { - match kind { - SortKindProto::NoteCreation => SortKind::NoteCreation, - SortKindProto::NoteMod => SortKind::NoteMod, - SortKindProto::NoteField => SortKind::NoteField, - SortKindProto::NoteTags => SortKind::NoteTags, - SortKindProto::NoteType => SortKind::NoteType, - SortKindProto::CardMod => SortKind::CardMod, - SortKindProto::CardReps => SortKind::CardReps, - SortKindProto::CardDue => SortKind::CardDue, - SortKindProto::CardEase => SortKind::CardEase, - SortKindProto::CardLapses => SortKind::CardLapses, - SortKindProto::CardInterval => SortKind::CardInterval, - SortKindProto::CardDeck => SortKind::CardDeck, - SortKindProto::CardTemplate => SortKind::CardTemplate, - } - } -} - -impl From> for SortMode { - fn from(order: Option) -> Self { - use pb::sort_order::Value as V; - match order.unwrap_or(V::FromConfig(pb::Empty {})) { - V::None(_) => SortMode::NoOrder, - V::Custom(s) => SortMode::Custom(s), - V::FromConfig(_) => SortMode::FromConfig, - V::Builtin(b) => SortMode::Builtin { - kind: b.kind().into(), - reverse: b.reverse, - }, - } - } -}