Make some more fields/methods public

Continuation of https://github.com/ankitects/anki/issues/2494
This commit is contained in:
Damien Elmes 2023-06-20 21:59:49 +10:00
parent c447999b4a
commit ba6325b47f
12 changed files with 96 additions and 11 deletions

View file

@ -62,6 +62,15 @@ pub enum CardQueue {
UserBuried = -3, UserBuried = -3,
} }
/// Which of the blue/red/green numbers this card maps to.
pub enum CardQueueNumber {
New,
Learning,
Review,
/// Suspended/buried cards should not be included.
Invalid,
}
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Card { pub struct Card {
pub(crate) id: CardId, pub(crate) id: CardId,
@ -115,6 +124,33 @@ impl Default for Card {
} }
impl Card { impl Card {
pub fn id(&self) -> CardId {
self.id
}
pub fn note_id(&self) -> NoteId {
self.note_id
}
pub fn deck_id(&self) -> DeckId {
self.deck_id
}
pub fn template_idx(&self) -> u16 {
self.template_idx
}
pub fn queue_number(&self) -> CardQueueNumber {
match self.queue {
CardQueue::New => CardQueueNumber::New,
CardQueue::PreviewRepeat | CardQueue::Learn => CardQueueNumber::Learning,
CardQueue::DayLearn | CardQueue::Review => CardQueueNumber::Review,
CardQueue::Suspended | CardQueue::SchedBuried | CardQueue::UserBuried => {
CardQueueNumber::Invalid
}
}
}
pub fn set_modified(&mut self, usn: Usn) { pub fn set_modified(&mut self, usn: Usn) {
self.mtime = TimestampSecs::now(); self.mtime = TimestampSecs::now();
self.usn = usn; self.usn = usn;

View file

@ -220,4 +220,8 @@ impl Collection {
self.state.deck_cache.clear(); self.state.deck_cache.clear();
self.state.notetype_cache.clear(); self.state.notetype_cache.clear();
} }
pub fn tr(&self) -> &I18n {
&self.tr
}
} }

View file

@ -20,17 +20,21 @@ impl CollectionTimestamps {
} }
impl Collection { impl Collection {
pub(crate) fn set_modified(&mut self) -> Result<()> { /// This is done automatically when you call collection methods, so callers
/// outside this crate should only need this if you are manually
/// modifying the database.
pub fn set_modified(&mut self) -> Result<()> {
let stamps = self.storage.get_collection_timestamps()?; let stamps = self.storage.get_collection_timestamps()?;
self.set_modified_time_undoable(TimestampMillis::now(), stamps.collection_change) self.set_modified_time_undoable(TimestampMillis::now(), stamps.collection_change)
} }
pub(crate) fn set_schema_modified(&mut self) -> Result<()> { /// Forces the next sync in one direction.
pub fn set_schema_modified(&mut self) -> Result<()> {
let stamps = self.storage.get_collection_timestamps()?; let stamps = self.storage.get_collection_timestamps()?;
self.set_schema_modified_time_undoable(TimestampMillis::now(), stamps.schema_change) self.set_schema_modified_time_undoable(TimestampMillis::now(), stamps.schema_change)
} }
pub(crate) fn changed_since_last_backup(&self) -> Result<bool> { pub fn changed_since_last_backup(&self) -> Result<bool> {
let stamps = self.storage.get_collection_timestamps()?; let stamps = self.storage.get_collection_timestamps()?;
Ok(self Ok(self
.state .state

View file

@ -168,11 +168,13 @@ impl Collection {
} }
} }
pub(crate) fn get_configured_utc_offset(&self) -> Option<i32> { /// In minutes west of UTC.
pub fn get_configured_utc_offset(&self) -> Option<i32> {
self.get_config_optional(ConfigKey::LocalOffset) self.get_config_optional(ConfigKey::LocalOffset)
} }
pub(crate) fn set_configured_utc_offset(&mut self, mins: i32) -> Result<()> { /// In minutes west of UTC.
pub fn set_configured_utc_offset(&mut self, mins: i32) -> Result<()> {
self.state.scheduler_info = None; self.state.scheduler_info = None;
self.set_config(ConfigKey::LocalOffset, &mins).map(|_| ()) self.set_config(ConfigKey::LocalOffset, &mins).map(|_| ())
} }

View file

@ -80,7 +80,7 @@ impl Deck {
} }
/// Returns deck config ID if deck is a normal deck. /// Returns deck config ID if deck is a normal deck.
pub(crate) fn config_id(&self) -> Option<DeckConfigId> { pub fn config_id(&self) -> Option<DeckConfigId> {
if let DeckKind::Normal(ref norm) = self.kind { if let DeckKind::Normal(ref norm) = self.kind {
Some(DeckConfigId(norm.config_id)) Some(DeckConfigId(norm.config_id))
} else { } else {

View file

@ -117,7 +117,7 @@ impl NoteTags {
} }
impl Note { impl Note {
pub(crate) fn new(notetype: &Notetype) -> Self { pub fn new(notetype: &Notetype) -> Self {
Note { Note {
id: NoteId(0), id: NoteId(0),
guid: base91_u64(), guid: base91_u64(),
@ -156,7 +156,7 @@ impl Note {
} }
} }
pub(crate) fn fields_mut(&mut self) -> &mut Vec<String> { pub fn fields_mut(&mut self) -> &mut Vec<String> {
self.mark_dirty(); self.mark_dirty();
&mut self.fields &mut self.fields
} }

View file

@ -9,6 +9,7 @@ use super::Notetype;
use super::NotetypeKind; use super::NotetypeKind;
use crate::prelude::*; use crate::prelude::*;
use crate::template::field_is_empty; use crate::template::field_is_empty;
use crate::template::flatten_nodes;
use crate::template::render_card; use crate::template::render_card;
use crate::template::ParsedTemplate; use crate::template::ParsedTemplate;
use crate::template::RenderedNode; use crate::template::RenderedNode;
@ -20,6 +21,18 @@ pub struct RenderCardOutput {
pub latex_svg: bool, pub latex_svg: bool,
} }
impl RenderCardOutput {
/// The question text, ignoring any unknown field replacements.
pub fn question(&self) -> Cow<str> {
flatten_nodes(&self.qnodes)
}
/// The answer text, ignoring any unknown field replacements.
pub fn answer(&self) -> Cow<str> {
flatten_nodes(&self.anodes)
}
}
impl Collection { impl Collection {
/// Render an existing card saved in the database. /// Render an existing card saved in the database.
pub fn render_existing_card(&mut self, cid: CardId, browser: bool) -> Result<RenderCardOutput> { pub fn render_existing_card(&mut self, cid: CardId, browser: bool) -> Result<RenderCardOutput> {

View file

@ -196,7 +196,7 @@ impl Collection {
} }
/// Describe the next intervals, to display on the answer buttons. /// Describe the next intervals, to display on the answer buttons.
pub fn describe_next_states(&mut self, choices: SchedulingStates) -> Result<Vec<String>> { pub fn describe_next_states(&mut self, choices: &SchedulingStates) -> Result<Vec<String>> {
let collapse_time = self.learn_ahead_secs(); let collapse_time = self.learn_ahead_secs();
let now = TimestampSecs::now(); let now = TimestampSecs::now();
let timing = self.timing_for_timestamp(now)?; let timing = self.timing_for_timestamp(now)?;

View file

@ -198,7 +198,7 @@ impl crate::services::SchedulerService for Collection {
input: scheduler::SchedulingStates, input: scheduler::SchedulingStates,
) -> Result<generic::StringList> { ) -> Result<generic::StringList> {
let states: SchedulingStates = input.into(); let states: SchedulingStates = input.into();
self.describe_next_states(states).map(Into::into) self.describe_next_states(&states).map(Into::into)
} }
fn state_is_leech(&mut self, input: scheduler::SchedulingState) -> Result<generic::Bool> { fn state_is_leech(&mut self, input: scheduler::SchedulingState) -> Result<generic::Bool> {

View file

@ -34,7 +34,7 @@ impl SchemaVersion {
} }
/// Write a list of IDs as '(x,y,...)' into the provided string. /// Write a list of IDs as '(x,y,...)' into the provided string.
pub(crate) fn ids_to_string<D, I>(buf: &mut String, ids: I) pub fn ids_to_string<D, I>(buf: &mut String, ids: I)
where where
D: std::fmt::Display, D: std::fmt::Display,
I: IntoIterator<Item = D>, I: IntoIterator<Item = D>,

View file

@ -76,6 +76,14 @@ fn open_or_create_collection_db(path: &Path) -> Result<Connection> {
Ok(db) Ok(db)
} }
impl SqliteStorage {
/// This is provided as an escape hatch for when you need to do something
/// not directly supported by this library. Please exercise caution when
/// using it.
pub fn db(&self) -> &Connection {
&self.db
}
}
/// Adds sql function field_at_index(flds, index) /// Adds sql function field_at_index(flds, index)
/// to split provided fields and return field at zero-based index. /// to split provided fields and return field at zero-based index.
/// If out of range, returns empty string. /// If out of range, returns empty string.

View file

@ -529,6 +529,24 @@ fn append_str_to_nodes(nodes: &mut Vec<RenderedNode>, text: &str) {
} }
} }
/// Return the resolved text of a list of nodes, ignoring any unknown
/// filters that were encountered.
pub(crate) fn flatten_nodes(nodes: &[RenderedNode]) -> Cow<str> {
match nodes {
[RenderedNode::Text { text }] => text.into(),
nodes => {
let mut buf = String::new();
for node in nodes {
match node {
RenderedNode::Text { text } => buf.push_str(text),
RenderedNode::Replacement { current_text, .. } => buf.push_str(current_text),
}
}
buf.into()
}
}
}
/// True if provided text contains only whitespace and/or empty BR/DIV tags. /// True if provided text contains only whitespace and/or empty BR/DIV tags.
pub(crate) fn field_is_empty(text: &str) -> bool { pub(crate) fn field_is_empty(text: &str) -> bool {
lazy_static! { lazy_static! {