mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Make some more fields/methods public
Continuation of https://github.com/ankitects/anki/issues/2494
This commit is contained in:
parent
c447999b4a
commit
ba6325b47f
12 changed files with 96 additions and 11 deletions
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(|_| ())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
Loading…
Reference in a new issue