mirror of
https://github.com/ankitects/anki.git
synced 2025-11-29 16:07:13 -05:00
* Add crate snafu * Replace all inline structs in AnkiError * Derive Snafu on AnkiError * Use snafu for card type errors * Use snafu whatever error for InvalidInput * Use snafu for NotFoundError and improve message * Use snafu for FileIoError to attach context Remove IoError. Add some context-attaching helpers to replace code returning bare io::Errors. * Add more context-attaching io helpers * Add message, context and backtrace to new snafus * Utilize error context and backtrace on frontend * Rename LocalizedError -> BackendError. * Remove DocumentedError. * Have all backend exceptions inherit BackendError. * Rename localized(_description) -> message * Remove accidentally committed experimental trait * invalid_input_context -> ok_or_invalid * ensure_valid_input! -> require! * Always return `Err` from `invalid_input!` Instead of a Result to unwrap, the macro accepts a source error now. * new_tempfile_in_parent -> new_tempfile_in_parent_of * ok_or_not_found -> or_not_found * ok_or_invalid -> or_invalid * Add crate convert_case * Use unqualified lowercase type name * Remove uses of snafu::ensure * Allow public construction of InvalidInputErrors (dae) Needed to port the AnkiDroid changes. * Make into_protobuf() public (dae) Also required for AnkiDroid. Not sure why it worked previously - possible bug in older Rust version?
129 lines
5.3 KiB
Rust
129 lines
5.3 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use serde_json::Value;
|
|
|
|
use super::Backend;
|
|
pub(super) use crate::pb::config_service::Service as ConfigService;
|
|
use crate::{
|
|
config::{BoolKey, StringKey},
|
|
pb,
|
|
pb::config_key::{Bool as BoolKeyProto, String as StringKeyProto},
|
|
prelude::*,
|
|
};
|
|
|
|
impl From<BoolKeyProto> for BoolKey {
|
|
fn from(k: BoolKeyProto) -> Self {
|
|
match k {
|
|
BoolKeyProto::BrowserTableShowNotesMode => BoolKey::BrowserTableShowNotesMode,
|
|
BoolKeyProto::PreviewBothSides => BoolKey::PreviewBothSides,
|
|
BoolKeyProto::CollapseTags => BoolKey::CollapseTags,
|
|
BoolKeyProto::CollapseNotetypes => BoolKey::CollapseNotetypes,
|
|
BoolKeyProto::CollapseDecks => BoolKey::CollapseDecks,
|
|
BoolKeyProto::CollapseSavedSearches => BoolKey::CollapseSavedSearches,
|
|
BoolKeyProto::CollapseToday => BoolKey::CollapseToday,
|
|
BoolKeyProto::CollapseCardState => BoolKey::CollapseCardState,
|
|
BoolKeyProto::CollapseFlags => BoolKey::CollapseFlags,
|
|
BoolKeyProto::Sched2021 => BoolKey::Sched2021,
|
|
BoolKeyProto::AddingDefaultsToCurrentDeck => BoolKey::AddingDefaultsToCurrentDeck,
|
|
BoolKeyProto::HideAudioPlayButtons => BoolKey::HideAudioPlayButtons,
|
|
BoolKeyProto::InterruptAudioWhenAnswering => BoolKey::InterruptAudioWhenAnswering,
|
|
BoolKeyProto::PasteImagesAsPng => BoolKey::PasteImagesAsPng,
|
|
BoolKeyProto::PasteStripsFormatting => BoolKey::PasteStripsFormatting,
|
|
BoolKeyProto::NormalizeNoteText => BoolKey::NormalizeNoteText,
|
|
BoolKeyProto::IgnoreAccentsInSearch => BoolKey::IgnoreAccentsInSearch,
|
|
BoolKeyProto::RestorePositionBrowser => BoolKey::RestorePositionBrowser,
|
|
BoolKeyProto::RestorePositionReviewer => BoolKey::RestorePositionReviewer,
|
|
BoolKeyProto::ResetCountsBrowser => BoolKey::ResetCountsBrowser,
|
|
BoolKeyProto::ResetCountsReviewer => BoolKey::ResetCountsReviewer,
|
|
BoolKeyProto::RandomOrderReposition => BoolKey::RandomOrderReposition,
|
|
BoolKeyProto::ShiftPositionOfExistingCards => BoolKey::ShiftPositionOfExistingCards,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<StringKeyProto> for StringKey {
|
|
fn from(k: StringKeyProto) -> Self {
|
|
match k {
|
|
StringKeyProto::SetDueBrowser => StringKey::SetDueBrowser,
|
|
StringKeyProto::SetDueReviewer => StringKey::SetDueReviewer,
|
|
StringKeyProto::DefaultSearchText => StringKey::DefaultSearchText,
|
|
StringKeyProto::CardStateCustomizer => StringKey::CardStateCustomizer,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ConfigService for Backend {
|
|
fn get_config_json(&self, input: pb::String) -> Result<pb::Json> {
|
|
self.with_col(|col| {
|
|
let val: Option<Value> = col.get_config_optional(input.val.as_str());
|
|
val.or_not_found(input.val)
|
|
.and_then(|v| serde_json::to_vec(&v).map_err(Into::into))
|
|
.map(Into::into)
|
|
})
|
|
}
|
|
|
|
fn set_config_json(&self, input: pb::SetConfigJsonRequest) -> Result<pb::OpChanges> {
|
|
self.with_col(|col| {
|
|
let val: Value = serde_json::from_slice(&input.value_json)?;
|
|
col.set_config_json(input.key.as_str(), &val, input.undoable)
|
|
})
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn set_config_json_no_undo(&self, input: pb::SetConfigJsonRequest) -> Result<pb::Empty> {
|
|
self.with_col(|col| {
|
|
let val: Value = serde_json::from_slice(&input.value_json)?;
|
|
col.transact_no_undo(|col| col.set_config(input.key.as_str(), &val).map(|_| ()))
|
|
})
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn remove_config(&self, input: pb::String) -> Result<pb::OpChanges> {
|
|
self.with_col(|col| col.remove_config(input.val.as_str()))
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_all_config(&self, _input: pb::Empty) -> Result<pb::Json> {
|
|
self.with_col(|col| {
|
|
let conf = col.storage.get_all_config()?;
|
|
serde_json::to_vec(&conf).map_err(Into::into)
|
|
})
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_config_bool(&self, input: pb::GetConfigBoolRequest) -> Result<pb::Bool> {
|
|
self.with_col(|col| {
|
|
Ok(pb::Bool {
|
|
val: col.get_config_bool(input.key().into()),
|
|
})
|
|
})
|
|
}
|
|
|
|
fn set_config_bool(&self, input: pb::SetConfigBoolRequest) -> Result<pb::OpChanges> {
|
|
self.with_col(|col| col.set_config_bool(input.key().into(), input.value, input.undoable))
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_config_string(&self, input: pb::GetConfigStringRequest) -> Result<pb::String> {
|
|
self.with_col(|col| {
|
|
Ok(pb::String {
|
|
val: col.get_config_string(input.key().into()),
|
|
})
|
|
})
|
|
}
|
|
|
|
fn set_config_string(&self, input: pb::SetConfigStringRequest) -> Result<pb::OpChanges> {
|
|
self.with_col(|col| col.set_config_string(input.key().into(), &input.value, input.undoable))
|
|
.map(Into::into)
|
|
}
|
|
|
|
fn get_preferences(&self, _input: pb::Empty) -> Result<pb::Preferences> {
|
|
self.with_col(|col| col.get_preferences())
|
|
}
|
|
|
|
fn set_preferences(&self, input: pb::Preferences) -> Result<pb::OpChanges> {
|
|
self.with_col(|col| col.set_preferences(input))
|
|
.map(Into::into)
|
|
}
|
|
}
|