From ded805b5046e2df849103022747b94ce289bed46 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 18 Jan 2023 21:39:55 +1000 Subject: [PATCH] Switch Rust import style (#2330) * Prepare to switch Rust import style * Run nightly format Closes #2320 * Clean up a few imports * Enable comment wrapping * Wrap comments --- .rustfmt.toml | 13 ++-- build/archives/src/main.rs | 7 +- build/configure/src/aqt.rs | 37 +++++---- build/configure/src/bundle.rs | 33 ++++---- build/configure/src/main.rs | 17 ++-- build/configure/src/platform.rs | 8 +- build/configure/src/proto.rs | 15 ++-- build/configure/src/pylib.rs | 27 +++---- build/configure/src/python.rs | 34 ++++---- build/configure/src/rust.rs | 19 +++-- build/configure/src/web.rs | 32 ++++---- build/ninja_gen/src/action.rs | 13 ++-- build/ninja_gen/src/archives.rs | 33 ++++---- build/ninja_gen/src/build.rs | 48 ++++++------ build/ninja_gen/src/cargo.rs | 18 +++-- build/ninja_gen/src/command.rs | 14 ++-- build/ninja_gen/src/configure.rs | 14 ++-- build/ninja_gen/src/copy.rs | 11 ++- build/ninja_gen/src/git.rs | 3 +- build/ninja_gen/src/hash.rs | 7 +- build/ninja_gen/src/input.rs | 6 +- build/ninja_gen/src/lib.rs | 3 +- build/ninja_gen/src/node.rs | 16 ++-- build/ninja_gen/src/protobuf.rs | 15 ++-- build/ninja_gen/src/python.rs | 7 +- build/ninja_gen/src/render.rs | 7 +- build/ninja_gen/src/rsync.rs | 18 ++--- build/ninja_gen/src/sass.rs | 13 ++-- build/runner/src/build.rs | 22 ++++-- build/runner/src/bundle/artifacts.rs | 8 +- build/runner/src/bundle/folder.rs | 21 ++--- build/runner/src/main.rs | 29 ++++--- build/runner/src/paths.rs | 4 +- build/runner/src/pyenv.rs | 7 +- build/runner/src/rsync.rs | 3 +- build/runner/src/run.rs | 7 +- build/runner/src/yarn.rs | 14 ++-- ftl/sync.rs | 3 +- pylib/rsbridge/lib.rs | 17 ++-- qt/bundle/mac/src/codesign.rs | 9 ++- qt/bundle/mac/src/dmg.rs | 9 ++- qt/bundle/mac/src/main.rs | 21 +++-- qt/bundle/mac/src/notarize.rs | 8 +- qt/bundle/win/src/main.rs | 17 +++- rslib/benches/benchmark.rs | 4 +- rslib/build/protobuf.rs | 4 +- rslib/i18n/build/check.rs | 6 +- rslib/i18n/build/extract.rs | 16 ++-- rslib/i18n/build/gather.rs | 17 ++-- rslib/i18n/build/write_strings.rs | 13 ++-- rslib/i18n/src/lib.rs | 18 +++-- rslib/i18n_helpers/src/garbage_collection.rs | 17 ++-- rslib/i18n_helpers/src/serialize.rs | 9 ++- rslib/linkchecker/tests/links.rs | 14 ++-- rslib/src/adding.rs | 15 ++-- rslib/src/backend/adding.rs | 3 +- rslib/src/backend/ankidroid/db.rs | 60 ++++++++------- rslib/src/backend/ankidroid/error.rs | 18 +++-- rslib/src/backend/ankidroid/mod.rs | 34 ++++---- rslib/src/backend/card.rs | 9 +-- rslib/src/backend/cardrendering.rs | 31 ++++---- rslib/src/backend/collection.rs | 12 +-- rslib/src/backend/config.rs | 12 +-- rslib/src/backend/dbproxy.rs | 31 ++++---- rslib/src/backend/deckconfig.rs | 10 +-- rslib/src/backend/decks.rs | 11 ++- rslib/src/backend/error.rs | 11 ++- rslib/src/backend/generic.rs | 3 +- rslib/src/backend/i18n.rs | 12 +-- rslib/src/backend/import_export.rs | 19 +++-- rslib/src/backend/links.rs | 4 +- rslib/src/backend/media.rs | 7 +- rslib/src/backend/mod.rs | 58 +++++++------- rslib/src/backend/notes.rs | 4 +- rslib/src/backend/notetypes.rs | 16 ++-- rslib/src/backend/ops.rs | 11 ++- rslib/src/backend/progress.rs | 25 +++--- rslib/src/backend/scheduler/answering.rs | 14 ++-- rslib/src/backend/scheduler/mod.rs | 19 ++--- .../src/backend/scheduler/states/filtered.rs | 3 +- .../src/backend/scheduler/states/learning.rs | 3 +- rslib/src/backend/scheduler/states/mod.rs | 9 ++- rslib/src/backend/scheduler/states/new.rs | 3 +- rslib/src/backend/scheduler/states/normal.rs | 3 +- rslib/src/backend/scheduler/states/preview.rs | 3 +- .../backend/scheduler/states/relearning.rs | 3 +- .../backend/scheduler/states/rescheduling.rs | 3 +- rslib/src/backend/scheduler/states/review.rs | 3 +- rslib/src/backend/search/browser_table.rs | 4 +- rslib/src/backend/search/mod.rs | 21 ++--- rslib/src/backend/search/search_node.rs | 24 +++--- rslib/src/backend/stats.rs | 4 +- rslib/src/backend/sync/mod.rs | 39 +++++----- rslib/src/backend/tags.rs | 6 +- rslib/src/browser_table.rs | 43 ++++++----- rslib/src/card/mod.rs | 50 ++++++------ rslib/src/card_rendering/mod.rs | 6 +- rslib/src/card_rendering/parser.rs | 41 +++++++--- rslib/src/card_rendering/writer.rs | 15 ++-- rslib/src/cloze.rs | 22 +++--- rslib/src/collection/backup.rs | 29 +++---- rslib/src/collection/mod.rs | 44 ++++++----- rslib/src/collection/transact.rs | 3 +- rslib/src/config/mod.rs | 21 +++-- rslib/src/config/notetype.rs | 3 +- rslib/src/dbcheck.rs | 39 ++++++---- rslib/src/deckconfig/mod.rs | 21 ++--- rslib/src/deckconfig/schema11.rs | 24 ++++-- rslib/src/deckconfig/update.rs | 45 +++++------ rslib/src/decks/addupdate.rs | 10 ++- rslib/src/decks/counts.rs | 3 +- rslib/src/decks/current.rs | 3 +- rslib/src/decks/filtered.rs | 5 +- rslib/src/decks/limits.rs | 29 ++++--- rslib/src/decks/mod.rs | 30 ++++---- rslib/src/decks/name.rs | 14 ++-- rslib/src/decks/reparent.rs | 3 +- rslib/src/decks/schema11.rs | 35 +++++---- rslib/src/decks/stats.rs | 3 +- rslib/src/decks/tree.rs | 31 ++++---- rslib/src/decks/undo.rs | 6 +- rslib/src/error/db.rs | 3 +- rslib/src/error/invalid_input.rs | 5 +- rslib/src/error/mod.rs | 29 ++++--- rslib/src/error/network.rs | 7 +- rslib/src/error/not_found.rs | 10 ++- rslib/src/error/search.rs | 3 +- rslib/src/findreplace.rs | 16 ++-- rslib/src/import_export/gather.rs | 32 ++++---- rslib/src/import_export/insert.rs | 3 +- rslib/src/import_export/mod.rs | 22 +++--- .../src/import_export/package/apkg/export.rs | 31 ++++---- .../package/apkg/import/cards.rs | 21 +++-- .../package/apkg/import/decks.rs | 9 ++- .../package/apkg/import/media.rs | 29 +++---- .../import_export/package/apkg/import/mod.rs | 28 ++++--- .../package/apkg/import/notes.rs | 40 +++++----- rslib/src/import_export/package/apkg/tests.rs | 15 ++-- .../import_export/package/colpkg/export.rs | 59 ++++++++------ .../import_export/package/colpkg/import.rs | 45 +++++------ .../src/import_export/package/colpkg/tests.rs | 14 ++-- rslib/src/import_export/package/media.rs | 38 +++++---- rslib/src/import_export/package/meta.rs | 14 +++- rslib/src/import_export/package/mod.rs | 6 +- rslib/src/import_export/text/csv/export.rs | 25 +++--- rslib/src/import_export/text/csv/import.rs | 35 +++++---- rslib/src/import_export/text/csv/metadata.rs | 45 ++++++----- rslib/src/import_export/text/import.rs | 46 ++++++----- rslib/src/import_export/text/json.rs | 10 +-- rslib/src/import_export/text/mod.rs | 3 +- rslib/src/io.rs | 15 ++-- rslib/src/latex.rs | 10 ++- rslib/src/log.rs | 16 ++-- rslib/src/markdown.rs | 3 +- rslib/src/media/check.rs | 70 +++++++++-------- rslib/src/media/files.rs | 52 +++++++------ rslib/src/media/mod.rs | 36 ++++----- rslib/src/notes/mod.rs | 46 ++++++----- rslib/src/notes/undo.rs | 6 +- rslib/src/notetype/cardgen.rs | 31 ++++---- rslib/src/notetype/checks.rs | 17 ++-- rslib/src/notetype/emptycards.rs | 19 +++-- rslib/src/notetype/fields.rs | 6 +- rslib/src/notetype/mod.rs | 73 ++++++++++-------- rslib/src/notetype/notetypechange.rs | 28 ++++--- rslib/src/notetype/render.rs | 20 +++-- rslib/src/notetype/schema11.rs | 32 ++++---- rslib/src/notetype/schemachange.rs | 23 +++--- rslib/src/notetype/stock.rs | 17 ++-- rslib/src/notetype/templates.rs | 10 ++- rslib/src/preferences.rs | 22 +++--- rslib/src/prelude.rs | 50 +++++++----- rslib/src/revlog/mod.rs | 15 ++-- rslib/src/scheduler/answering/current.rs | 18 +++-- rslib/src/scheduler/answering/learning.rs | 18 +++-- rslib/src/scheduler/answering/mod.rs | 41 +++++----- rslib/src/scheduler/answering/preview.rs | 31 ++++---- rslib/src/scheduler/answering/relearning.rs | 12 +-- rslib/src/scheduler/answering/review.rs | 11 +-- rslib/src/scheduler/answering/revlog.rs | 10 +-- rslib/src/scheduler/bury_and_suspend.rs | 29 ++++--- rslib/src/scheduler/congrats.rs | 3 +- rslib/src/scheduler/filtered/card.rs | 12 +-- rslib/src/scheduler/filtered/custom_study.rs | 38 +++++---- rslib/src/scheduler/filtered/mod.rs | 33 ++++---- rslib/src/scheduler/learning.rs | 8 +- rslib/src/scheduler/mod.rs | 13 ++-- rslib/src/scheduler/new.rs | 31 ++++---- rslib/src/scheduler/queue/builder/burying.rs | 10 ++- .../src/scheduler/queue/builder/gathering.rs | 12 +-- rslib/src/scheduler/queue/builder/mod.rs | 32 ++++---- rslib/src/scheduler/queue/builder/sorting.rs | 7 +- rslib/src/scheduler/queue/entry.rs | 7 +- rslib/src/scheduler/queue/learning.rs | 15 ++-- rslib/src/scheduler/queue/mod.rs | 20 +++-- rslib/src/scheduler/queue/undo.rs | 14 ++-- rslib/src/scheduler/reviews.rs | 18 +++-- rslib/src/scheduler/states/filtered.rs | 10 ++- rslib/src/scheduler/states/learning.rs | 6 +- rslib/src/scheduler/states/mod.rs | 3 +- rslib/src/scheduler/states/new.rs | 5 +- rslib/src/scheduler/states/normal.rs | 11 ++- rslib/src/scheduler/states/preview_filter.rs | 4 +- rslib/src/scheduler/states/relearning.rs | 9 ++- .../scheduler/states/rescheduling_filter.rs | 8 +- rslib/src/scheduler/states/review.rs | 24 +++--- rslib/src/scheduler/states/steps.rs | 11 +-- rslib/src/scheduler/timespan.rs | 8 +- rslib/src/scheduler/timing.rs | 17 ++-- rslib/src/scheduler/upgrade.rs | 11 ++- rslib/src/search/builder.rs | 15 +++- rslib/src/search/mod.rs | 24 ++++-- rslib/src/search/parser.rs | 38 +++++---- rslib/src/search/sqlwriter.rs | 62 ++++++++------- rslib/src/search/writer.rs | 28 ++++--- rslib/src/serde.rs | 12 +-- rslib/src/stats/card.rs | 14 ++-- rslib/src/stats/graphs/added.rs | 3 +- rslib/src/stats/graphs/buttons.rs | 8 +- rslib/src/stats/graphs/card_counts.rs | 11 +-- rslib/src/stats/graphs/eases.rs | 4 +- rslib/src/stats/graphs/future_due.rs | 4 +- rslib/src/stats/graphs/hours.rs | 9 +-- rslib/src/stats/graphs/intervals.rs | 4 +- rslib/src/stats/graphs/mod.rs | 13 ++-- rslib/src/stats/graphs/reviews.rs | 3 +- rslib/src/stats/graphs/today.rs | 6 +- rslib/src/stats/today.rs | 4 +- rslib/src/storage/card/data.rs | 15 ++-- rslib/src/storage/card/filtered.rs | 7 +- rslib/src/storage/card/mod.rs | 52 ++++++++----- rslib/src/storage/collection_timestamps.rs | 3 +- rslib/src/storage/config/mod.rs | 5 +- rslib/src/storage/deck/mod.rs | 30 ++++---- rslib/src/storage/deckconfig/mod.rs | 12 +-- rslib/src/storage/graves/mod.rs | 3 +- rslib/src/storage/note/mod.rs | 29 ++++--- rslib/src/storage/notetype/mod.rs | 27 ++++--- rslib/src/storage/revlog/mod.rs | 26 +++---- rslib/src/storage/sqlite.rs | 39 ++++++---- rslib/src/storage/sync.rs | 4 +- rslib/src/storage/sync_check.rs | 9 +-- rslib/src/storage/tag/mod.rs | 7 +- rslib/src/storage/upgrades/mod.rs | 3 +- rslib/src/sync/collection/changes.rs | 46 ++++++----- rslib/src/sync/collection/chunks.rs | 38 ++++----- rslib/src/sync/collection/download.rs | 29 ++++--- rslib/src/sync/collection/finish.rs | 13 ++-- rslib/src/sync/collection/graves.rs | 10 +-- rslib/src/sync/collection/meta.rs | 38 ++++----- rslib/src/sync/collection/normal.rs | 27 +++---- rslib/src/sync/collection/progress.rs | 13 ++-- rslib/src/sync/collection/protocol.rs | 46 +++++------ rslib/src/sync/collection/sanity.rs | 25 +++--- rslib/src/sync/collection/start.rs | 29 ++++--- rslib/src/sync/collection/status.rs | 29 ++++--- rslib/src/sync/collection/tests.rs | 77 ++++++++++--------- rslib/src/sync/collection/upload.rs | 42 +++++----- rslib/src/sync/error.rs | 11 +-- rslib/src/sync/http_client/full_sync.rs | 27 +++---- rslib/src/sync/http_client/io_monitor.rs | 75 ++++++++++-------- rslib/src/sync/http_client/mod.rs | 34 ++++---- rslib/src/sync/http_client/protocol.rs | 59 +++++++------- rslib/src/sync/http_server/handlers.rs | 75 ++++++++++-------- rslib/src/sync/http_server/logging.rs | 8 +- .../http_server/media_manager/download.rs | 18 ++--- .../src/sync/http_server/media_manager/mod.rs | 21 +++-- .../sync/http_server/media_manager/upload.rs | 28 +++---- rslib/src/sync/http_server/mod.rs | 59 +++++++------- rslib/src/sync/http_server/routes.rs | 42 +++++----- rslib/src/sync/http_server/user.rs | 29 ++++--- rslib/src/sync/login.rs | 13 ++-- rslib/src/sync/media/begin.rs | 7 +- rslib/src/sync/media/changes.rs | 13 ++-- .../media/database/client/changetracker.rs | 39 ++++++---- rslib/src/sync/media/database/client/mod.rs | 29 +++---- .../media/database/server/entry/changes.rs | 7 +- .../media/database/server/entry/download.rs | 33 ++++---- .../sync/media/database/server/entry/mod.rs | 19 +++-- .../media/database/server/entry/upload.rs | 12 ++- .../sync/media/database/server/meta/mod.rs | 18 +++-- rslib/src/sync/media/download.rs | 18 +++-- rslib/src/sync/media/protocol.rs | 34 ++++---- rslib/src/sync/media/sanity.rs | 3 +- rslib/src/sync/media/syncer.rs | 49 ++++++------ rslib/src/sync/media/tests.rs | 63 +++++++-------- rslib/src/sync/media/upload.rs | 29 +++---- rslib/src/sync/media/zip.rs | 25 +++--- rslib/src/sync/request/header_and_stream.rs | 38 ++++----- rslib/src/sync/request/mod.rs | 45 ++++++----- rslib/src/sync/request/multipart.rs | 18 +++-- rslib/src/sync/response.rs | 27 +++---- rslib/src/sync/version.rs | 20 ++--- rslib/src/tags/bulkadd.rs | 6 +- rslib/src/tags/findreplace.rs | 14 +++- rslib/src/tags/matcher.rs | 12 ++- rslib/src/tags/notes.rs | 8 +- rslib/src/tags/register.rs | 27 ++++--- rslib/src/tags/remove.rs | 6 +- rslib/src/tags/rename.rs | 10 ++- rslib/src/tags/reparent.rs | 3 +- rslib/src/tags/tree.rs | 9 ++- rslib/src/tags/undo.rs | 5 +- rslib/src/template.rs | 61 ++++++++------- rslib/src/template_filters.rs | 15 ++-- rslib/src/tests.rs | 18 ++--- rslib/src/text.rs | 16 ++-- rslib/src/timestamp.rs | 8 +- rslib/src/typeanswer.rs | 10 +-- rslib/src/undo/changes.rs | 18 +++-- rslib/src/undo/mod.rs | 18 +++-- 311 files changed, 3410 insertions(+), 2687 deletions(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index e4645a37f..ed92d0b98 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,8 +1,7 @@ -# this is not supported on stable Rust, and is ignored by the Bazel rules; it is only -# useful for manual invocation with 'cargo +nightly fmt' -imports_granularity = "Crate" +# These settings are not supported on stable Rust, and are ignored by the ninja +# build script - to use them you need to run 'cargo +nightly fmt' group_imports = "StdExternalCrate" - -# wrap_comments = true -# imports_granularity = "Item" -# imports_layout = "Vertical" +imports_granularity = "Item" +imports_layout = "Vertical" +wrap_comments = true +ignore = ["ascii_percent_encoding"] diff --git a/build/archives/src/main.rs b/build/archives/src/main.rs index aa838346e..ddb74011c 100644 --- a/build/archives/src/main.rs +++ b/build/archives/src/main.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{error::Error, fs, io::Read}; +use std::error::Error; +use std::fs; +use std::io::Read; use camino::Utf8Path; use sha2::Digest; @@ -117,7 +119,8 @@ fn extract(archive_path: &str, output_folder: &str) -> Result<()> { archive.extract(&output_tmp)?; } } - // if the output folder contains a single folder (eg foo-1.2), move it up a level + // if the output folder contains a single folder (eg foo-1.2), move it up a + // level let mut entries: Vec<_> = output_tmp.read_dir_utf8()?.take(2).collect(); let first_entry = entries.pop().unwrap()?; if entries.is_empty() && first_entry.metadata()?.is_dir() { diff --git a/build/configure/src/aqt.rs b/build/configure/src/aqt.rs index 3e88074bf..82624f748 100644 --- a/build/configure/src/aqt.rs +++ b/build/configure/src/aqt.rs @@ -1,21 +1,27 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use ninja_gen::{ - action::BuildAction, - command::RunCommand, - copy::{CopyFile, CopyFiles}, - glob, hashmap, inputs, - node::{CompileSass, EsbuildScript, TypescriptCheck}, - python::{python_format, PythonTest}, - Build, Result, Utf8Path, Utf8PathBuf, -}; +use ninja_gen::action::BuildAction; +use ninja_gen::command::RunCommand; +use ninja_gen::copy::CopyFile; +use ninja_gen::copy::CopyFiles; +use ninja_gen::glob; +use ninja_gen::hashmap; +use ninja_gen::inputs; +use ninja_gen::node::CompileSass; +use ninja_gen::node::EsbuildScript; +use ninja_gen::node::TypescriptCheck; +use ninja_gen::python::python_format; +use ninja_gen::python::PythonTest; +use ninja_gen::Build; +use ninja_gen::Result; +use ninja_gen::Utf8Path; +use ninja_gen::Utf8PathBuf; -use crate::{ - anki_version, - python::BuildWheel, - web::{copy_mathjax, eslint}, -}; +use crate::anki_version; +use crate::python::BuildWheel; +use crate::web::copy_mathjax; +use crate::web::eslint; pub fn build_and_check_aqt(build: &mut Build) -> Result<()> { build_forms(build)?; @@ -294,7 +300,8 @@ impl BuildAction for BuildThemedIcon<'_> { fn files(&mut self, build: &mut impl ninja_gen::build::FilesHandle) { let stem = self.src_icon.file_stem().unwrap(); - // eg foo-light.svg, foo-dark.svg, foo-FG_SUBTLE-light.svg, foo-FG_SUBTLE-dark.svg + // eg foo-light.svg, foo-dark.svg, foo-FG_SUBTLE-light.svg, + // foo-FG_SUBTLE-dark.svg let outputs: Vec<_> = self .colors .iter() diff --git a/build/configure/src/bundle.rs b/build/configure/src/bundle.rs index 2a0b21774..e4226f62c 100644 --- a/build/configure/src/bundle.rs +++ b/build/configure/src/bundle.rs @@ -1,22 +1,25 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use ninja_gen::{ - action::BuildAction, - archives::{download_and_extract, empty_manifest, with_exe, OnlineArchive}, - cargo::{CargoBuild, RustOutput}, - git::SyncSubmodule, - glob, - input::BuildInput, - inputs, - python::PythonEnvironment, - Build, Result, Utf8Path, -}; +use ninja_gen::action::BuildAction; +use ninja_gen::archives::download_and_extract; +use ninja_gen::archives::empty_manifest; +use ninja_gen::archives::with_exe; +use ninja_gen::archives::OnlineArchive; +use ninja_gen::cargo::CargoBuild; +use ninja_gen::cargo::RustOutput; +use ninja_gen::git::SyncSubmodule; +use ninja_gen::glob; +use ninja_gen::input::BuildInput; +use ninja_gen::inputs; +use ninja_gen::python::PythonEnvironment; +use ninja_gen::Build; +use ninja_gen::Result; +use ninja_gen::Utf8Path; -use crate::{ - anki_version, - platform::{overriden_python_target_platform, overriden_rust_target_triple}, -}; +use crate::anki_version; +use crate::platform::overriden_python_target_platform; +use crate::platform::overriden_rust_target_triple; #[derive(Debug, PartialEq, Eq)] enum DistKind { diff --git a/build/configure/src/main.rs b/build/configure/src/main.rs index ef787e902..58956169c 100644 --- a/build/configure/src/main.rs +++ b/build/configure/src/main.rs @@ -12,11 +12,18 @@ mod web; use aqt::build_and_check_aqt; use bundle::build_bundle; -use ninja_gen::{Build, Result}; -use pylib::{build_pylib, check_pylib}; -use python::{check_copyright, check_python, setup_python, setup_venv}; -use rust::{build_rust, check_rust}; -use web::{build_and_check_web, check_sql}; +use ninja_gen::Build; +use ninja_gen::Result; +use pylib::build_pylib; +use pylib::check_pylib; +use python::check_copyright; +use python::check_python; +use python::setup_python; +use python::setup_venv; +use rust::build_rust; +use rust::check_rust; +use web::build_and_check_web; +use web::check_sql; use crate::proto::check_proto; diff --git a/build/configure/src/platform.rs b/build/configure/src/platform.rs index 300d2f3cc..4aec36e65 100644 --- a/build/configure/src/platform.rs +++ b/build/configure/src/platform.rs @@ -5,14 +5,14 @@ use std::env; use ninja_gen::archives::Platform; -/// Usually None to use the host architecture; can be overriden by setting MAC_X86 -/// to build for x86_64 on Apple Silicon +/// Usually None to use the host architecture; can be overriden by setting +/// MAC_X86 to build for x86_64 on Apple Silicon pub fn overriden_rust_target_triple() -> Option<&'static str> { overriden_python_target_platform().map(|p| p.as_rust_triple()) } -/// Usually None to use the host architecture; can be overriden by setting MAC_X86 -/// to build for x86_64 on Apple Silicon +/// Usually None to use the host architecture; can be overriden by setting +/// MAC_X86 to build for x86_64 on Apple Silicon pub fn overriden_python_target_platform() -> Option { if env::var("MAC_X86").is_ok() { Some(Platform::MacX64) diff --git a/build/configure/src/proto.rs b/build/configure/src/proto.rs index c72394253..47590af32 100644 --- a/build/configure/src/proto.rs +++ b/build/configure/src/proto.rs @@ -1,12 +1,15 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use ninja_gen::{ - archives::{download_and_extract, with_exe}, - glob, hashmap, inputs, - protobuf::{protoc_archive, ClangFormat}, - Build, Result, -}; +use ninja_gen::archives::download_and_extract; +use ninja_gen::archives::with_exe; +use ninja_gen::glob; +use ninja_gen::hashmap; +use ninja_gen::inputs; +use ninja_gen::protobuf::protoc_archive; +use ninja_gen::protobuf::ClangFormat; +use ninja_gen::Build; +use ninja_gen::Result; pub fn download_protoc(build: &mut Build) -> Result<()> { download_and_extract( diff --git a/build/configure/src/pylib.rs b/build/configure/src/pylib.rs index 731485678..851208d3a 100644 --- a/build/configure/src/pylib.rs +++ b/build/configure/src/pylib.rs @@ -1,20 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use ninja_gen::{ - action::BuildAction, - archives::Platform, - command::RunCommand, - copy::LinkFile, - glob, hashmap, inputs, - python::{python_format, PythonTest}, - Build, Result, -}; +use ninja_gen::action::BuildAction; +use ninja_gen::archives::Platform; +use ninja_gen::command::RunCommand; +use ninja_gen::copy::LinkFile; +use ninja_gen::glob; +use ninja_gen::hashmap; +use ninja_gen::inputs; +use ninja_gen::python::python_format; +use ninja_gen::python::PythonTest; +use ninja_gen::Build; +use ninja_gen::Result; -use crate::{ - platform::overriden_python_target_platform, - python::{BuildWheel, GenPythonProto}, -}; +use crate::platform::overriden_python_target_platform; +use crate::python::BuildWheel; +use crate::python::GenPythonProto; pub fn build_pylib(build: &mut Build) -> Result<()> { // generated files diff --git a/build/configure/src/python.rs b/build/configure/src/python.rs index 32bc9f905..6dd329b6c 100644 --- a/build/configure/src/python.rs +++ b/build/configure/src/python.rs @@ -3,18 +3,24 @@ use std::env; -use ninja_gen::{ - action::BuildAction, - archives::{download_and_extract, OnlineArchive, Platform}, - build::FilesHandle, - command::RunCommand, - glob, hashmap, - input::BuildInput, - inputs, - python::{python_format, PythonEnvironment, PythonLint, PythonTypecheck}, - rsync::RsyncFiles, - Build, Result, Utf8Path, -}; +use ninja_gen::action::BuildAction; +use ninja_gen::archives::download_and_extract; +use ninja_gen::archives::OnlineArchive; +use ninja_gen::archives::Platform; +use ninja_gen::build::FilesHandle; +use ninja_gen::command::RunCommand; +use ninja_gen::glob; +use ninja_gen::hashmap; +use ninja_gen::input::BuildInput; +use ninja_gen::inputs; +use ninja_gen::python::python_format; +use ninja_gen::python::PythonEnvironment; +use ninja_gen::python::PythonLint; +use ninja_gen::python::PythonTypecheck; +use ninja_gen::rsync::RsyncFiles; +use ninja_gen::Build; +use ninja_gen::Result; +use ninja_gen::Utf8Path; fn python_archive(platform: Platform) -> OnlineArchive { match platform { @@ -252,8 +258,8 @@ pub fn check_python(build: &mut Build) -> Result<()> { fn add_pylint(build: &mut Build) -> Result<()> { // pylint does not support PEP420 implicit namespaces split across import paths, - // so we need to merge our pylib sources and generated files before invoking it, and - // add a top-level __init__.py + // so we need to merge our pylib sources and generated files before invoking it, + // and add a top-level __init__.py build.add( "pylint/anki", RsyncFiles { diff --git a/build/configure/src/rust.rs b/build/configure/src/rust.rs index 2523ce2b9..b51d99445 100644 --- a/build/configure/src/rust.rs +++ b/build/configure/src/rust.rs @@ -1,13 +1,20 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use ninja_gen::{ - cargo::{CargoBuild, CargoClippy, CargoFormat, CargoRun, CargoTest, RustOutput}, - git::SyncSubmodule, - glob, inputs, Build, Result, -}; +use ninja_gen::cargo::CargoBuild; +use ninja_gen::cargo::CargoClippy; +use ninja_gen::cargo::CargoFormat; +use ninja_gen::cargo::CargoRun; +use ninja_gen::cargo::CargoTest; +use ninja_gen::cargo::RustOutput; +use ninja_gen::git::SyncSubmodule; +use ninja_gen::glob; +use ninja_gen::inputs; +use ninja_gen::Build; +use ninja_gen::Result; -use crate::{platform::overriden_rust_target_triple, proto::download_protoc}; +use crate::platform::overriden_rust_target_triple; +use crate::proto::download_protoc; pub fn build_rust(build: &mut Build) -> Result<()> { prepare_translations(build)?; diff --git a/build/configure/src/web.rs b/build/configure/src/web.rs index 91e5bf6c7..6d969f327 100644 --- a/build/configure/src/web.rs +++ b/build/configure/src/web.rs @@ -2,19 +2,25 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // use super::*; -use ninja_gen::{ - action::BuildAction, - command::RunCommand, - glob, hashmap, - input::BuildInput, - inputs, - node::{ - node_archive, CompileSass, DPrint, EsbuildScript, Eslint, GenTypescriptProto, JestTest, - SqlFormat, SvelteCheck, TypescriptCheck, - }, - rsync::RsyncFiles, - Build, Result, -}; +use ninja_gen::action::BuildAction; +use ninja_gen::command::RunCommand; +use ninja_gen::glob; +use ninja_gen::hashmap; +use ninja_gen::input::BuildInput; +use ninja_gen::inputs; +use ninja_gen::node::node_archive; +use ninja_gen::node::CompileSass; +use ninja_gen::node::DPrint; +use ninja_gen::node::EsbuildScript; +use ninja_gen::node::Eslint; +use ninja_gen::node::GenTypescriptProto; +use ninja_gen::node::JestTest; +use ninja_gen::node::SqlFormat; +use ninja_gen::node::SvelteCheck; +use ninja_gen::node::TypescriptCheck; +use ninja_gen::rsync::RsyncFiles; +use ninja_gen::Build; +use ninja_gen::Result; pub fn build_and_check_web(build: &mut Build) -> Result<()> { setup_node(build)?; diff --git a/build/ninja_gen/src/action.rs b/build/ninja_gen/src/action.rs index 0a04a16ba..e6c9e1c29 100644 --- a/build/ninja_gen/src/action.rs +++ b/build/ninja_gen/src/action.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{build::FilesHandle, Build, Result}; +use crate::build::FilesHandle; +use crate::Build; +use crate::Result; pub trait BuildAction { /// Command line to invoke for each build statement. @@ -10,8 +12,9 @@ pub trait BuildAction { /// Declare the input files and variables, and output files. fn files(&mut self, build: &mut impl FilesHandle); - /// If true, this action will not trigger a rebuild of dependent targets if the output - /// files are unchanged. This corresponds to Ninja's "restat" argument. + /// If true, this action will not trigger a rebuild of dependent targets if + /// the output files are unchanged. This corresponds to Ninja's "restat" + /// argument. fn check_output_timestamps(&self) -> bool { false } @@ -21,8 +24,8 @@ pub trait BuildAction { false } - /// Called on first action invocation; can be used to inject other build actions - /// to perform initial setup. + /// Called on first action invocation; can be used to inject other build + /// actions to perform initial setup. #[allow(unused_variables)] fn on_first_instance(&self, build: &mut Build) -> Result<()> { Ok(()) diff --git a/build/ninja_gen/src/archives.rs b/build/ninja_gen/src/archives.rs index bbb3cc562..50815b75f 100644 --- a/build/ninja_gen/src/archives.rs +++ b/build/ninja_gen/src/archives.rs @@ -1,17 +1,20 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashMap}; +use std::borrow::Cow; +use std::collections::HashMap; -use camino::{Utf8Path, Utf8PathBuf}; +use camino::Utf8Path; +use camino::Utf8PathBuf; -use crate::{ - action::BuildAction, - cargo::{CargoBuild, RustOutput}, - glob, - input::BuildInput, - inputs, Build, Result, -}; +use crate::action::BuildAction; +use crate::cargo::CargoBuild; +use crate::cargo::RustOutput; +use crate::glob; +use crate::input::BuildInput; +use crate::inputs; +use crate::Build; +use crate::Result; #[derive(Clone, Copy, Debug)] pub struct OnlineArchive { @@ -98,12 +101,14 @@ impl BuildAction for DownloadArchive { struct ExtractArchive<'a, I> { pub archive_path: BuildInput, - /// The folder that the archive should be extracted into, relative to $builddir/extracted. - /// If the archive contains a single top-level folder, its contents will be extracted into the - /// provided folder, so that output like tool-1.2/ can be extracted into tool/. + /// The folder that the archive should be extracted into, relative to + /// $builddir/extracted. If the archive contains a single top-level + /// folder, its contents will be extracted into the provided folder, so + /// that output like tool-1.2/ can be extracted into tool/. pub extraction_folder_name: &'a str, - /// Files contained inside the archive, relative to the archive root, and excluding the top-level - /// folder if it is the sole top-level entry. Any files you wish to use as part of subsequent rules + /// Files contained inside the archive, relative to the archive root, and + /// excluding the top-level folder if it is the sole top-level entry. + /// Any files you wish to use as part of subsequent rules /// must be declared here. pub file_manifest: HashMap<&'static str, I>, } diff --git a/build/ninja_gen/src/build.rs b/build/ninja_gen/src/build.rs index 643a1e426..60c69dadb 100644 --- a/build/ninja_gen/src/build.rs +++ b/build/ninja_gen/src/build.rs @@ -1,20 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::{HashMap, HashSet}, - fmt::Write, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::fmt::Write; use camino::Utf8PathBuf; -use crate::{ - action::BuildAction, - archives::Platform, - configure::ConfigureBuild, - input::{space_separated, BuildInput}, - Result, -}; +use crate::action::BuildAction; +use crate::archives::Platform; +use crate::configure::ConfigureBuild; +use crate::input::space_separated; +use crate::input::BuildInput; +use crate::Result; #[derive(Debug)] pub struct Build { @@ -64,8 +62,8 @@ impl Build { self.pools.push((name, size)); } - /// Evaluate the provided closure only once, using `key` to determine uniqueness. - /// This key should not match any build action name. + /// Evaluate the provided closure only once, using `key` to determine + /// uniqueness. This key should not match any build action name. pub fn once_only( &mut self, key: &'static str, @@ -155,15 +153,16 @@ rule {action_name} self.add_resolved_files_to_group(target_group, &additional_files.clone()) } - /// Outputs from a given build statement group. An error if no files have been registered yet. + /// Outputs from a given build statement group. An error if no files have + /// been registered yet. pub fn group_outputs(&self, group_name: &'static str) -> &[String] { self.groups .get(group_name) .unwrap_or_else(|| panic!("expected files in {group_name}")) } - /// Single output from a given build statement group. An error if no files have been registered yet, - /// or more than one file has been registered. + /// Single output from a given build statement group. An error if no files + /// have been registered yet, or more than one file has been registered. pub fn group_output(&self, group_name: &'static str) -> String { let outputs = self.group_outputs(group_name); assert_eq!(outputs.len(), 1); @@ -201,8 +200,8 @@ fn split_groups(group: &str) -> Vec<&str> { } struct BuildStatement<'a> { - /// Cache of outputs by already-evaluated build rules, allowing later rules to more easily consume - /// the outputs of previous rules. + /// Cache of outputs by already-evaluated build rules, allowing later rules + /// to more easily consume the outputs of previous rules. existing_outputs: &'a HashMap>, rule_name: &'static str, // implicit refers to files that are not automatically assigned to $in and $out by Ninja, @@ -260,8 +259,8 @@ impl BuildStatement<'_> { stmt } - /// Returns a list of all output files, which `Build` will add to `existing_outputs`, - /// and any subgroups. + /// Returns a list of all output files, which `Build` will add to + /// `existing_outputs`, and any subgroups. fn render_into(mut self, buf: &mut String) -> (Vec, Vec<(String, Vec)>) { let action_name = self.rule_name; let inputs_str = to_ninja_target_string(&self.explicit_inputs, &self.implicit_inputs); @@ -344,8 +343,9 @@ pub trait FilesHandle { /// created so the file list can be accessed in the command. By convention, /// this is often `out`. /// - If subgroup is true, the files are also placed in a subgroup. Eg - /// if a rule `foo` exists and subgroup `bar` is provided, the files are accessible - /// via `:foo:bar`. The variable name must not be empty, or called `out`. + /// if a rule `foo` exists and subgroup `bar` is provided, the files are + /// accessible via `:foo:bar`. The variable name must not be empty, or + /// called `out`. fn add_outputs_ext( &mut self, variable: impl Into, @@ -357,8 +357,8 @@ pub trait FilesHandle { fn add_output_stamp(&mut self, path: impl Into); /// Set an env var for the duration of the provided command(s). /// Note this is defined once for the rule, so if the value should change - /// for each command, `constant_value` should reference a `$variable` you have - /// defined. + /// for each command, `constant_value` should reference a `$variable` you + /// have defined. fn add_env_var(&mut self, key: &str, constant_value: &str); fn release_build(&self) -> bool; diff --git a/build/ninja_gen/src/cargo.rs b/build/ninja_gen/src/cargo.rs index 9419731ad..111923e13 100644 --- a/build/ninja_gen/src/cargo.rs +++ b/build/ninja_gen/src/cargo.rs @@ -1,12 +1,16 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use camino::{Utf8Path, Utf8PathBuf}; +use camino::Utf8Path; +use camino::Utf8PathBuf; -use crate::{ - action::BuildAction, archives::with_exe, build::FilesHandle, input::BuildInput, inputs, Build, - Result, -}; +use crate::action::BuildAction; +use crate::archives::with_exe; +use crate::build::FilesHandle; +use crate::input::BuildInput; +use crate::inputs; +use crate::Build; +use crate::Result; #[derive(Debug, PartialEq, Eq)] pub enum RustOutput<'a> { @@ -191,8 +195,8 @@ impl BuildAction for CargoFormat { } } -/// Use Cargo to download and build a Rust binary. If `binary_name` is `foo`, a `$foo` variable -/// will be defined with the path to the binary. +/// Use Cargo to download and build a Rust binary. If `binary_name` is `foo`, a +/// `$foo` variable will be defined with the path to the binary. pub struct CargoInstall { pub binary_name: &'static str, /// eg 'foo --version 1.3' or '--git git://...' diff --git a/build/ninja_gen/src/command.rs b/build/ninja_gen/src/command.rs index c26c97d56..d347a9206 100644 --- a/build/ninja_gen/src/command.rs +++ b/build/ninja_gen/src/command.rs @@ -3,11 +3,10 @@ use std::collections::HashMap; -use crate::{ - action::BuildAction, - input::{space_separated, BuildInput}, - inputs, -}; +use crate::action::BuildAction; +use crate::input::space_separated; +use crate::input::BuildInput; +use crate::inputs; pub struct RunCommand<'a> { // Will be automatically included as a dependency @@ -24,8 +23,9 @@ impl BuildAction for RunCommand<'_> { } fn files(&mut self, build: &mut impl crate::build::FilesHandle) { - // Because we've defined a generic rule instead of making one for a specific use case, - // we need to manually intepolate variables in the user-provided args. + // Because we've defined a generic rule instead of making one for a specific use + // case, we need to manually intepolate variables in the user-provided + // args. let mut args = self.args.to_string(); for (key, inputs) in &self.inputs { let files = build.expand_inputs(inputs); diff --git a/build/ninja_gen/src/configure.rs b/build/ninja_gen/src/configure.rs index 155edb8ef..dd7e17306 100644 --- a/build/ninja_gen/src/configure.rs +++ b/build/ninja_gen/src/configure.rs @@ -1,12 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - action::BuildAction, - build::FilesHandle, - cargo::{CargoBuild, RustOutput}, - glob, inputs, Build, Result, -}; +use crate::action::BuildAction; +use crate::build::FilesHandle; +use crate::cargo::CargoBuild; +use crate::cargo::RustOutput; +use crate::glob; +use crate::inputs; +use crate::Build; +use crate::Result; pub struct ConfigureBuild {} diff --git a/build/ninja_gen/src/copy.rs b/build/ninja_gen/src/copy.rs index 88fe9e476..f6dce8377 100644 --- a/build/ninja_gen/src/copy.rs +++ b/build/ninja_gen/src/copy.rs @@ -3,14 +3,16 @@ use camino::Utf8Path; -use crate::{action::BuildAction, input::BuildInput}; +use crate::action::BuildAction; +use crate::input::BuildInput; /// Copy the provided files into the specified destination folder. /// Directory structure is not preserved - eg foo/bar.js is copied /// into out/$output_folder/bar.js. pub struct CopyFiles<'a> { pub inputs: BuildInput, - /// The folder (relative to the build folder) that files should be copied into. + /// The folder (relative to the build folder) that files should be copied + /// into. pub output_folder: &'a str, } @@ -51,8 +53,9 @@ impl BuildAction for CopyFile<'_> { } } -/// Create a symbolic link to the provided output path, which should be relative to -/// the output folder. This can be used to create a copy with a different name. +/// Create a symbolic link to the provided output path, which should be relative +/// to the output folder. This can be used to create a copy with a different +/// name. pub struct LinkFile<'a> { pub input: BuildInput, pub output: &'a str, diff --git a/build/ninja_gen/src/git.rs b/build/ninja_gen/src/git.rs index f5a668c76..712ed23a6 100644 --- a/build/ninja_gen/src/git.rs +++ b/build/ninja_gen/src/git.rs @@ -4,7 +4,8 @@ use itertools::Itertools; use super::*; -use crate::{action::BuildAction, input::BuildInput}; +use crate::action::BuildAction; +use crate::input::BuildInput; pub struct SyncSubmodule { pub path: &'static str, diff --git a/build/ninja_gen/src/hash.rs b/build/ninja_gen/src/hash.rs index 8e2f6a327..1f6bfc5a8 100644 --- a/build/ninja_gen/src/hash.rs +++ b/build/ninja_gen/src/hash.rs @@ -1,10 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::hash_map::DefaultHasher, - hash::{Hash, Hasher}, -}; +use std::collections::hash_map::DefaultHasher; +use std::hash::Hash; +use std::hash::Hasher; pub fn simple_hash(hashable: impl Hash) -> u64 { let mut hasher = DefaultHasher::new(); diff --git a/build/ninja_gen/src/input.rs b/build/ninja_gen/src/input.rs index 06a35cc3f..773576611 100644 --- a/build/ninja_gen/src/input.rs +++ b/build/ninja_gen/src/input.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, fmt::Display}; +use std::collections::HashMap; +use std::fmt::Display; use camino::Utf8PathBuf; @@ -126,7 +127,8 @@ lazy_static::lazy_static! { static ref CACHED_FILES: Vec = cache_files(); } -/// Walking the source tree once instead of for each glob yields ~4x speed improvements. +/// Walking the source tree once instead of for each glob yields ~4x speed +/// improvements. fn cache_files() -> Vec { walkdir::WalkDir::new(".") // ensure the output order is predictable diff --git a/build/ninja_gen/src/lib.rs b/build/ninja_gen/src/lib.rs index c673ea3e7..5c0856f17 100644 --- a/build/ninja_gen/src/lib.rs +++ b/build/ninja_gen/src/lib.rs @@ -19,7 +19,8 @@ pub mod rsync; pub mod sass; pub use build::Build; -pub use camino::{Utf8Path, Utf8PathBuf}; +pub use camino::Utf8Path; +pub use camino::Utf8PathBuf; pub use maplit::hashmap; pub use which::which; diff --git a/build/ninja_gen/src/node.rs b/build/ninja_gen/src/node.rs index f3beb3f42..9e2c43a30 100644 --- a/build/ninja_gen/src/node.rs +++ b/build/ninja_gen/src/node.rs @@ -1,15 +1,17 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashMap}; +use std::borrow::Cow; +use std::collections::HashMap; use super::*; -use crate::{ - action::BuildAction, - archives::{download_and_extract, OnlineArchive, Platform}, - hash::simple_hash, - input::{space_separated, BuildInput}, -}; +use crate::action::BuildAction; +use crate::archives::download_and_extract; +use crate::archives::OnlineArchive; +use crate::archives::Platform; +use crate::hash::simple_hash; +use crate::input::space_separated; +use crate::input::BuildInput; pub fn node_archive(platform: Platform) -> OnlineArchive { match platform { diff --git a/build/ninja_gen/src/protobuf.rs b/build/ninja_gen/src/protobuf.rs index 1b7496609..fe2d09401 100644 --- a/build/ninja_gen/src/protobuf.rs +++ b/build/ninja_gen/src/protobuf.rs @@ -3,13 +3,14 @@ use maplit::hashmap; -use crate::{ - action::BuildAction, - archives::{download_and_extract, with_exe, OnlineArchive, Platform}, - hash::simple_hash, - input::BuildInput, - inputs, -}; +use crate::action::BuildAction; +use crate::archives::download_and_extract; +use crate::archives::with_exe; +use crate::archives::OnlineArchive; +use crate::archives::Platform; +use crate::hash::simple_hash; +use crate::input::BuildInput; +use crate::inputs; pub fn protoc_archive(platform: Platform) -> OnlineArchive { match platform { diff --git a/build/ninja_gen/src/python.rs b/build/ninja_gen/src/python.rs index 1aa6f3907..2a367b46b 100644 --- a/build/ninja_gen/src/python.rs +++ b/build/ninja_gen/src/python.rs @@ -1,7 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{action::BuildAction, hash::simple_hash, input::BuildInput, inputs, Build, Result}; +use crate::action::BuildAction; +use crate::hash::simple_hash; +use crate::input::BuildInput; +use crate::inputs; +use crate::Build; +use crate::Result; pub struct PythonEnvironment<'a> { pub folder: &'static str, diff --git a/build/ninja_gen/src/render.rs b/build/ninja_gen/src/render.rs index eb7cda279..a34d248e3 100644 --- a/build/ninja_gen/src/render.rs +++ b/build/ninja_gen/src/render.rs @@ -1,9 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fmt::Write, fs::read_to_string}; +use std::fmt::Write; +use std::fs::read_to_string; -use crate::{archives::with_exe, input::space_separated, Build}; +use crate::archives::with_exe; +use crate::input::space_separated; +use crate::Build; impl Build { pub fn render(&self) -> String { diff --git a/build/ninja_gen/src/rsync.rs b/build/ninja_gen/src/rsync.rs index ac575330e..c1c29ca5e 100644 --- a/build/ninja_gen/src/rsync.rs +++ b/build/ninja_gen/src/rsync.rs @@ -3,16 +3,16 @@ use camino::Utf8Path; -use crate::{ - action::BuildAction, - build::FilesHandle, - input::{space_separated, BuildInput}, -}; +use crate::action::BuildAction; +use crate::build::FilesHandle; +use crate::input::space_separated; +use crate::input::BuildInput; -/// Rsync the provided inputs into `output_folder`, preserving directory structure, -/// eg foo/bar.js -> out/$target_folder/foo/bar.js. `strip_prefix` can be used to -/// remove a portion of the the path when copying. If the input files are from previous -/// build outputs, the prefix should begin with `$builddir/`. +/// Rsync the provided inputs into `output_folder`, preserving directory +/// structure, eg foo/bar.js -> out/$target_folder/foo/bar.js. `strip_prefix` +/// can be used to remove a portion of the the path when copying. If the input +/// files are from previous build outputs, the prefix should begin with +/// `$builddir/`. pub struct RsyncFiles<'a> { pub inputs: BuildInput, pub target_folder: &'a str, diff --git a/build/ninja_gen/src/sass.rs b/build/ninja_gen/src/sass.rs index 115ef8eaf..d35ecc6c0 100644 --- a/build/ninja_gen/src/sass.rs +++ b/build/ninja_gen/src/sass.rs @@ -1,12 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - action::BuildAction, - cargo::CargoInstall, - input::{space_separated, BuildInput}, - inputs, Build, Result, -}; +use crate::action::BuildAction; +use crate::cargo::CargoInstall; +use crate::input::space_separated; +use crate::input::BuildInput; +use crate::inputs; +use crate::Build; +use crate::Result; pub struct CompileSassWithGrass { pub input: BuildInput, diff --git a/build/runner/src/build.rs b/build/runner/src/build.rs index 0c7f04cea..036d03b56 100644 --- a/build/runner/src/build.rs +++ b/build/runner/src/build.rs @@ -1,11 +1,19 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{env, fs, io::Write, process::Command, time::Instant}; +use std::env; +use std::fs; +use std::io::Write; +use std::process::Command; +use std::time::Instant; use camino::Utf8Path; use clap::Args; -use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; +use termcolor::Color; +use termcolor::ColorChoice; +use termcolor::ColorSpec; +use termcolor::StandardStream; +use termcolor::WriteColor; #[derive(Args)] pub struct BuildArgs { @@ -39,7 +47,8 @@ pub fn run_build(args: BuildArgs) { maybe_reconfigure_build(&build_file, &path); } - // automatically convert foo:bar references to foo_bar, as Ninja can not represent the former + // automatically convert foo:bar references to foo_bar, as Ninja can not + // represent the former let ninja_args = args.args.into_iter().map(|a| a.replace(':', "_")); let start_time = Instant::now(); @@ -66,9 +75,10 @@ pub fn run_build(args: BuildArgs) { // run build let mut status = command.status().expect("ninja not installed"); if !status.success() && Instant::now().duration_since(start_time).as_secs() < 3 { - // if the build fails quickly, there's a reasonable chance that build.ninja references - // a file that has been renamed/deleted. We currently don't capture stderr, so we can't - // confirm, but in case that's the case, we regenerate the build.ninja file then try again. + // if the build fails quickly, there's a reasonable chance that build.ninja + // references a file that has been renamed/deleted. We currently don't + // capture stderr, so we can't confirm, but in case that's the case, we + // regenerate the build.ninja file then try again. bootstrap_build(); status = command.status().expect("ninja missing"); } diff --git a/build/runner/src/bundle/artifacts.rs b/build/runner/src/bundle/artifacts.rs index b9e4dcf0f..b4c2d10ee 100644 --- a/build/runner/src/bundle/artifacts.rs +++ b/build/runner/src/bundle/artifacts.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{env, fs, process::Command}; +use std::env; +use std::fs; +use std::process::Command; use camino::Utf8PathBuf; use clap::Args; @@ -15,8 +17,8 @@ pub struct BuildArtifactsArgs { } pub fn build_artifacts(args: BuildArtifactsArgs) { - // build.rs doesn't declare inputs from venv, so we need to force a rebuild to ensure - // changes to our libs/the venv get included + // build.rs doesn't declare inputs from venv, so we need to force a rebuild to + // ensure changes to our libs/the venv get included let artifacts = args.bundle_root.join("artifacts"); if artifacts.exists() { fs::remove_dir_all(&artifacts).unwrap(); diff --git a/build/runner/src/bundle/folder.rs b/build/runner/src/bundle/folder.rs index 1600981b2..2699e78c0 100644 --- a/build/runner/src/bundle/folder.rs +++ b/build/runner/src/bundle/folder.rs @@ -1,15 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{env, fs, process::Command}; +use std::env; +use std::fs; +use std::process::Command; -use camino::{Utf8Path, Utf8PathBuf}; -use clap::{Args, ValueEnum}; +use camino::Utf8Path; +use camino::Utf8PathBuf; +use clap::Args; +use clap::ValueEnum; -use crate::{ - paths::{absolute_msys_path, unix_path}, - run::run_silent, -}; +use crate::paths::absolute_msys_path; +use crate::paths::unix_path; +use crate::run::run_silent; #[derive(Clone, Copy, ValueEnum, Debug)] enum DistKind { @@ -26,8 +29,8 @@ pub struct BuildDistFolderArgs { pub fn build_dist_folder(args: BuildDistFolderArgs) { let BuildDistFolderArgs { kind, folder_root } = args; fs::create_dir_all(&folder_root).unwrap(); - // Start with Qt, as it's the largest, and we use --delete to ensure there are no - // stale files in lib/. Skipped on macOS as Qt is handled later. + // Start with Qt, as it's the largest, and we use --delete to ensure there are + // no stale files in lib/. Skipped on macOS as Qt is handled later. if !cfg!(target_os = "macos") { copy_qt_from_venv(kind, &folder_root); } diff --git a/build/runner/src/main.rs b/build/runner/src/main.rs index 8bd94256a..63635f261 100644 --- a/build/runner/src/main.rs +++ b/build/runner/src/main.rs @@ -15,18 +15,23 @@ mod yarn; use std::error::Error; -use build::{run_build, BuildArgs}; -use bundle::{ - artifacts::{build_artifacts, BuildArtifactsArgs}, - binary::build_bundle_binary, - folder::{build_dist_folder, BuildDistFolderArgs}, -}; -// use bundle::{build_bundle_binary, build_dist_folder, BuildDistFolderArgs}; -use clap::{Parser, Subcommand}; -use pyenv::{setup_pyenv, PyenvArgs}; -use rsync::{rsync_files, RsyncArgs}; -use run::{run_commands, RunArgs}; -use yarn::{setup_yarn, YarnArgs}; +use build::run_build; +use build::BuildArgs; +use bundle::artifacts::build_artifacts; +use bundle::artifacts::BuildArtifactsArgs; +use bundle::binary::build_bundle_binary; +use bundle::folder::build_dist_folder; +use bundle::folder::BuildDistFolderArgs; +use clap::Parser; +use clap::Subcommand; +use pyenv::setup_pyenv; +use pyenv::PyenvArgs; +use rsync::rsync_files; +use rsync::RsyncArgs; +use run::run_commands; +use run::RunArgs; +use yarn::setup_yarn; +use yarn::YarnArgs; pub type Result> = std::result::Result; diff --git a/build/runner/src/paths.rs b/build/runner/src/paths.rs index 5d5ccc943..2021120cb 100644 --- a/build/runner/src/paths.rs +++ b/build/runner/src/paths.rs @@ -3,8 +3,8 @@ use camino::Utf8Path; -/// On Unix, just a normal path. On Windows, c:\foo\bar.txt becomes /c/foo/bar.txt, -/// which msys rsync expects. +/// On Unix, just a normal path. On Windows, c:\foo\bar.txt becomes +/// /c/foo/bar.txt, which msys rsync expects. pub fn absolute_msys_path(path: &Utf8Path) -> String { let path = path.canonicalize_utf8().unwrap().into_string(); if !cfg!(windows) { diff --git a/build/runner/src/pyenv.rs b/build/runner/src/pyenv.rs index 90f8c62fd..491f0b80d 100644 --- a/build/runner/src/pyenv.rs +++ b/build/runner/src/pyenv.rs @@ -18,7 +18,8 @@ pub struct PyenvArgs { venv_args: Vec, } -/// Set up a venv if one doesn't already exist, and then sync packages with provided requirements file. +/// Set up a venv if one doesn't already exist, and then sync packages with +/// provided requirements file. pub fn setup_pyenv(args: PyenvArgs) { let pyenv_folder = Utf8Path::new(&args.pyenv_folder); @@ -35,8 +36,8 @@ pub fn setup_pyenv(args: PyenvArgs) { ); if cfg!(windows) { - // the first install on Windows throws an error the first time pip is upgraded, so we install - // it twice and swallow the first error + // the first install on Windows throws an error the first time pip is upgraded, + // so we install it twice and swallow the first error let _output = Command::new(&pyenv_python) .args(["-m", "pip", "install", "-r", &args.initial_reqs]) .output() diff --git a/build/runner/src/rsync.rs b/build/runner/src/rsync.rs index ffcd16a71..f8ef8ead1 100644 --- a/build/runner/src/rsync.rs +++ b/build/runner/src/rsync.rs @@ -6,7 +6,8 @@ use std::process::Command; use camino::Utf8Path; use clap::Args; -use crate::{paths::absolute_msys_path, run::run_silent}; +use crate::paths::absolute_msys_path; +use crate::run::run_silent; #[derive(Args)] pub struct RsyncArgs { diff --git a/build/runner/src/run.rs b/build/runner/src/run.rs index 3342ac0f2..a2e67391e 100644 --- a/build/runner/src/run.rs +++ b/build/runner/src/run.rs @@ -1,10 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - io::ErrorKind, - process::{Command, Output}, -}; +use std::io::ErrorKind; +use std::process::Command; +use std::process::Output; use clap::Args; diff --git a/build/runner/src/yarn.rs b/build/runner/src/yarn.rs index 712731d4c..6601e220a 100644 --- a/build/runner/src/yarn.rs +++ b/build/runner/src/yarn.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{path::Path, process::Command}; +use std::path::Path; +use std::process::Command; use clap::Args; @@ -21,8 +22,8 @@ pub fn setup_yarn(args: YarnArgs) { std::fs::write(args.stamp, b"").unwrap(); } -/// Unfortunately a lot of the node ecosystem expects the output folder to reside -/// in the repo root, so we need to link in our output folder. +/// Unfortunately a lot of the node ecosystem expects the output folder to +/// reside in the repo root, so we need to link in our output folder. #[cfg(not(windows))] fn link_node_modules() { let target = Path::new("node_modules"); @@ -35,9 +36,10 @@ fn link_node_modules() { } } -/// Things are more complicated on Windows - having $root/node_modules point to $root/out/node_modules -/// breaks our globs for some reason, so we create the junction in the opposite direction instead. -/// Ninja will have already created some empty folders based on our declared outputs, so we move the +/// Things are more complicated on Windows - having $root/node_modules point to +/// $root/out/node_modules breaks our globs for some reason, so we create the +/// junction in the opposite direction instead. Ninja will have already created +/// some empty folders based on our declared outputs, so we move the /// created folder into the root. #[cfg(windows)] fn link_node_modules() { diff --git a/ftl/sync.rs b/ftl/sync.rs index 987542eec..8461b0303 100644 --- a/ftl/sync.rs +++ b/ftl/sync.rs @@ -8,7 +8,8 @@ use std::process::Command; use camino::Utf8Path; -use snafu::{prelude::*, Whatever}; +use snafu::prelude::*; +use snafu::Whatever; type Result = std::result::Result; diff --git a/pylib/rsbridge/lib.rs b/pylib/rsbridge/lib.rs index 1cfab5791..62ca2dc0d 100644 --- a/pylib/rsbridge/lib.rs +++ b/pylib/rsbridge/lib.rs @@ -1,14 +1,15 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use anki::{ - backend::{init_backend, Backend as RustBackend}, - log::set_global_logger, - sync::http_server::SimpleServer, -}; -use pyo3::{ - create_exception, exceptions::PyException, prelude::*, types::PyBytes, wrap_pyfunction, -}; +use anki::backend::init_backend; +use anki::backend::Backend as RustBackend; +use anki::log::set_global_logger; +use anki::sync::http_server::SimpleServer; +use pyo3::create_exception; +use pyo3::exceptions::PyException; +use pyo3::prelude::*; +use pyo3::types::PyBytes; +use pyo3::wrap_pyfunction; #[pyclass(module = "_rsbridge")] struct Backend { diff --git a/qt/bundle/mac/src/codesign.rs b/qt/bundle/mac/src/codesign.rs index 4f3c21319..fb251521f 100644 --- a/qt/bundle/mac/src/codesign.rs +++ b/qt/bundle/mac/src/codesign.rs @@ -1,10 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{env, process::Command}; +use std::env; +use std::process::Command; -use anyhow::{bail, Result}; -use camino::{Utf8Path, Utf8PathBuf}; +use anyhow::bail; +use anyhow::Result; +use camino::Utf8Path; +use camino::Utf8PathBuf; const CODESIGN_ARGS: &[&str] = &["-vvvv", "-o", "runtime", "-s", "Developer ID Application:"]; diff --git a/qt/bundle/mac/src/dmg.rs b/qt/bundle/mac/src/dmg.rs index 7c15054d0..862150340 100644 --- a/qt/bundle/mac/src/dmg.rs +++ b/qt/bundle/mac/src/dmg.rs @@ -1,10 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs, process::Command}; +use std::fs; +use std::process::Command; -use anyhow::{Context, Result}; -use camino::{Utf8Path, Utf8PathBuf}; +use anyhow::Context; +use anyhow::Result; +use camino::Utf8Path; +use camino::Utf8PathBuf; use clap::Args; use crate::notarize::wait_then_staple_app; diff --git a/qt/bundle/mac/src/main.rs b/qt/bundle/mac/src/main.rs index 597f10157..b98a877a8 100644 --- a/qt/bundle/mac/src/main.rs +++ b/qt/bundle/mac/src/main.rs @@ -10,14 +10,23 @@ mod codesign; mod dmg; mod notarize; -use std::{env, fs, os::unix::prelude::PermissionsExt, process::Command}; +use std::env; +use std::fs; +use std::os::unix::prelude::PermissionsExt; +use std::process::Command; -use anyhow::{bail, Result}; +use anyhow::bail; +use anyhow::Result; use apple_bundles::MacOsApplicationBundleBuilder; -use camino::{Utf8Path, Utf8PathBuf}; -use clap::{Parser, Subcommand, ValueEnum}; -use codesign::{codesign_app, codesign_python_libs}; -use dmg::{make_dmgs, BuildDmgsArgs}; +use camino::Utf8Path; +use camino::Utf8PathBuf; +use clap::Parser; +use clap::Subcommand; +use clap::ValueEnum; +use codesign::codesign_app; +use codesign::codesign_python_libs; +use dmg::make_dmgs; +use dmg::BuildDmgsArgs; use notarize::notarize_app; use plist::Value; use simple_file_manifest::FileEntry; diff --git a/qt/bundle/mac/src/notarize.rs b/qt/bundle/mac/src/notarize.rs index 7b3066efd..da89e1dbf 100644 --- a/qt/bundle/mac/src/notarize.rs +++ b/qt/bundle/mac/src/notarize.rs @@ -1,9 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{env, fs, process::Command}; +use std::env; +use std::fs; +use std::process::Command; -use anyhow::{bail, Context, Result}; +use anyhow::bail; +use anyhow::Context; +use anyhow::Result; use camino::Utf8Path; use serde::Deserialize; diff --git a/qt/bundle/win/src/main.rs b/qt/bundle/win/src/main.rs index 777a86d68..04d4d3c42 100644 --- a/qt/bundle/win/src/main.rs +++ b/qt/bundle/win/src/main.rs @@ -1,12 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs, io::prelude::*, path::Path, process::Command}; +use std::fs; +use std::io::prelude::*; +use std::path::Path; +use std::process::Command; -use anyhow::{bail, Context, Result}; -use camino::{Utf8Path, Utf8PathBuf}; +use anyhow::bail; +use anyhow::Context; +use anyhow::Result; +use camino::Utf8Path; +use camino::Utf8PathBuf; use clap::Parser; -use tugger_windows_codesign::{CodeSigningCertificate, SigntoolSign, SystemStore, TimestampServer}; +use tugger_windows_codesign::CodeSigningCertificate; +use tugger_windows_codesign::SigntoolSign; +use tugger_windows_codesign::SystemStore; +use tugger_windows_codesign::TimestampServer; use walkdir::WalkDir; #[derive(Parser)] diff --git a/rslib/benches/benchmark.rs b/rslib/benches/benchmark.rs index 90cc64d1e..451d9e7d8 100644 --- a/rslib/benches/benchmark.rs +++ b/rslib/benches/benchmark.rs @@ -2,7 +2,9 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use anki::card_rendering::anki_tag_benchmark; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::criterion_group; +use criterion::criterion_main; +use criterion::Criterion; pub fn criterion_benchmark(c: &mut Criterion) { c.bench_function("anki_tag_parse", |b| b.iter(|| anki_tag_benchmark())); diff --git a/rslib/build/protobuf.rs b/rslib/build/protobuf.rs index 09b7aefe2..2d92940f3 100644 --- a/rslib/build/protobuf.rs +++ b/rslib/build/protobuf.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{env, fmt::Write, path::PathBuf}; +use std::env; +use std::fmt::Write; +use std::path::PathBuf; struct CustomGenerator {} diff --git a/rslib/i18n/build/check.rs b/rslib/i18n/build/check.rs index c453c8ebc..f168406d1 100644 --- a/rslib/i18n/build/check.rs +++ b/rslib/i18n/build/check.rs @@ -1,9 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -//! Check the .ftl files at build time to ensure we don't get runtime load failures. +//! Check the .ftl files at build time to ensure we don't get runtime load +//! failures. -use fluent::{FluentBundle, FluentResource}; +use fluent::FluentBundle; +use fluent::FluentResource; use unic_langid::LanguageIdentifier; use super::gather::TranslationsByLang; diff --git a/rslib/i18n/build/extract.rs b/rslib/i18n/build/extract.rs index bd0bb01e0..60efd596c 100644 --- a/rslib/i18n/build/extract.rs +++ b/rslib/i18n/build/extract.rs @@ -1,12 +1,15 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashSet, fmt::Write}; +use std::collections::HashSet; +use std::fmt::Write; -use fluent_syntax::{ - ast::{Entry, Expression, InlineExpression, Pattern, PatternElement}, - parser::parse, -}; +use fluent_syntax::ast::Entry; +use fluent_syntax::ast::Expression; +use fluent_syntax::ast::InlineExpression; +use fluent_syntax::ast::Pattern; +use fluent_syntax::ast::PatternElement; +use fluent_syntax::parser::parse; use serde::Serialize; use crate::gather::TranslationsByLang; @@ -163,7 +166,8 @@ impl Visitor { impl From for Variable { fn from(name: String) -> Self { // rather than adding more items here as we add new strings, we should probably - // try to either reuse existing ones, or consider some sort of Hungarian notation + // try to either reuse existing ones, or consider some sort of Hungarian + // notation let kind = match name.as_str() { "cards" | "notes" | "count" | "amount" | "reviews" | "total" | "selected" | "kilobytes" | "daysStart" | "daysEnd" | "days" | "secs-per-card" | "remaining" diff --git a/rslib/i18n/build/gather.rs b/rslib/i18n/build/gather.rs index e28a8b2ea..eb68776e8 100644 --- a/rslib/i18n/build/gather.rs +++ b/rslib/i18n/build/gather.rs @@ -1,14 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -//! By default, the Qt translations will be included in rslib. EXTRA_FTL_ROOT can be set -//! to an external folder so the mobile clients can use their own translations instead. +//! By default, the Qt translations will be included in rslib. EXTRA_FTL_ROOT +//! can be set to an external folder so the mobile clients can use their own +//! translations instead. -use std::{ - collections::HashMap, - fs, - path::{Path, PathBuf}, -}; +use std::collections::HashMap; +use std::fs; +use std::path::Path; +use std::path::PathBuf; pub type TranslationsByFile = HashMap; pub type TranslationsByLang = HashMap; @@ -26,7 +26,8 @@ pub fn get_ftl_data() -> TranslationsByLang { if let Some(path) = extra_ftl_root() { // Mobile client has requested its own extra translations add_translation_root(&mut map, &path, false); - // In a debug build, also include the Qt translations so that our Python unit tests pass. + // In a debug build, also include the Qt translations so that our Python unit + // tests pass. if std::env::var("RELEASE").is_err() { add_folder(&mut map, &ftl_base.join("qt"), "templates"); } diff --git a/rslib/i18n/build/write_strings.rs b/rslib/i18n/build/write_strings.rs index 85c460b81..5d7e570f7 100644 --- a/rslib/i18n/build/write_strings.rs +++ b/rslib/i18n/build/write_strings.rs @@ -3,14 +3,17 @@ //! Write strings to a strings.rs file that will be compiled into the binary. -use std::{fmt::Write, fs, path::PathBuf}; +use std::fmt::Write; +use std::fs; +use std::path::PathBuf; use inflections::Inflect; -use crate::{ - extract::{Module, Translation, VariableKind}, - gather::{TranslationsByFile, TranslationsByLang}, -}; +use crate::extract::Module; +use crate::extract::Translation; +use crate::extract::VariableKind; +use crate::gather::TranslationsByFile; +use crate::gather::TranslationsByLang; pub fn write_strings(map: &TranslationsByLang, modules: &[Module]) { let mut buf = String::new(); diff --git a/rslib/i18n/src/lib.rs b/rslib/i18n/src/lib.rs index 0650187b0..a2c68c6bb 100644 --- a/rslib/i18n/src/lib.rs +++ b/rslib/i18n/src/lib.rs @@ -3,14 +3,17 @@ mod generated; -use std::{ - borrow::Cow, - sync::{Arc, Mutex}, -}; +use std::borrow::Cow; +use std::sync::Arc; +use std::sync::Mutex; -use fluent::{types::FluentNumber, FluentArgs, FluentResource, FluentValue}; +use fluent::types::FluentNumber; +use fluent::FluentArgs; +use fluent::FluentResource; +use fluent::FluentValue; use fluent_bundle::bundle::FluentBundle as FluentBundleOrig; -use generated::{KEYS_BY_MODULE, STRINGS}; +use generated::KEYS_BY_MODULE; +use generated::STRINGS; use num_format::Locale; use serde::Serialize; use unic_langid::LanguageIdentifier; @@ -265,7 +268,8 @@ impl I18n { key.to_string().into() } - /// Return text from configured locales for use with the JS Fluent implementation. + /// Return text from configured locales for use with the JS Fluent + /// implementation. pub fn resources_for_js(&self, desired_modules: &[String]) -> ResourcesForJavascript { let inner = self.inner.lock().unwrap(); let resources = get_modules(&inner.langs, desired_modules); diff --git a/rslib/i18n_helpers/src/garbage_collection.rs b/rslib/i18n_helpers/src/garbage_collection.rs index bc7125ddb..423428ee7 100644 --- a/rslib/i18n_helpers/src/garbage_collection.rs +++ b/rslib/i18n_helpers/src/garbage_collection.rs @@ -1,19 +1,24 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashSet, fs, io::BufReader, iter::FromIterator}; +use std::collections::HashSet; +use std::fs; +use std::io::BufReader; +use std::iter::FromIterator; -use fluent_syntax::{ast, parser}; +use fluent_syntax::ast; +use fluent_syntax::parser; use lazy_static::lazy_static; use regex::Regex; use serde_json; -use walkdir::{DirEntry, WalkDir}; +use walkdir::DirEntry; +use walkdir::WalkDir; use crate::serialize; -/// Extract references from all Rust, Python, TS, Svelte, Swift and Designer files in -/// the `roots`, convert them to kebab case and write them as a json to the -/// target file. +/// Extract references from all Rust, Python, TS, Svelte, Swift and Designer +/// files in the `roots`, convert them to kebab case and write them as a json to +/// the target file. pub fn extract_ftl_references, S2: AsRef>(roots: &[S1], target: S2) { let mut refs = HashSet::new(); for root in roots { diff --git a/rslib/i18n_helpers/src/serialize.rs b/rslib/i18n_helpers/src/serialize.rs index 7cd9d8806..c6eda559c 100644 --- a/rslib/i18n_helpers/src/serialize.rs +++ b/rslib/i18n_helpers/src/serialize.rs @@ -3,11 +3,12 @@ // copied from https://github.com/projectfluent/fluent-rs/pull/241 -use std::fmt::{ - Error, Write, {self}, -}; +use std::fmt; +use std::fmt::Error; +use std::fmt::Write; -use fluent_syntax::{ast::*, parser::Slice}; +use fluent_syntax::ast::*; +use fluent_syntax::parser::Slice; pub fn serialize<'s, S: Slice<'s>>(resource: &Resource) -> String { serialize_with_options(resource, Options::default()) diff --git a/rslib/linkchecker/tests/links.rs b/rslib/linkchecker/tests/links.rs index 19e6a3e8f..35c5ee23d 100644 --- a/rslib/linkchecker/tests/links.rs +++ b/rslib/linkchecker/tests/links.rs @@ -5,20 +5,22 @@ use anki::links::HelpPage; #[cfg(test)] mod test { - use std::{env, iter}; + use std::env; + use std::iter; use futures::StreamExt; use itertools::Itertools; - use linkcheck::{ - validation::{check_web, Context, Reason}, - BasicContext, - }; + use linkcheck::validation::check_web; + use linkcheck::validation::Context; + use linkcheck::validation::Reason; + use linkcheck::BasicContext; use reqwest::Url; use strum::IntoEnumIterator; use super::*; - /// Aggregates [`Outcome`]s by collecting the error messages of the invalid ones. + /// Aggregates [`Outcome`]s by collecting the error messages of the invalid + /// ones. #[derive(Default)] struct Outcomes(Vec); diff --git a/rslib/src/adding.rs b/rslib/src/adding.rs index a3994ee92..fba879e15 100644 --- a/rslib/src/adding.rs +++ b/rslib/src/adding.rs @@ -15,8 +15,9 @@ impl Collection { /// /// - When 'default to the current deck' is enabled, we use the current deck /// if it's normal, the provided reviewer card's deck as a fallback, and - /// Default as a final fallback. We then fetch the last used notetype stored - /// in the deck, falling back to the global notetype, or the first available one. + /// Default as a final fallback. We then fetch the last used notetype + /// stored in the deck, falling back to the global notetype, or the first + /// available one. /// /// - Otherwise, each note type remembers the last deck cards were added to, /// and we use that, defaulting to the current deck if missing, and @@ -49,7 +50,8 @@ impl Collection { }) } - /// The currently selected deck, the home deck of the provided card, or the default deck. + /// The currently selected deck, the home deck of the provided card, or the + /// default deck. fn get_current_deck_for_adding( &mut self, home_deck_of_reviewer_card: DeckId, @@ -96,9 +98,10 @@ impl Collection { } /// Returns the last deck added to with this notetype, provided it is valid. - /// This is optional due to the inconsistent handling, where changes in notetype - /// may need to update the current deck, but not vice versa. If a previous deck is - /// not set, we want to keep the current selection, instead of resetting it. + /// This is optional due to the inconsistent handling, where changes in + /// notetype may need to update the current deck, but not vice versa. If + /// a previous deck is not set, we want to keep the current selection, + /// instead of resetting it. pub(crate) fn default_deck_for_notetype(&mut self, ntid: NotetypeId) -> Result> { if let Some(last_deck_id) = self.get_last_deck_added_to_for_notetype(ntid) { if let Some(deck) = self.get_deck(last_deck_id)? { diff --git a/rslib/src/backend/adding.rs b/rslib/src/backend/adding.rs index 515e1e79c..b0f8da28f 100644 --- a/rslib/src/backend/adding.rs +++ b/rslib/src/backend/adding.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{adding::DeckAndNotetype, pb::notes::DeckAndNotetype as DeckAndNotetypeProto}; +use crate::adding::DeckAndNotetype; +use crate::pb::notes::DeckAndNotetype as DeckAndNotetypeProto; impl From for DeckAndNotetypeProto { fn from(s: DeckAndNotetype) -> Self { diff --git a/rslib/src/backend/ankidroid/db.rs b/rslib/src/backend/ankidroid/db.rs index be5668eb6..70e901cbc 100644 --- a/rslib/src/backend/ankidroid/db.rs +++ b/rslib/src/backend/ankidroid/db.rs @@ -1,29 +1,27 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::HashMap, - mem::size_of, - sync::{ - atomic::{AtomicI32, Ordering}, - Mutex, - }, -}; +use std::collections::HashMap; +use std::mem::size_of; +use std::sync::atomic::AtomicI32; +use std::sync::atomic::Ordering; +use std::sync::Mutex; -use itertools::{ - FoldWhile, - FoldWhile::{Continue, Done}, - Itertools, -}; +use itertools::FoldWhile; +use itertools::FoldWhile::Continue; +use itertools::FoldWhile::Done; +use itertools::Itertools; use lazy_static::lazy_static; use rusqlite::ToSql; use serde_derive::Deserialize; -use crate::{ - collection::Collection, - error::Result, - pb::ankidroid::{sql_value::Data, DbResponse, DbResult, Row, SqlValue}, -}; +use crate::collection::Collection; +use crate::error::Result; +use crate::pb::ankidroid::sql_value::Data; +use crate::pb::ankidroid::DbResponse; +use crate::pb::ankidroid::DbResult; +use crate::pb::ankidroid::Row; +use crate::pb::ankidroid::SqlValue; /// A pointer to the SqliteStorage object stored in a collection, used to /// uniquely index results from multiple open collections at once. @@ -76,9 +74,10 @@ impl Sizable for Row { impl Sizable for DbResult { fn estimate_size(&self) -> usize { - // Performance: It might be best to take the first x rows and determine the data types - // If we have floats or longs, they'll be a fixed size (excluding nulls) and should speed - // up the calculation as we'll only calculate a subset of the columns. + // Performance: It might be best to take the first x rows and determine the data + // types If we have floats or longs, they'll be a fixed size (excluding + // nulls) and should speed up the calculation as we'll only calculate a + // subset of the columns. self.rows.iter().map(|x| x.estimate_size()).sum() } } @@ -96,8 +95,9 @@ fn select_slice_of_size<'a>( let init: Vec = Vec::new(); rows.fold_while((0, init), |mut acc, x| { let new_size = acc.0 + x.estimate_size(); - // If the accumulator is 0, but we're over the size: return a single result so we don't loop forever. - // Theoretically, this shouldn't happen as data should be reasonably sized + // If the accumulator is 0, but we're over the size: return a single result so + // we don't loop forever. Theoretically, this shouldn't happen as data + // should be reasonably sized if new_size > max_size && acc.0 > 0 { Done(acc) } else { @@ -147,7 +147,8 @@ pub(crate) fn trim_and_cache_remaining( ) -> DbResponse { let start_index = 0; - // PERF: Could speed this up by not creating the vector and just calculating the count + // PERF: Could speed this up by not creating the vector and just calculating the + // count let first_result = select_next_slice(values.rows.iter()); let row_count = values.rows.len() as i32; @@ -279,11 +280,12 @@ pub(crate) fn execute_for_row_count(col: &Collection, req: &[u8]) -> Result #[cfg(test)] mod tests { use super::*; - use crate::{ - backend::ankidroid::db::{select_slice_of_size, Sizable}, - collection::open_test_collection, - pb::ankidroid::{sql_value, Row, SqlValue}, - }; + use crate::backend::ankidroid::db::select_slice_of_size; + use crate::backend::ankidroid::db::Sizable; + use crate::collection::open_test_collection; + use crate::pb::ankidroid::sql_value; + use crate::pb::ankidroid::Row; + use crate::pb::ankidroid::SqlValue; fn gen_data() -> Vec { vec![ diff --git a/rslib/src/backend/ankidroid/error.rs b/rslib/src/backend/ankidroid/error.rs index c1c24615f..4f92faf97 100644 --- a/rslib/src/backend/ankidroid/error.rs +++ b/rslib/src/backend/ankidroid/error.rs @@ -1,13 +1,17 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - error::{ - DbError, DbErrorKind as DB, FilteredDeckError, InvalidInputError, NetworkError, - NetworkErrorKind as Net, NotFoundError, SearchErrorKind, SyncError, SyncErrorKind as Sync, - }, - prelude::AnkiError, -}; +use crate::error::DbError; +use crate::error::DbErrorKind as DB; +use crate::error::FilteredDeckError; +use crate::error::InvalidInputError; +use crate::error::NetworkError; +use crate::error::NetworkErrorKind as Net; +use crate::error::NotFoundError; +use crate::error::SearchErrorKind; +use crate::error::SyncError; +use crate::error::SyncErrorKind as Sync; +use crate::prelude::AnkiError; pub(super) fn debug_produce_error(s: &str) -> AnkiError { let info = "error_value".to_string(); diff --git a/rslib/src/backend/ankidroid/mod.rs b/rslib/src/backend/ankidroid/mod.rs index 26881a059..72e52681e 100644 --- a/rslib/src/backend/ankidroid/mod.rs +++ b/rslib/src/backend/ankidroid/mod.rs @@ -4,23 +4,25 @@ pub(crate) mod db; pub(crate) mod error; -use self::{db::active_sequences, error::debug_produce_error}; -use super::{ - dbproxy::{db_command_bytes, db_command_proto}, - Backend, -}; +use self::db::active_sequences; +use self::error::debug_produce_error; +use super::dbproxy::db_command_bytes; +use super::dbproxy::db_command_proto; +use super::Backend; +use crate::backend::ankidroid::db::execute_for_row_count; +use crate::backend::ankidroid::db::insert_for_id; +use crate::pb; pub(super) use crate::pb::ankidroid::ankidroid_service::Service as AnkidroidService; -use crate::{ - backend::ankidroid::db::{execute_for_row_count, insert_for_id}, - pb, - pb::{ - ankidroid::{DbResponse, GetActiveSequenceNumbersResponse, GetNextResultPageRequest}, - generic, - generic::{Empty, Int32, Json}, - }, - prelude::*, - scheduler::{timing, timing::fixed_offset_from_minutes}, -}; +use crate::pb::ankidroid::DbResponse; +use crate::pb::ankidroid::GetActiveSequenceNumbersResponse; +use crate::pb::ankidroid::GetNextResultPageRequest; +use crate::pb::generic; +use crate::pb::generic::Empty; +use crate::pb::generic::Int32; +use crate::pb::generic::Json; +use crate::prelude::*; +use crate::scheduler::timing; +use crate::scheduler::timing::fixed_offset_from_minutes; impl AnkidroidService for Backend { fn sched_timing_today_legacy( diff --git a/rslib/src/backend/card.rs b/rslib/src/backend/card.rs index 324691d27..a8adbcc0b 100644 --- a/rslib/src/backend/card.rs +++ b/rslib/src/backend/card.rs @@ -2,12 +2,11 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::Backend; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::pb; pub(super) use crate::pb::cards::cards_service::Service as CardsService; -use crate::{ - card::{CardQueue, CardType}, - pb, - prelude::*, -}; +use crate::prelude::*; impl CardsService for Backend { fn get_card(&self, input: pb::cards::CardId) -> Result { diff --git a/rslib/src/backend/cardrendering.rs b/rslib/src/backend/cardrendering.rs index 2cf51e1ae..363c80793 100644 --- a/rslib/src/backend/cardrendering.rs +++ b/rslib/src/backend/cardrendering.rs @@ -2,21 +2,24 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::Backend; +use crate::card_rendering::extract_av_tags; +use crate::card_rendering::strip_av_tags; +use crate::latex::extract_latex; +use crate::latex::extract_latex_expanding_clozes; +use crate::latex::ExtractedLatex; +use crate::markdown::render_markdown; +use crate::notetype::CardTemplateSchema11; +use crate::notetype::RenderCardOutput; +use crate::pb; pub(super) use crate::pb::card_rendering::cardrendering_service::Service as CardRenderingService; -use crate::{ - card_rendering::{extract_av_tags, strip_av_tags}, - latex::{extract_latex, extract_latex_expanding_clozes, ExtractedLatex}, - markdown::render_markdown, - notetype::{CardTemplateSchema11, RenderCardOutput}, - pb, - prelude::*, - template::RenderedNode, - text::{ - decode_iri_paths, encode_iri_paths, sanitize_html_no_images, strip_html, - strip_html_preserving_media_filenames, - }, - typeanswer::compare_answer, -}; +use crate::prelude::*; +use crate::template::RenderedNode; +use crate::text::decode_iri_paths; +use crate::text::encode_iri_paths; +use crate::text::sanitize_html_no_images; +use crate::text::strip_html; +use crate::text::strip_html_preserving_media_filenames; +use crate::typeanswer::compare_answer; impl CardRenderingService for Backend { fn extract_av_tags( diff --git a/rslib/src/backend/collection.rs b/rslib/src/backend/collection.rs index 8ba1fc4a7..82d5ac818 100644 --- a/rslib/src/backend/collection.rs +++ b/rslib/src/backend/collection.rs @@ -5,12 +5,14 @@ use std::sync::MutexGuard; use tracing::error; -use super::{progress::Progress, Backend}; +use super::progress::Progress; +use super::Backend; +use crate::backend::progress::progress_to_proto; +use crate::collection::CollectionBuilder; +use crate::pb; pub(super) use crate::pb::collection::collection_service::Service as CollectionService; -use crate::{ - backend::progress::progress_to_proto, collection::CollectionBuilder, pb, prelude::*, - storage::SchemaVersion, -}; +use crate::prelude::*; +use crate::storage::SchemaVersion; impl CollectionService for Backend { fn latest_progress(&self, _input: pb::generic::Empty) -> Result { diff --git a/rslib/src/backend/config.rs b/rslib/src/backend/config.rs index 9b41030bc..f041a0043 100644 --- a/rslib/src/backend/config.rs +++ b/rslib/src/backend/config.rs @@ -4,13 +4,13 @@ use serde_json::Value; use super::Backend; +use crate::config::BoolKey; +use crate::config::StringKey; +use crate::pb; +use crate::pb::config::config_key::Bool as BoolKeyProto; +use crate::pb::config::config_key::String as StringKeyProto; pub(super) use crate::pb::config::config_service::Service as ConfigService; -use crate::{ - config::{BoolKey, StringKey}, - pb, - pb::config::config_key::{Bool as BoolKeyProto, String as StringKeyProto}, - prelude::*, -}; +use crate::prelude::*; impl From for BoolKey { fn from(k: BoolKeyProto) -> Self { diff --git a/rslib/src/backend/dbproxy.rs b/rslib/src/backend/dbproxy.rs index 0738b3d1b..a977bad7f 100644 --- a/rslib/src/backend/dbproxy.rs +++ b/rslib/src/backend/dbproxy.rs @@ -1,21 +1,24 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use rusqlite::{ - params_from_iter, - types::{FromSql, FromSqlError, ToSql, ToSqlOutput, ValueRef}, - OptionalExtension, -}; -use serde_derive::{Deserialize, Serialize}; +use rusqlite::params_from_iter; +use rusqlite::types::FromSql; +use rusqlite::types::FromSqlError; +use rusqlite::types::ToSql; +use rusqlite::types::ToSqlOutput; +use rusqlite::types::ValueRef; +use rusqlite::OptionalExtension; +use serde_derive::Deserialize; +use serde_derive::Serialize; -use crate::{ - pb, - pb::ankidroid::{ - sql_value::Data, DbResponse, DbResult as ProtoDbResult, Row, SqlValue as pb_SqlValue, - }, - prelude::*, - storage::SqliteStorage, -}; +use crate::pb; +use crate::pb::ankidroid::sql_value::Data; +use crate::pb::ankidroid::DbResponse; +use crate::pb::ankidroid::DbResult as ProtoDbResult; +use crate::pb::ankidroid::Row; +use crate::pb::ankidroid::SqlValue as pb_SqlValue; +use crate::prelude::*; +use crate::storage::SqliteStorage; #[derive(Deserialize)] #[serde(tag = "kind", rename_all = "lowercase")] diff --git a/rslib/src/backend/deckconfig.rs b/rslib/src/backend/deckconfig.rs index b6e6f8c45..3c107924d 100644 --- a/rslib/src/backend/deckconfig.rs +++ b/rslib/src/backend/deckconfig.rs @@ -2,12 +2,12 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::Backend; +use crate::deckconfig::DeckConfSchema11; +use crate::deckconfig::DeckConfig; +use crate::deckconfig::UpdateDeckConfigsRequest; +use crate::pb; pub(super) use crate::pb::deckconfig::deckconfig_service::Service as DeckConfigService; -use crate::{ - deckconfig::{DeckConfSchema11, DeckConfig, UpdateDeckConfigsRequest}, - pb, - prelude::*, -}; +use crate::prelude::*; impl DeckConfigService for Backend { fn add_or_update_deck_config_legacy( diff --git a/rslib/src/backend/decks.rs b/rslib/src/backend/decks.rs index 72605935d..bfa64dfa9 100644 --- a/rslib/src/backend/decks.rs +++ b/rslib/src/backend/decks.rs @@ -4,13 +4,12 @@ use std::convert::TryFrom; use super::Backend; +use crate::decks::DeckSchema11; +use crate::decks::FilteredSearchOrder; +use crate::pb; pub(super) use crate::pb::decks::decks_service::Service as DecksService; -use crate::{ - decks::{DeckSchema11, FilteredSearchOrder}, - pb, - prelude::*, - scheduler::filtered::FilteredDeckForUpdate, -}; +use crate::prelude::*; +use crate::scheduler::filtered::FilteredDeckForUpdate; impl DecksService for Backend { fn new_deck(&self, _input: pb::generic::Empty) -> Result { diff --git a/rslib/src/backend/error.rs b/rslib/src/backend/error.rs index 052091657..7f670d14d 100644 --- a/rslib/src/backend/error.rs +++ b/rslib/src/backend/error.rs @@ -1,12 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - error::{AnkiError, SyncErrorKind}, - pb, - pb::backend::backend_error::Kind, - prelude::*, -}; +use crate::error::AnkiError; +use crate::error::SyncErrorKind; +use crate::pb; +use crate::pb::backend::backend_error::Kind; +use crate::prelude::*; impl AnkiError { pub fn into_protobuf(self, tr: &I18n) -> pb::backend::BackendError { diff --git a/rslib/src/backend/generic.rs b/rslib/src/backend/generic.rs index 6d272618d..43ed4215d 100644 --- a/rslib/src/backend/generic.rs +++ b/rslib/src/backend/generic.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, prelude::*}; +use crate::pb; +use crate::prelude::*; impl From> for pb::generic::Json { fn from(json: Vec) -> Self { diff --git a/rslib/src/backend/i18n.rs b/rslib/src/backend/i18n.rs index 25261cb0e..9996b0314 100644 --- a/rslib/src/backend/i18n.rs +++ b/rslib/src/backend/i18n.rs @@ -3,15 +3,15 @@ use std::collections::HashMap; -use fluent::{FluentArgs, FluentValue}; +use fluent::FluentArgs; +use fluent::FluentValue; use super::Backend; +use crate::pb; pub(super) use crate::pb::i18n::i18n_service::Service as I18nService; -use crate::{ - pb, - prelude::*, - scheduler::timespan::{answer_button_time, time_span}, -}; +use crate::prelude::*; +use crate::scheduler::timespan::answer_button_time; +use crate::scheduler::timespan::time_span; impl I18nService for Backend { fn translate_string( diff --git a/rslib/src/backend/import_export.rs b/rslib/src/backend/import_export.rs index 4a857a87e..d4dd2e2b3 100644 --- a/rslib/src/backend/import_export.rs +++ b/rslib/src/backend/import_export.rs @@ -3,15 +3,18 @@ use std::path::Path; -use super::{progress::Progress, Backend}; +use super::progress::Progress; +use super::Backend; +use crate::import_export::package::import_colpkg; +use crate::import_export::ExportProgress; +use crate::import_export::ImportProgress; +use crate::import_export::NoteLog; +use crate::pb; +use crate::pb::import_export::export_limit; pub(super) use crate::pb::import_export::importexport_service::Service as ImportExportService; -use crate::{ - import_export::{package::import_colpkg, ExportProgress, ImportProgress, NoteLog}, - pb, - pb::import_export::{export_limit, ExportLimit}, - prelude::*, - search::SearchNode, -}; +use crate::pb::import_export::ExportLimit; +use crate::prelude::*; +use crate::search::SearchNode; impl ImportExportService for Backend { fn export_collection_package( diff --git a/rslib/src/backend/links.rs b/rslib/src/backend/links.rs index 59661cb6f..69e649583 100644 --- a/rslib/src/backend/links.rs +++ b/rslib/src/backend/links.rs @@ -2,8 +2,10 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::Backend; +use crate::pb; +use crate::pb::links::help_page_link_request::HelpPage; pub(super) use crate::pb::links::links_service::Service as LinksService; -use crate::{pb, pb::links::help_page_link_request::HelpPage, prelude::*}; +use crate::prelude::*; impl LinksService for Backend { fn help_page_link(&self, input: pb::links::HelpPageLinkRequest) -> Result { diff --git a/rslib/src/backend/media.rs b/rslib/src/backend/media.rs index d30cc6a69..6b6abed8c 100644 --- a/rslib/src/backend/media.rs +++ b/rslib/src/backend/media.rs @@ -1,9 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{progress::Progress, Backend}; +use super::progress::Progress; +use super::Backend; +use crate::media::check::MediaChecker; +use crate::pb; pub(super) use crate::pb::media::media_service::Service as MediaService; -use crate::{media::check::MediaChecker, pb, prelude::*}; +use crate::prelude::*; impl MediaService for Backend { // media diff --git a/rslib/src/backend/mod.rs b/rslib/src/backend/mod.rs index 4bba04f36..0af56e3a6 100644 --- a/rslib/src/backend/mod.rs +++ b/rslib/src/backend/mod.rs @@ -29,39 +29,41 @@ mod stats; mod sync; mod tags; -use std::{ - result, - sync::{Arc, Mutex}, - thread::JoinHandle, -}; +use std::result; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread::JoinHandle; use once_cell::sync::OnceCell; use progress::AbortHandleSlot; use prost::Message; -use tokio::{runtime, runtime::Runtime}; +use tokio::runtime; +use tokio::runtime::Runtime; -use self::{ - ankidroid::AnkidroidService, - card::CardsService, - cardrendering::CardRenderingService, - collection::CollectionService, - config::ConfigService, - deckconfig::DeckConfigService, - decks::DecksService, - i18n::I18nService, - import_export::ImportExportService, - links::LinksService, - media::MediaService, - notes::NotesService, - notetypes::NotetypesService, - progress::ProgressState, - scheduler::SchedulerService, - search::SearchService, - stats::StatsService, - sync::{SyncService, SyncState}, - tags::TagsService, -}; -use crate::{backend::dbproxy::db_command_bytes, pb, pb::backend::ServiceIndex, prelude::*}; +use self::ankidroid::AnkidroidService; +use self::card::CardsService; +use self::cardrendering::CardRenderingService; +use self::collection::CollectionService; +use self::config::ConfigService; +use self::deckconfig::DeckConfigService; +use self::decks::DecksService; +use self::i18n::I18nService; +use self::import_export::ImportExportService; +use self::links::LinksService; +use self::media::MediaService; +use self::notes::NotesService; +use self::notetypes::NotetypesService; +use self::progress::ProgressState; +use self::scheduler::SchedulerService; +use self::search::SearchService; +use self::stats::StatsService; +use self::sync::SyncService; +use self::sync::SyncState; +use self::tags::TagsService; +use crate::backend::dbproxy::db_command_bytes; +use crate::pb; +use crate::pb::backend::ServiceIndex; +use crate::prelude::*; pub struct Backend { col: Arc>>, diff --git a/rslib/src/backend/notes.rs b/rslib/src/backend/notes.rs index 695d16621..0fbd26fc0 100644 --- a/rslib/src/backend/notes.rs +++ b/rslib/src/backend/notes.rs @@ -4,8 +4,10 @@ use std::collections::HashSet; use super::Backend; +use crate::cloze::add_cloze_numbers_in_string; +use crate::pb; pub(super) use crate::pb::notes::notes_service::Service as NotesService; -use crate::{cloze::add_cloze_numbers_in_string, pb, prelude::*}; +use crate::prelude::*; impl NotesService for Backend { fn new_note(&self, input: pb::notetypes::NotetypeId) -> Result { diff --git a/rslib/src/backend/notetypes.rs b/rslib/src/backend/notetypes.rs index 6fab603e8..a5837d531 100644 --- a/rslib/src/backend/notetypes.rs +++ b/rslib/src/backend/notetypes.rs @@ -2,15 +2,15 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::Backend; +use crate::config::get_aux_notetype_config_key; +use crate::notetype::all_stock_notetypes; +use crate::notetype::ChangeNotetypeInput; +use crate::notetype::Notetype; +use crate::notetype::NotetypeChangeInfo; +use crate::notetype::NotetypeSchema11; +use crate::pb; pub(super) use crate::pb::notetypes::notetypes_service::Service as NotetypesService; -use crate::{ - config::get_aux_notetype_config_key, - notetype::{ - all_stock_notetypes, ChangeNotetypeInput, Notetype, NotetypeChangeInfo, NotetypeSchema11, - }, - pb, - prelude::*, -}; +use crate::prelude::*; impl NotetypesService for Backend { fn add_notetype( diff --git a/rslib/src/backend/ops.rs b/rslib/src/backend/ops.rs index c08875ae9..fd0f61ef4 100644 --- a/rslib/src/backend/ops.rs +++ b/rslib/src/backend/ops.rs @@ -1,12 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - ops::OpChanges, - pb, - prelude::*, - undo::{UndoOutput, UndoStatus}, -}; +use crate::ops::OpChanges; +use crate::pb; +use crate::prelude::*; +use crate::undo::UndoOutput; +use crate::undo::UndoStatus; impl From for pb::collection::OpChanges { fn from(c: OpChanges) -> Self { diff --git a/rslib/src/backend/progress.rs b/rslib/src/backend/progress.rs index 0d10e9cc5..6bbbcd401 100644 --- a/rslib/src/backend/progress.rs +++ b/rslib/src/backend/progress.rs @@ -1,24 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::sync::{Arc, Mutex}; +use std::sync::Arc; +use std::sync::Mutex; use futures::future::AbortHandle; use super::Backend; -use crate::{ - dbcheck::DatabaseCheckProgress, - i18n::I18n, - import_export::{ExportProgress, ImportProgress}, - pb, - sync::{ - collection::{ - normal::NormalSyncProgress, - progress::{FullSyncProgress, SyncStage}, - }, - media::progress::MediaSyncProgress, - }, -}; +use crate::dbcheck::DatabaseCheckProgress; +use crate::i18n::I18n; +use crate::import_export::ExportProgress; +use crate::import_export::ImportProgress; +use crate::pb; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::progress::FullSyncProgress; +use crate::sync::collection::progress::SyncStage; +use crate::sync::media::progress::MediaSyncProgress; pub(super) struct ThrottlingProgressHandler { pub state: Arc>, diff --git a/rslib/src/backend/scheduler/answering.rs b/rslib/src/backend/scheduler/answering.rs index d6c376cd5..5dfeb944f 100644 --- a/rslib/src/backend/scheduler/answering.rs +++ b/rslib/src/backend/scheduler/answering.rs @@ -3,14 +3,12 @@ use std::mem; -use crate::{ - pb, - prelude::*, - scheduler::{ - answering::{CardAnswer, Rating}, - queue::{QueuedCard, QueuedCards}, - }, -}; +use crate::pb; +use crate::prelude::*; +use crate::scheduler::answering::CardAnswer; +use crate::scheduler::answering::Rating; +use crate::scheduler::queue::QueuedCard; +use crate::scheduler::queue::QueuedCards; impl From for CardAnswer { fn from(mut answer: pb::scheduler::CardAnswer) -> Self { diff --git a/rslib/src/backend/scheduler/mod.rs b/rslib/src/backend/scheduler/mod.rs index 164a1574d..15b0506d8 100644 --- a/rslib/src/backend/scheduler/mod.rs +++ b/rslib/src/backend/scheduler/mod.rs @@ -5,20 +5,17 @@ mod answering; mod states; use super::Backend; +use crate::pb; pub(super) use crate::pb::scheduler::scheduler_service::Service as SchedulerService; -use crate::{ - pb, - prelude::*, - scheduler::{ - new::NewCardDueOrder, - states::{CardState, SchedulingStates}, - }, - stats::studied_today, -}; +use crate::prelude::*; +use crate::scheduler::new::NewCardDueOrder; +use crate::scheduler::states::CardState; +use crate::scheduler::states::SchedulingStates; +use crate::stats::studied_today; impl SchedulerService for Backend { - /// This behaves like _updateCutoff() in older code - it also unburies at the start of - /// a new day. + /// This behaves like _updateCutoff() in older code - it also unburies at + /// the start of a new day. fn sched_timing_today( &self, _input: pb::generic::Empty, diff --git a/rslib/src/backend/scheduler/states/filtered.rs b/rslib/src/backend/scheduler/states/filtered.rs index 744379947..56733f614 100644 --- a/rslib/src/backend/scheduler/states/filtered.rs +++ b/rslib/src/backend/scheduler/states/filtered.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::FilteredState}; +use crate::pb; +use crate::scheduler::states::FilteredState; impl From for pb::scheduler::scheduling_state::Filtered { fn from(state: FilteredState) -> Self { diff --git a/rslib/src/backend/scheduler/states/learning.rs b/rslib/src/backend/scheduler/states/learning.rs index 34bd78a30..f165bac12 100644 --- a/rslib/src/backend/scheduler/states/learning.rs +++ b/rslib/src/backend/scheduler/states/learning.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::LearnState}; +use crate::pb; +use crate::scheduler::states::LearnState; impl From for LearnState { fn from(state: pb::scheduler::scheduling_state::Learning) -> Self { diff --git a/rslib/src/backend/scheduler/states/mod.rs b/rslib/src/backend/scheduler/states/mod.rs index 7e1f55198..ee1722b7a 100644 --- a/rslib/src/backend/scheduler/states/mod.rs +++ b/rslib/src/backend/scheduler/states/mod.rs @@ -10,10 +10,11 @@ mod relearning; mod rescheduling; mod review; -use crate::{ - pb, - scheduler::states::{CardState, NewState, NormalState, SchedulingStates}, -}; +use crate::pb; +use crate::scheduler::states::CardState; +use crate::scheduler::states::NewState; +use crate::scheduler::states::NormalState; +use crate::scheduler::states::SchedulingStates; impl From for pb::scheduler::SchedulingStates { fn from(choices: SchedulingStates) -> Self { diff --git a/rslib/src/backend/scheduler/states/new.rs b/rslib/src/backend/scheduler/states/new.rs index 48eadbacb..9b866951a 100644 --- a/rslib/src/backend/scheduler/states/new.rs +++ b/rslib/src/backend/scheduler/states/new.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::NewState}; +use crate::pb; +use crate::scheduler::states::NewState; impl From for NewState { fn from(state: pb::scheduler::scheduling_state::New) -> Self { diff --git a/rslib/src/backend/scheduler/states/normal.rs b/rslib/src/backend/scheduler/states/normal.rs index c9e366808..457e2f342 100644 --- a/rslib/src/backend/scheduler/states/normal.rs +++ b/rslib/src/backend/scheduler/states/normal.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::NormalState}; +use crate::pb; +use crate::scheduler::states::NormalState; impl From for pb::scheduler::scheduling_state::Normal { fn from(state: NormalState) -> Self { diff --git a/rslib/src/backend/scheduler/states/preview.rs b/rslib/src/backend/scheduler/states/preview.rs index 96c228e95..b6d457f2a 100644 --- a/rslib/src/backend/scheduler/states/preview.rs +++ b/rslib/src/backend/scheduler/states/preview.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::PreviewState}; +use crate::pb; +use crate::scheduler::states::PreviewState; impl From for PreviewState { fn from(state: pb::scheduler::scheduling_state::Preview) -> Self { diff --git a/rslib/src/backend/scheduler/states/relearning.rs b/rslib/src/backend/scheduler/states/relearning.rs index f99e4a969..2d2fa9405 100644 --- a/rslib/src/backend/scheduler/states/relearning.rs +++ b/rslib/src/backend/scheduler/states/relearning.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::RelearnState}; +use crate::pb; +use crate::scheduler::states::RelearnState; impl From for RelearnState { fn from(state: pb::scheduler::scheduling_state::Relearning) -> Self { diff --git a/rslib/src/backend/scheduler/states/rescheduling.rs b/rslib/src/backend/scheduler/states/rescheduling.rs index 5fe37a4fa..d2ad5f416 100644 --- a/rslib/src/backend/scheduler/states/rescheduling.rs +++ b/rslib/src/backend/scheduler/states/rescheduling.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::ReschedulingFilterState}; +use crate::pb; +use crate::scheduler::states::ReschedulingFilterState; impl From for ReschedulingFilterState { fn from(state: pb::scheduler::scheduling_state::ReschedulingFilter) -> Self { diff --git a/rslib/src/backend/scheduler/states/review.rs b/rslib/src/backend/scheduler/states/review.rs index ab4eb5386..b175f31f1 100644 --- a/rslib/src/backend/scheduler/states/review.rs +++ b/rslib/src/backend/scheduler/states/review.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, scheduler::states::ReviewState}; +use crate::pb; +use crate::scheduler::states::ReviewState; impl From for ReviewState { fn from(state: pb::scheduler::scheduling_state::Review) -> Self { diff --git a/rslib/src/backend/search/browser_table.rs b/rslib/src/backend/search/browser_table.rs index c743266fb..cfa08f902 100644 --- a/rslib/src/backend/search/browser_table.rs +++ b/rslib/src/backend/search/browser_table.rs @@ -3,7 +3,9 @@ use std::str::FromStr; -use crate::{browser_table, i18n::I18n, pb}; +use crate::browser_table; +use crate::i18n::I18n; +use crate::pb; impl browser_table::Column { pub fn to_pb_column(self, i18n: &I18n) -> pb::search::browser_columns::Column { diff --git a/rslib/src/backend/search/mod.rs b/rslib/src/backend/search/mod.rs index 5066edf58..905c2588a 100644 --- a/rslib/src/backend/search/mod.rs +++ b/rslib/src/backend/search/mod.rs @@ -4,17 +4,20 @@ mod browser_table; mod search_node; -use std::{str::FromStr, sync::Arc}; +use std::str::FromStr; +use std::sync::Arc; -use super::{notes::to_note_ids, Backend}; +use super::notes::to_note_ids; +use super::Backend; +use crate::browser_table::Column; +use crate::pb; pub(super) use crate::pb::search::search_service::Service as SearchService; -use crate::{ - browser_table::Column, - pb, - pb::search::sort_order::Value as SortOrderProto, - prelude::*, - search::{replace_search_node, JoinSearches, Node, SortMode}, -}; +use crate::pb::search::sort_order::Value as SortOrderProto; +use crate::prelude::*; +use crate::search::replace_search_node; +use crate::search::JoinSearches; +use crate::search::Node; +use crate::search::SortMode; impl SearchService for Backend { fn build_search_string(&self, input: pb::search::SearchNode) -> Result { diff --git a/rslib/src/backend/search/search_node.rs b/rslib/src/backend/search/search_node.rs index bd8e3f119..907f69a98 100644 --- a/rslib/src/backend/search/search_node.rs +++ b/rslib/src/backend/search/search_node.rs @@ -3,20 +3,26 @@ use itertools::Itertools; -use crate::{ - pb, - prelude::*, - search::{ - parse_search, Negated, Node, PropertyKind, RatingKind, SearchNode, StateKind, TemplateKind, - }, - text::{escape_anki_wildcards, escape_anki_wildcards_for_search_node}, -}; +use crate::pb; +use crate::prelude::*; +use crate::search::parse_search; +use crate::search::Negated; +use crate::search::Node; +use crate::search::PropertyKind; +use crate::search::RatingKind; +use crate::search::SearchNode; +use crate::search::StateKind; +use crate::search::TemplateKind; +use crate::text::escape_anki_wildcards; +use crate::text::escape_anki_wildcards_for_search_node; impl TryFrom for Node { type Error = AnkiError; fn try_from(msg: pb::search::SearchNode) -> std::result::Result { - use pb::search::search_node::{group::Joiner, Filter, Flag}; + use pb::search::search_node::group::Joiner; + use pb::search::search_node::Filter; + use pb::search::search_node::Flag; Ok(if let Some(filter) = msg.filter { match filter { Filter::Tag(s) => SearchNode::from_tag_name(&s).into(), diff --git a/rslib/src/backend/stats.rs b/rslib/src/backend/stats.rs index ee3470eb0..7ac9c8caa 100644 --- a/rslib/src/backend/stats.rs +++ b/rslib/src/backend/stats.rs @@ -2,8 +2,10 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::Backend; +use crate::pb; pub(super) use crate::pb::stats::stats_service::Service as StatsService; -use crate::{pb, prelude::*, revlog::RevlogReviewKind}; +use crate::prelude::*; +use crate::revlog::RevlogReviewKind; impl StatsService for Backend { fn card_stats(&self, input: pb::cards::CardId) -> Result { diff --git a/rslib/src/backend/sync/mod.rs b/rslib/src/backend/sync/mod.rs index dc629c55a..4c7aba72b 100644 --- a/rslib/src/backend/sync/mod.rs +++ b/rslib/src/backend/sync/mod.rs @@ -3,27 +3,29 @@ use std::sync::Arc; -use futures::future::{AbortHandle, AbortRegistration, Abortable}; +use futures::future::AbortHandle; +use futures::future::AbortRegistration; +use futures::future::Abortable; use pb::sync::sync_status_response::Required; use reqwest::Url; use tracing::warn; -use super::{progress::AbortHandleSlot, Backend}; +use super::progress::AbortHandleSlot; +use super::Backend; +use crate::pb; pub(super) use crate::pb::sync::sync_service::Service as SyncService; -use crate::{ - pb, - pb::sync::SyncStatusResponse, - prelude::*, - sync::{ - collection::{ - normal::{ClientSyncState, NormalSyncProgress, SyncActionRequired, SyncOutput}, - progress::{sync_abort, FullSyncProgress}, - status::online_sync_status_check, - }, - http_client::HttpSyncClient, - login::{sync_login, SyncAuth}, - }, -}; +use crate::pb::sync::SyncStatusResponse; +use crate::prelude::*; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::SyncActionRequired; +use crate::sync::collection::normal::SyncOutput; +use crate::sync::collection::progress::sync_abort; +use crate::sync::collection::progress::FullSyncProgress; +use crate::sync::collection::status::online_sync_status_check; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::sync_login; +use crate::sync::login::SyncAuth; #[derive(Default)] pub(super) struct SyncState { @@ -264,8 +266,9 @@ impl Backend { let state = rt.block_on(online_sync_status_check(local, &mut client))?; { let mut guard = self.state.lock().unwrap(); - // On startup, the sync status check will block on network access, and then automatic syncing begins, - // taking hold of the mutex. By the time we reach here, our network status may be out of date, + // On startup, the sync status check will block on network access, and then + // automatic syncing begins, taking hold of the mutex. By the time + // we reach here, our network status may be out of date, // so we discard it if stale. if guard.sync.remote_sync_status.last_check < time_at_check_begin { guard.sync.remote_sync_status.last_check = time_at_check_begin; diff --git a/rslib/src/backend/tags.rs b/rslib/src/backend/tags.rs index df18b7085..d10b89997 100644 --- a/rslib/src/backend/tags.rs +++ b/rslib/src/backend/tags.rs @@ -1,9 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{notes::to_note_ids, Backend}; +use super::notes::to_note_ids; +use super::Backend; +use crate::pb; pub(super) use crate::pb::tags::tags_service::Service as TagsService; -use crate::{pb, prelude::*}; +use crate::prelude::*; impl TagsService for Backend { fn clear_unused_tags( diff --git a/rslib/src/browser_table.rs b/rslib/src/browser_table.rs index d8dbc5087..9d20de7d7 100644 --- a/rslib/src/browser_table.rs +++ b/rslib/src/browser_table.rs @@ -4,18 +4,22 @@ use std::sync::Arc; use itertools::Itertools; -use strum::{Display, EnumIter, EnumString, IntoEnumIterator}; +use strum::Display; +use strum::EnumIter; +use strum::EnumString; +use strum::IntoEnumIterator; -use crate::{ - card::{CardQueue, CardType}, - card_rendering::prettify_av_tags, - notetype::{CardTemplate, NotetypeKind}, - pb, - prelude::*, - scheduler::{timespan::time_span, timing::SchedTimingToday}, - template::RenderedNode, - text::html_to_text_line, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::card_rendering::prettify_av_tags; +use crate::notetype::CardTemplate; +use crate::notetype::NotetypeKind; +use crate::pb; +use crate::prelude::*; +use crate::scheduler::timespan::time_span; +use crate::scheduler::timing::SchedTimingToday; +use crate::template::RenderedNode; +use crate::text::html_to_text_line; #[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumIter, EnumString)] #[strum(serialize_all = "camelCase")] @@ -242,9 +246,9 @@ impl Collection { } fn get_note_maybe_with_fields(&self, id: NoteId, _with_fields: bool) -> Result { - // todo: After note.sort_field has been modified so it can be displayed in the browser, - // we can update note_field_str() and only load the note with fields if a card render is - // necessary (see #1082). + // todo: After note.sort_field has been modified so it can be displayed in the + // browser, we can update note_field_str() and only load the note with + // fields if a card render is necessary (see #1082). if true { self.storage.get_note(id)? } else { @@ -449,8 +453,9 @@ impl RowContext { } } - /// Returns the due date of the next due card that is not in a filtered deck, new, suspended or - /// buried or the empty string if there is no such card. + /// Returns the due date of the next due card that is not in a filtered + /// deck, new, suspended or buried or the empty string if there is no + /// such card. fn note_due_str(&self) -> String { self.cards .iter() @@ -461,7 +466,8 @@ impl RowContext { .unwrap_or_else(|| "".into()) } - /// Returns the average ease of the non-new cards or a hint if there aren't any. + /// Returns the average ease of the non-new cards or a hint if there aren't + /// any. fn ease_str(&self) -> String { let eases: Vec = self .cards @@ -476,7 +482,8 @@ impl RowContext { } } - /// Returns the average interval of the review and relearn cards if there are any. + /// Returns the average interval of the review and relearn cards if there + /// are any. fn interval_str(&self) -> String { if !self.notes_mode { match self.cards[0].ctype { diff --git a/rslib/src/card/mod.rs b/rslib/src/card/mod.rs index a38e70575..9c36797b1 100644 --- a/rslib/src/card/mod.rs +++ b/rslib/src/card/mod.rs @@ -3,24 +3,27 @@ pub(crate) mod undo; -use std::collections::{hash_map::Entry, HashMap, HashSet}; +use std::collections::hash_map::Entry; +use std::collections::HashMap; +use std::collections::HashSet; use num_enum::TryFromPrimitive; -use serde_repr::{Deserialize_repr, Serialize_repr}; +use serde_repr::Deserialize_repr; +use serde_repr::Serialize_repr; -use crate::{ - collection::Collection, - config::SchedulerVersion, - deckconfig::DeckConfig, - decks::DeckId, - define_newtype, - error::{AnkiError, FilteredDeckError, Result}, - notes::NoteId, - ops::StateChanges, - prelude::*, - timestamp::TimestampSecs, - types::Usn, -}; +use crate::collection::Collection; +use crate::config::SchedulerVersion; +use crate::deckconfig::DeckConfig; +use crate::decks::DeckId; +use crate::define_newtype; +use crate::error::AnkiError; +use crate::error::FilteredDeckError; +use crate::error::Result; +use crate::notes::NoteId; +use crate::ops::StateChanges; +use crate::prelude::*; +use crate::timestamp::TimestampSecs; +use crate::types::Usn; define_newtype!(CardId, i64); @@ -79,7 +82,8 @@ pub struct Card { pub(crate) flags: u8, /// The position in the new queue before leaving it. pub(crate) original_position: Option, - /// JSON object or empty; exposed through the reviewer for persisting custom state + /// JSON object or empty; exposed through the reviewer for persisting custom + /// state pub(crate) custom_data: String, } @@ -159,9 +163,10 @@ impl Card { } } - /// Remaining steps after configured steps have changed, disregarding "remaining today". - /// [None] if same as before. A step counts as remaining if the card has not passed a step - /// with the same or a greater delay, but output will be at least 1. + /// Remaining steps after configured steps have changed, disregarding + /// "remaining today". [None] if same as before. A step counts as + /// remaining if the card has not passed a step with the same or a + /// greater delay, but output will be at least 1. fn new_remaining_steps(&self, new_steps: &[f32], old_steps: &[f32]) -> Option { let remaining = self.remaining_steps(); let new_remaining = old_steps @@ -387,10 +392,9 @@ impl<'a> RemainingStepsAdjuster<'a> { #[cfg(test)] mod test { - use crate::tests::{ - open_test_collection_with_learning_card, open_test_collection_with_relearning_card, - DeckAdder, - }; + use crate::tests::open_test_collection_with_learning_card; + use crate::tests::open_test_collection_with_relearning_card; + use crate::tests::DeckAdder; #[test] fn should_increase_remaining_learning_steps_if_new_deck_has_more_unpassed_ones() { diff --git a/rslib/src/card_rendering/mod.rs b/rslib/src/card_rendering/mod.rs index 9b528301f..f9c9b8e3d 100644 --- a/rslib/src/card_rendering/mod.rs +++ b/rslib/src/card_rendering/mod.rs @@ -3,7 +3,8 @@ use std::collections::HashMap; -use crate::{pb, prelude::*}; +use crate::pb; +use crate::prelude::*; mod parser; mod writer; @@ -92,7 +93,8 @@ pub fn anki_directive_benchmark() { mod test { use super::*; - /// Strip av tags and assert equality with input or separately passed output. + /// Strip av tags and assert equality with input or separately passed + /// output. macro_rules! assert_av_stripped { ($input:expr) => { assert_eq!($input, strip_av_tags($input)); diff --git a/rslib/src/card_rendering/parser.rs b/rslib/src/card_rendering/parser.rs index 2957384eb..ca1d17eb5 100644 --- a/rslib/src/card_rendering/parser.rs +++ b/rslib/src/card_rendering/parser.rs @@ -3,16 +3,30 @@ use std::collections::HashMap; -use nom::{ - branch::alt, - bytes::complete::{is_not, tag}, - character::complete::{anychar, multispace0}, - combinator::{map, not, recognize, success, value}, - multi::{many0, many1}, - sequence::{delimited, pair, preceded, separated_pair, terminated, tuple}, -}; +use nom::branch::alt; +use nom::bytes::complete::is_not; +use nom::bytes::complete::tag; +use nom::character::complete::anychar; +use nom::character::complete::multispace0; +use nom::combinator::map; +use nom::combinator::not; +use nom::combinator::recognize; +use nom::combinator::success; +use nom::combinator::value; +use nom::multi::many0; +use nom::multi::many1; +use nom::sequence::delimited; +use nom::sequence::pair; +use nom::sequence::preceded; +use nom::sequence::separated_pair; +use nom::sequence::terminated; +use nom::sequence::tuple; -use super::{CardNodes, Directive, Node, OtherDirective, TtsDirective}; +use super::CardNodes; +use super::Directive; +use super::Node; +use super::OtherDirective; +use super::TtsDirective; type IResult<'a, O> = nom::IResult<&'a str, O>; @@ -87,7 +101,8 @@ fn node(s: &str) -> IResult { alt((text_node, sound_node, tag_node))(s) } -/// A sound tag `[sound:resource]`, where `resource` is pointing to a sound or video file. +/// A sound tag `[sound:resource]`, where `resource` is pointing to a sound or +/// video file. fn sound_node(s: &str) -> IResult { map( delimited(tag("[sound:"), is_not("]"), tag("]")), @@ -106,7 +121,8 @@ fn tag_node(s: &str) -> IResult { fn opening_parser<'name, 's: 'name>( name: &'name str, ) -> impl FnMut(&'s str) -> IResult> + 'name { - /// List of whitespace-separated `key=val` tuples, where `val` may be empty. + /// List of whitespace-separated `key=val` tuples, where `val` may be + /// empty. fn options(s: &str) -> IResult> { fn key(s: &str) -> IResult<&str> { is_not("] \t\r\n=")(s) @@ -136,7 +152,8 @@ fn tag_node(s: &str) -> IResult { value((), tuple((tag("[/anki:"), tag(name), tag("]")))) } - /// Return a parser to match and return anything until a closing `name` tag is found. + /// Return a parser to match and return anything until a closing `name` tag + /// is found. fn content_parser<'parser, 'name: 'parser, 's: 'parser>( name: &'name str, ) -> impl FnMut(&'s str) -> IResult<&str> + 'parser { diff --git a/rslib/src/card_rendering/writer.rs b/rslib/src/card_rendering/writer.rs index f2d1d58bb..0695eb131 100644 --- a/rslib/src/card_rendering/writer.rs +++ b/rslib/src/card_rendering/writer.rs @@ -3,12 +3,15 @@ use std::fmt::Write as _; -use super::{CardNodes, Directive, Node, OtherDirective, TtsDirective}; -use crate::{ - pb, - prelude::*, - text::{decode_entities, strip_html_for_tts}, -}; +use super::CardNodes; +use super::Directive; +use super::Node; +use super::OtherDirective; +use super::TtsDirective; +use crate::pb; +use crate::prelude::*; +use crate::text::decode_entities; +use crate::text::strip_html_for_tts; impl<'a> CardNodes<'a> { pub(super) fn write_without_av_tags(&self) -> String { diff --git a/rslib/src/cloze.rs b/rslib/src/cloze.rs index 5027bc308..ae63640b1 100644 --- a/rslib/src/cloze.rs +++ b/rslib/src/cloze.rs @@ -1,19 +1,23 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashSet, fmt::Write}; +use std::borrow::Cow; +use std::collections::HashSet; +use std::fmt::Write; use htmlescape::encode_attribute; use lazy_static::lazy_static; -use nom::{ - branch::alt, - bytes::complete::{tag, take_while}, - combinator::map, - IResult, -}; -use regex::{Captures, Regex}; +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::bytes::complete::take_while; +use nom::combinator::map; +use nom::IResult; +use regex::Captures; +use regex::Regex; -use crate::{latex::contains_latex, template::RenderContext, text::strip_html_preserving_entities}; +use crate::latex::contains_latex; +use crate::template::RenderContext; +use crate::text::strip_html_preserving_entities; lazy_static! { static ref MATHJAX: Regex = Regex::new( diff --git a/rslib/src/collection/backup.rs b/rslib/src/collection/backup.rs index f52414c1c..22d222c11 100644 --- a/rslib/src/collection/backup.rs +++ b/rslib/src/collection/backup.rs @@ -1,23 +1,24 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - ffi::OsStr, - fs::{read_dir, remove_file, DirEntry}, - path::{Path, PathBuf}, - thread, - thread::JoinHandle, - time::SystemTime, -}; +use std::ffi::OsStr; +use std::fs::read_dir; +use std::fs::remove_file; +use std::fs::DirEntry; +use std::path::Path; +use std::path::PathBuf; +use std::thread; +use std::thread::JoinHandle; +use std::time::SystemTime; use chrono::prelude::*; use itertools::Itertools; use tracing::error; -use crate::{ - import_export::package::export_colpkg_from_data, io::read_file, - pb::config::preferences::BackupLimits, prelude::*, -}; +use crate::import_export::package::export_colpkg_from_data; +use crate::io::read_file; +use crate::pb::config::preferences::BackupLimits; +use crate::prelude::*; const BACKUP_FORMAT_STRING: &str = "backup-%Y-%m-%d-%H.%M.%S.colpkg"; @@ -129,8 +130,8 @@ impl Backup { /// Serial week number, starting on Monday fn week(&self) -> i32 { - // Day 1 (01/01/01) was a Monday, meaning week rolled over on Sunday (when day % 7 == 0). - // We subtract 1 to shift the rollover to Monday. + // Day 1 (01/01/01) was a Monday, meaning week rolled over on Sunday (when day % + // 7 == 0). We subtract 1 to shift the rollover to Monday. (self.day() - 1) / 7 } diff --git a/rslib/src/collection/mod.rs b/rslib/src/collection/mod.rs index b682c219b..49fc04514 100644 --- a/rslib/src/collection/mod.rs +++ b/rslib/src/collection/mod.rs @@ -6,25 +6,26 @@ pub(crate) mod timestamps; mod transact; pub(crate) mod undo; -use std::{ - collections::HashMap, - fmt::{Debug, Formatter}, - path::PathBuf, - sync::Arc, -}; +use std::collections::HashMap; +use std::fmt::Debug; +use std::fmt::Formatter; +use std::path::PathBuf; +use std::sync::Arc; -use crate::{ - browser_table, - decks::{Deck, DeckId}, - error::Result, - i18n::I18n, - notetype::{Notetype, NotetypeId}, - scheduler::{queue::CardQueues, SchedulerInfo}, - storage::{SchemaVersion, SqliteStorage}, - timestamp::TimestampMillis, - types::Usn, - undo::UndoManager, -}; +use crate::browser_table; +use crate::decks::Deck; +use crate::decks::DeckId; +use crate::error::Result; +use crate::i18n::I18n; +use crate::notetype::Notetype; +use crate::notetype::NotetypeId; +use crate::scheduler::queue::CardQueues; +use crate::scheduler::SchedulerInfo; +use crate::storage::SchemaVersion; +use crate::storage::SqliteStorage; +use crate::timestamp::TimestampMillis; +use crate::types::Usn; +use crate::undo::UndoManager; #[derive(Default)] pub struct CollectionBuilder { @@ -159,8 +160,8 @@ impl Collection { builder } - // A count of all changed rows since the collection was opened, which can be used to detect - // if the collection was modified or not. + // A count of all changed rows since the collection was opened, which can be + // used to detect if the collection was modified or not. pub fn changes_since_open(&self) -> u64 { self.storage.db.changes() } @@ -170,7 +171,8 @@ impl Collection { } pub(crate) fn usn(&self) -> Result { - // if we cache this in the future, must make sure to invalidate cache when usn bumped in sync.finish() + // if we cache this in the future, must make sure to invalidate cache when usn + // bumped in sync.finish() self.storage.usn(self.server) } diff --git a/rslib/src/collection/transact.rs b/rslib/src/collection/transact.rs index 19c253309..2d98b6679 100644 --- a/rslib/src/collection/transact.rs +++ b/rslib/src/collection/transact.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ops::StateChanges, prelude::*}; +use crate::ops::StateChanges; +use crate::prelude::*; impl Collection { fn transact_inner(&mut self, op: Option, func: F) -> Result> diff --git a/rslib/src/config/mod.rs b/rslib/src/config/mod.rs index 050cb40e0..4a79f5550 100644 --- a/rslib/src/config/mod.rs +++ b/rslib/src/config/mod.rs @@ -9,15 +9,19 @@ pub(crate) mod schema11; mod string; pub(crate) mod undo; -use serde::{de::DeserializeOwned, Serialize}; -use serde_repr::{Deserialize_repr, Serialize_repr}; +use serde::de::DeserializeOwned; +use serde::Serialize; +use serde_repr::Deserialize_repr; +use serde_repr::Serialize_repr; use strum::IntoStaticStr; -pub use self::{ - bool::BoolKey, deck::DeckConfigKey, notetype::get_aux_notetype_config_key, - number::I32ConfigKey, string::StringKey, -}; -use crate::{pb::config::preferences::BackupLimits, prelude::*}; +pub use self::bool::BoolKey; +pub use self::deck::DeckConfigKey; +pub use self::notetype::get_aux_notetype_config_key; +pub use self::number::I32ConfigKey; +pub use self::string::StringKey; +use crate::pb::config::preferences::BackupLimits; +use crate::prelude::*; /// Only used when updating/undoing. #[derive(Debug)] @@ -306,7 +310,8 @@ pub(crate) enum Weekday { #[cfg(test)] mod test { - use crate::{collection::open_test_collection, decks::DeckId}; + use crate::collection::open_test_collection; + use crate::decks::DeckId; #[test] fn defaults() { diff --git a/rslib/src/config/notetype.rs b/rslib/src/config/notetype.rs index 9256db50f..0d3fd9611 100644 --- a/rslib/src/config/notetype.rs +++ b/rslib/src/config/notetype.rs @@ -4,7 +4,8 @@ use strum::IntoStaticStr; use super::ConfigKey; -use crate::{notetype::NotetypeKind, prelude::*}; +use crate::notetype::NotetypeKind; +use crate::prelude::*; /// Notetype config packed into a collection config key. This may change /// frequently, and we want to avoid the potentially expensive notetype diff --git a/rslib/src/dbcheck.rs b/rslib/src/dbcheck.rs index f0e4f49c8..747802c40 100644 --- a/rslib/src/dbcheck.rs +++ b/rslib/src/dbcheck.rs @@ -1,23 +1,28 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashSet, sync::Arc}; +use std::collections::HashSet; +use std::sync::Arc; use itertools::Itertools; use tracing::debug; -use crate::{ - collection::Collection, - config::SchedulerVersion, - error::{AnkiError, DbError, DbErrorKind, Result}, - i18n::I18n, - notetype::{ - all_stock_notetypes, AlreadyGeneratedCardInfo, CardGenContext, Notetype, NotetypeId, - NotetypeKind, - }, - prelude::*, - timestamp::{TimestampMillis, TimestampSecs}, -}; +use crate::collection::Collection; +use crate::config::SchedulerVersion; +use crate::error::AnkiError; +use crate::error::DbError; +use crate::error::DbErrorKind; +use crate::error::Result; +use crate::i18n::I18n; +use crate::notetype::all_stock_notetypes; +use crate::notetype::AlreadyGeneratedCardInfo; +use crate::notetype::CardGenContext; +use crate::notetype::Notetype; +use crate::notetype::NotetypeId; +use crate::notetype::NotetypeKind; +use crate::prelude::*; +use crate::timestamp::TimestampMillis; +use crate::timestamp::TimestampSecs; #[derive(Debug, Default, PartialEq, Eq)] pub struct CheckDatabaseOutput { @@ -278,8 +283,8 @@ impl Collection { // to ensure to restore the collapse state self.storage.restore_expanded_tags(&expanded_tags)?; - // if the collection is empty and the user has deleted all note types, ensure at least - // one note type exists + // if the collection is empty and the user has deleted all note types, ensure at + // least one note type exists if self.storage.get_all_notetype_names()?.is_empty() { let mut nt = all_stock_notetypes(&self.tr).remove(0); self.add_notetype_inner(&mut nt, usn, true)?; @@ -408,7 +413,9 @@ impl Collection { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, decks::DeckId, search::SortMode}; + use crate::collection::open_test_collection; + use crate::decks::DeckId; + use crate::search::SortMode; fn progress_fn(_progress: DatabaseCheckProgress, _throttle: bool) {} diff --git a/rslib/src/deckconfig/mod.rs b/rslib/src/deckconfig/mod.rs index b299b0294..b97c88d5c 100644 --- a/rslib/src/deckconfig/mod.rs +++ b/rslib/src/deckconfig/mod.rs @@ -5,21 +5,24 @@ mod schema11; pub(crate) mod undo; mod update; -pub use schema11::{DeckConfSchema11, NewCardOrderSchema11}; +pub use schema11::DeckConfSchema11; +pub use schema11::NewCardOrderSchema11; pub use update::UpdateDeckConfigsRequest; -pub use crate::pb::deckconfig::deck_config::{ - config::{ - LeechAction, NewCardGatherPriority, NewCardInsertOrder, NewCardSortOrder, ReviewCardOrder, - ReviewMix, - }, - Config as DeckConfigInner, -}; +pub use crate::pb::deckconfig::deck_config::config::LeechAction; +pub use crate::pb::deckconfig::deck_config::config::NewCardGatherPriority; +pub use crate::pb::deckconfig::deck_config::config::NewCardInsertOrder; +pub use crate::pb::deckconfig::deck_config::config::NewCardSortOrder; +pub use crate::pb::deckconfig::deck_config::config::ReviewCardOrder; +pub use crate::pb::deckconfig::deck_config::config::ReviewMix; +pub use crate::pb::deckconfig::deck_config::Config as DeckConfigInner; /// Old deck config and cards table store 250% as 2500. pub(crate) const INITIAL_EASE_FACTOR_THOUSANDS: u16 = (INITIAL_EASE_FACTOR * 1000.0) as u16; -use crate::{define_newtype, prelude::*, scheduler::states::review::INITIAL_EASE_FACTOR}; +use crate::define_newtype; +use crate::prelude::*; +use crate::scheduler::states::review::INITIAL_EASE_FACTOR; define_newtype!(DeckConfigId, i64); diff --git a/rslib/src/deckconfig/schema11.rs b/rslib/src/deckconfig/schema11.rs index 1bf355dec..9a84e3c84 100644 --- a/rslib/src/deckconfig/schema11.rs +++ b/rslib/src/deckconfig/schema11.rs @@ -3,17 +3,24 @@ use std::collections::HashMap; -use serde::{Deserialize as DeTrait, Deserializer}; +use serde::Deserialize as DeTrait; +use serde::Deserializer; use serde_aux::field_attributes::deserialize_number_from_string; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use serde_json::Value; -use serde_repr::{Deserialize_repr, Serialize_repr}; +use serde_repr::Deserialize_repr; +use serde_repr::Serialize_repr; use serde_tuple::Serialize_tuple; -use super::{ - DeckConfig, DeckConfigId, DeckConfigInner, NewCardInsertOrder, INITIAL_EASE_FACTOR_THOUSANDS, -}; -use crate::{serde::default_on_invalid, timestamp::TimestampSecs, types::Usn}; +use super::DeckConfig; +use super::DeckConfigId; +use super::DeckConfigInner; +use super::NewCardInsertOrder; +use super::INITIAL_EASE_FACTOR_THOUSANDS; +use crate::serde::default_on_invalid; +use crate::timestamp::TimestampSecs; +use crate::types::Usn; #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] #[serde(rename_all = "camelCase")] @@ -430,7 +437,8 @@ fn clear_other_duplicates(top_other: &mut HashMap) { #[cfg(test)] mod test { use serde::de::IntoDeserializer; - use serde_json::{json, Value}; + use serde_json::json; + use serde_json::Value; use super::*; diff --git a/rslib/src/deckconfig/update.rs b/rslib/src/deckconfig/update.rs index 29891a41f..c3a135238 100644 --- a/rslib/src/deckconfig/update.rs +++ b/rslib/src/deckconfig/update.rs @@ -3,22 +3,20 @@ //! Updating configs in bulk, from the deck options screen. -use std::{ - collections::{HashMap, HashSet}, - iter, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::iter; -use crate::{ - config::StringKey, - decks::NormalDeck, - pb, - pb::{ - deckconfig::deck_configs_for_update::{current_deck::Limits, ConfigWithExtra, CurrentDeck}, - decks::deck::normal::DayLimit, - }, - prelude::*, - search::{JoinSearches, SearchNode}, -}; +use crate::config::StringKey; +use crate::decks::NormalDeck; +use crate::pb; +use crate::pb::deckconfig::deck_configs_for_update::current_deck::Limits; +use crate::pb::deckconfig::deck_configs_for_update::ConfigWithExtra; +use crate::pb::deckconfig::deck_configs_for_update::CurrentDeck; +use crate::pb::decks::deck::normal::DayLimit; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::SearchNode; #[derive(Debug, Clone)] pub struct UpdateDeckConfigsRequest { @@ -165,7 +163,8 @@ impl Collection { .map(|c| c.inner.new_card_insert_order()) .unwrap_or_default(); - // if a selected (sub)deck, or its old config was removed, update deck to point to new config + // if a selected (sub)deck, or its old config was removed, update deck to point + // to new config let current_config_id = if selected_deck_ids.contains(&deck.id) || !configs_after_update.contains_key(&previous_config_id) { @@ -196,7 +195,8 @@ impl Collection { Ok(()) } - /// Adjust the remaining steps of cards in the given deck according to the config change. + /// Adjust the remaining steps of cards in the given deck according to the + /// config change. fn adjust_remaining_steps_in_deck( &mut self, deck: DeckId, @@ -269,13 +269,10 @@ fn update_day_limit(day_limit: &mut Option, new_limit: Option, to #[cfg(test)] mod test { use super::*; - use crate::{ - collection::open_test_collection, - deckconfig::NewCardInsertOrder, - tests::{ - open_test_collection_with_learning_card, open_test_collection_with_relearning_card, - }, - }; + use crate::collection::open_test_collection; + use crate::deckconfig::NewCardInsertOrder; + use crate::tests::open_test_collection_with_learning_card; + use crate::tests::open_test_collection_with_relearning_card; #[test] fn updating() -> Result<()> { diff --git a/rslib/src/decks/addupdate.rs b/rslib/src/decks/addupdate.rs index 180001ba1..be4cb34cd 100644 --- a/rslib/src/decks/addupdate.rs +++ b/rslib/src/decks/addupdate.rs @@ -4,7 +4,8 @@ //! Adding and updating. use super::name::immediate_parent_name; -use crate::{error::FilteredDeckError, prelude::*}; +use crate::error::FilteredDeckError; +use crate::prelude::*; impl Collection { /// Add a new deck. The id must be 0, as it will be automatically assigned. @@ -70,8 +71,8 @@ impl Collection { } self.update_single_deck_undoable(deck, original)?; if name_changed { - // after updating, we need to ensure all grandparents exist, which may not be the case - // in the parent->child case + // after updating, we need to ensure all grandparents exist, which may not be + // the case in the parent->child case self.create_missing_parents(&deck.name, usn)?; } Ok(()) @@ -108,7 +109,8 @@ impl Collection { /// If parent deck(s) exist, rewrite name to match their case. /// If they don't exist, create them. - /// Returns an error if a DB operation fails, or if the first existing parent is a filtered deck. + /// Returns an error if a DB operation fails, or if the first existing + /// parent is a filtered deck. fn match_or_create_parents(&mut self, deck: &mut Deck, usn: Usn) -> Result<()> { let child_split: Vec<_> = deck.name.components().collect(); if let Some(parent_deck) = self.first_existing_parent(deck.name.as_native_str(), 0)? { diff --git a/rslib/src/decks/counts.rs b/rslib/src/decks/counts.rs index dca78af31..2f2f2997f 100644 --- a/rslib/src/decks/counts.rs +++ b/rslib/src/decks/counts.rs @@ -2,7 +2,8 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use std::collections::HashMap; -use crate::{pb, prelude::*}; +use crate::pb; +use crate::prelude::*; #[derive(Debug)] pub(crate) struct DueCounts { diff --git a/rslib/src/decks/current.rs b/rslib/src/decks/current.rs index f2162f431..b8d9fd81e 100644 --- a/rslib/src/decks/current.rs +++ b/rslib/src/decks/current.rs @@ -3,7 +3,8 @@ use std::sync::Arc; -use crate::{config::ConfigKey, prelude::*}; +use crate::config::ConfigKey; +use crate::prelude::*; impl Collection { pub fn set_current_deck(&mut self, deck: DeckId) -> Result> { diff --git a/rslib/src/decks/filtered.rs b/rslib/src/decks/filtered.rs index ed797eb6a..e0d083afc 100644 --- a/rslib/src/decks/filtered.rs +++ b/rslib/src/decks/filtered.rs @@ -3,7 +3,10 @@ use strum::IntoEnumIterator; -use super::{DeckCommon, FilteredDeck, FilteredSearchOrder, FilteredSearchTerm}; +use super::DeckCommon; +use super::FilteredDeck; +use super::FilteredSearchOrder; +use super::FilteredSearchTerm; use crate::prelude::*; impl Deck { diff --git a/rslib/src/decks/limits.rs b/rslib/src/decks/limits.rs index 64f6565e4..97e23fcae 100644 --- a/rslib/src/decks/limits.rs +++ b/rslib/src/decks/limits.rs @@ -1,24 +1,30 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, iter::Peekable}; +use std::collections::HashMap; +use std::iter::Peekable; -use id_tree::{InsertBehavior, Node, NodeId, Tree}; +use id_tree::InsertBehavior; +use id_tree::Node; +use id_tree::NodeId; +use id_tree::Tree; -use super::{Deck, NormalDeck}; -use crate::{ - deckconfig::{DeckConfig, DeckConfigId}, - pb::decks::deck::normal::DayLimit, - prelude::*, -}; +use super::Deck; +use super::NormalDeck; +use crate::deckconfig::DeckConfig; +use crate::deckconfig::DeckConfigId; +use crate::pb::decks::deck::normal::DayLimit; +use crate::prelude::*; impl NormalDeck { - /// The deck's review limit for today, or its regular one, if any is configured. + /// The deck's review limit for today, or its regular one, if any is + /// configured. pub fn current_review_limit(&self, today: u32) -> Option { self.review_limit_today(today).or(self.review_limit) } - /// The deck's new limit for today, or its regular one, if any is configured. + /// The deck's new limit for today, or its regular one, if any is + /// configured. pub fn current_new_limit(&self, today: u32) -> Option { self.new_limit_today(today).or(self.new_limit) } @@ -185,7 +191,8 @@ impl LimitTreeMap { /// Recursively appends descendants to the provided parent [Node], and adds /// them to the [HashMap]. /// Given [Deck]s are assumed to arrive in depth-first order. - /// The tree-from-deck-list logic is taken from [crate::decks::tree::add_child_nodes]. + /// The tree-from-deck-list logic is taken from + /// [crate::decks::tree::add_child_nodes]. fn add_child_nodes( &mut self, parent_node_id: NodeId, diff --git a/rslib/src/decks/mod.rs b/rslib/src/decks/mod.rs index 73468b134..d3ff199b4 100644 --- a/rslib/src/decks/mod.rs +++ b/rslib/src/decks/mod.rs @@ -21,19 +21,19 @@ pub(crate) use name::immediate_parent_name; pub use name::NativeDeckName; pub use schema11::DeckSchema11; -pub use crate::pb::decks::{ - deck::{ - filtered::{search_term::Order as FilteredSearchOrder, SearchTerm as FilteredSearchTerm}, - kind_container::Kind as DeckKind, - Common as DeckCommon, Filtered as FilteredDeck, KindContainer as DeckKindContainer, - Normal as NormalDeck, - }, - Deck as DeckProto, -}; -use crate::{ - define_newtype, error::FilteredDeckError, markdown::render_markdown, prelude::*, - text::sanitize_html_no_images, -}; +use crate::define_newtype; +use crate::error::FilteredDeckError; +use crate::markdown::render_markdown; +pub use crate::pb::decks::deck::filtered::search_term::Order as FilteredSearchOrder; +pub use crate::pb::decks::deck::filtered::SearchTerm as FilteredSearchTerm; +pub use crate::pb::decks::deck::kind_container::Kind as DeckKind; +pub use crate::pb::decks::deck::Common as DeckCommon; +pub use crate::pb::decks::deck::Filtered as FilteredDeck; +pub use crate::pb::decks::deck::KindContainer as DeckKindContainer; +pub use crate::pb::decks::deck::Normal as NormalDeck; +pub use crate::pb::decks::Deck as DeckProto; +use crate::prelude::*; +use crate::text::sanitize_html_no_images; define_newtype!(DeckId, i64); @@ -185,7 +185,9 @@ impl Collection { #[cfg(test)] mod test { - use crate::{collection::open_test_collection, prelude::*, search::SortMode}; + use crate::collection::open_test_collection; + use crate::prelude::*; + use crate::search::SortMode; fn sorted_names(col: &Collection) -> Vec { col.storage diff --git a/rslib/src/decks/name.rs b/rslib/src/decks/name.rs index 39ef3d3f4..54028a72c 100644 --- a/rslib/src/decks/name.rs +++ b/rslib/src/decks/name.rs @@ -4,7 +4,8 @@ use std::borrow::Cow; use itertools::Itertools; -use crate::{prelude::*, text::normalize_to_nfc}; +use crate::prelude::*; +use crate::text::normalize_to_nfc; #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct NativeDeckName(String); @@ -42,7 +43,8 @@ impl NativeDeckName { self.0.split('\x1f') } - /// Normalize the name's components if necessary. True if mutation took place. + /// Normalize the name's components if necessary. True if mutation took + /// place. pub(crate) fn maybe_normalize(&mut self) -> bool { let needs_normalization = self .components() @@ -57,8 +59,8 @@ impl NativeDeckName { } /// Determine name to rename a deck to, when `self` is dropped on `target`. - /// `target` being unset represents a drop at the top or bottom of the deck list. - /// The returned name should be used to replace `self`. + /// `target` being unset represents a drop at the top or bottom of the deck + /// list. The returned name should be used to replace `self`. pub(crate) fn reparented_name(&self, target: Option<&NativeDeckName>) -> Option { let dragged_base = self.0.rsplit('\x1f').next().unwrap(); let dragged_root = self.components().next().unwrap(); @@ -77,8 +79,8 @@ impl NativeDeckName { } } - /// Replace the old parent's name with the new parent's name in self's name, where the old - /// parent's name is expected to be a prefix. + /// Replace the old parent's name with the new parent's name in self's name, + /// where the old parent's name is expected to be a prefix. fn reparent(&mut self, old_parent: &NativeDeckName, new_parent: &NativeDeckName) { self.0 = std::iter::once(new_parent.as_native_str()) .chain(self.components().skip(old_parent.components().count())) diff --git a/rslib/src/decks/reparent.rs b/rslib/src/decks/reparent.rs index 15de58cbb..a9fcd318f 100644 --- a/rslib/src/decks/reparent.rs +++ b/rslib/src/decks/reparent.rs @@ -1,6 +1,7 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{error::FilteredDeckError, prelude::*}; +use crate::error::FilteredDeckError; +use crate::prelude::*; impl Collection { pub fn reparent_decks( diff --git a/rslib/src/decks/schema11.rs b/rslib/src/decks/schema11.rs index deb9604a1..f379fa308 100644 --- a/rslib/src/decks/schema11.rs +++ b/rslib/src/decks/schema11.rs @@ -3,16 +3,20 @@ use std::collections::HashMap; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use serde_json::Value; use serde_tuple::Serialize_tuple; -use super::{DeckCommon, FilteredDeck, FilteredSearchTerm, NormalDeck}; -use crate::{ - pb::decks::deck::normal::DayLimit, - prelude::*, - serde::{default_on_invalid, deserialize_bool_from_anything, deserialize_number_from_string}, -}; +use super::DeckCommon; +use super::FilteredDeck; +use super::FilteredSearchTerm; +use super::NormalDeck; +use crate::pb::decks::deck::normal::DayLimit; +use crate::prelude::*; +use crate::serde::default_on_invalid; +use crate::serde::deserialize_bool_from_anything; +use crate::serde::deserialize_number_from_string; #[derive(Serialize, PartialEq, Debug, Clone)] #[serde(untagged)] @@ -21,15 +25,18 @@ pub enum DeckSchema11 { Filtered(FilteredDeckSchema11), } -// serde doesn't support integer/bool enum tags, so we manually pick the correct variant +// serde doesn't support integer/bool enum tags, so we manually pick the correct +// variant mod dynfix { - use serde::{ - de, - de::{Deserialize, Deserializer}, - }; - use serde_json::{Map, Value}; + use serde::de; + use serde::de::Deserialize; + use serde::de::Deserializer; + use serde_json::Map; + use serde_json::Value; - use super::{DeckSchema11, FilteredDeckSchema11, NormalDeckSchema11}; + use super::DeckSchema11; + use super::FilteredDeckSchema11; + use super::NormalDeckSchema11; impl<'de> Deserialize<'de> for DeckSchema11 { fn deserialize(deserializer: D) -> Result diff --git a/rslib/src/decks/stats.rs b/rslib/src/decks/stats.rs index 421512c61..502388e7a 100644 --- a/rslib/src/decks/stats.rs +++ b/rslib/src/decks/stats.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::DeckCommon; -use crate::{pb, prelude::*}; +use crate::pb; +use crate::prelude::*; impl Deck { pub(super) fn reset_stats_if_day_changed(&mut self, today: u32) { diff --git a/rslib/src/decks/tree.rs b/rslib/src/decks/tree.rs index de7ff6b0e..2c472cbcb 100644 --- a/rslib/src/decks/tree.rs +++ b/rslib/src/decks/tree.rs @@ -1,23 +1,23 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::{HashMap, HashSet}, - iter::Peekable, - ops::AddAssign, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::iter::Peekable; +use std::ops::AddAssign; use serde_tuple::Serialize_tuple; use unicase::UniCase; -use super::{ - limits::{remaining_limits_map, RemainingLimits}, - DueCounts, -}; +use super::limits::remaining_limits_map; +use super::limits::RemainingLimits; +use super::DueCounts; +use crate::config::SchedulerVersion; +use crate::ops::OpOutput; pub use crate::pb::decks::set_deck_collapsed_request::Scope as DeckCollapseScope; -use crate::{ - config::SchedulerVersion, ops::OpOutput, pb::decks::DeckTreeNode, prelude::*, undo::Op, -}; +use crate::pb::decks::DeckTreeNode; +use crate::prelude::*; +use crate::undo::Op; fn deck_names_to_tree(names: impl Iterator) -> DeckTreeNode { let mut top = DeckTreeNode::default(); @@ -395,7 +395,9 @@ impl Collection { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, deckconfig::DeckConfigId, error::Result}; + use crate::collection::open_test_collection; + use crate::deckconfig::DeckConfigId; + use crate::error::Result; #[test] fn wellformed() -> Result<()> { @@ -516,7 +518,8 @@ mod test { assert_eq!(parent.children[0].children[1].new_count, 1); // child: cards from self and children, limited by own new limit assert_eq!(parent.children[0].new_count, 4); - // parent: cards from self and all subdecks, all limits in the hierarchy are respected + // parent: cards from self and all subdecks, all limits in the hierarchy are + // respected assert_eq!(parent.new_count, 6); assert_eq!(parent.total_including_children, 8); assert_eq!(parent.total_in_deck, 2); diff --git a/rslib/src/decks/undo.rs b/rslib/src/decks/undo.rs index 4e8bd430c..a1ca3e171 100644 --- a/rslib/src/decks/undo.rs +++ b/rslib/src/decks/undo.rs @@ -60,9 +60,9 @@ impl Collection { Ok(()) } - /// Update an individual, existing deck. Caller is responsible for ensuring deck - /// is normalized, matches parents, is not a duplicate name, and bumping mtime. - /// Clears deck cache. + /// Update an individual, existing deck. Caller is responsible for ensuring + /// deck is normalized, matches parents, is not a duplicate name, and + /// bumping mtime. Clears deck cache. pub(super) fn update_single_deck_undoable( &mut self, deck: &mut Deck, diff --git a/rslib/src/error/db.rs b/rslib/src/error/db.rs index 36946ee23..78f076eb4 100644 --- a/rslib/src/error/db.rs +++ b/rslib/src/error/db.rs @@ -4,7 +4,8 @@ use std::str::Utf8Error; use anki_i18n::I18n; -use rusqlite::{types::FromSqlError, Error}; +use rusqlite::types::FromSqlError; +use rusqlite::Error; use snafu::Snafu; use super::AnkiError; diff --git a/rslib/src/error/invalid_input.rs b/rslib/src/error/invalid_input.rs index 97080c94f..f62174578 100644 --- a/rslib/src/error/invalid_input.rs +++ b/rslib/src/error/invalid_input.rs @@ -1,7 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use snafu::{Backtrace, OptionExt, ResultExt, Snafu}; +use snafu::Backtrace; +use snafu::OptionExt; +use snafu::ResultExt; +use snafu::Snafu; use crate::prelude::*; diff --git a/rslib/src/error/mod.rs b/rslib/src/error/mod.rs index 89cfeddff..1f595289d 100644 --- a/rslib/src/error/mod.rs +++ b/rslib/src/error/mod.rs @@ -9,18 +9,27 @@ pub(crate) mod network; mod not_found; mod search; -pub use db::{DbError, DbErrorKind}; -pub use filtered::{CustomStudyError, FilteredDeckError}; -pub use network::{NetworkError, NetworkErrorKind, SyncError, SyncErrorKind}; -pub use search::{ParseError, SearchErrorKind}; +pub use db::DbError; +pub use db::DbErrorKind; +pub use filtered::CustomStudyError; +pub use filtered::FilteredDeckError; +pub use network::NetworkError; +pub use network::NetworkErrorKind; +pub use network::SyncError; +pub use network::SyncErrorKind; +pub use search::ParseError; +pub use search::SearchErrorKind; use snafu::Snafu; -pub use self::{ - file_io::{FileIoError, FileIoSnafu, FileOp}, - invalid_input::{InvalidInputError, OrInvalid}, - not_found::{NotFoundError, OrNotFound}, -}; -use crate::{i18n::I18n, links::HelpPage}; +pub use self::file_io::FileIoError; +pub use self::file_io::FileIoSnafu; +pub use self::file_io::FileOp; +pub use self::invalid_input::InvalidInputError; +pub use self::invalid_input::OrInvalid; +pub use self::not_found::NotFoundError; +pub use self::not_found::OrNotFound; +use crate::i18n::I18n; +use crate::links::HelpPage; pub type Result = std::result::Result; diff --git a/rslib/src/error/network.rs b/rslib/src/error/network.rs index 715e2144d..c9080a7bc 100644 --- a/rslib/src/error/network.rs +++ b/rslib/src/error/network.rs @@ -8,7 +8,8 @@ use reqwest::StatusCode; use snafu::Snafu; use super::AnkiError; -use crate::sync::{collection::sanity::SanityCheckCounts, error::HttpError}; +use crate::sync::collection::sanity::SanityCheckCounts; +use crate::sync::error::HttpError; #[derive(Debug, PartialEq, Eq, Snafu)] #[snafu(visibility(pub(crate)))] @@ -203,8 +204,8 @@ impl NetworkError { } } -// This needs rethinking; we should be attaching error context as errors are encountered -// instead of trying to determine the problem later. +// This needs rethinking; we should be attaching error context as errors are +// encountered instead of trying to determine the problem later. impl From for AnkiError { fn from(err: HttpError) -> Self { if let Some(source) = &err.source { diff --git a/rslib/src/error/not_found.rs b/rslib/src/error/not_found.rs index 05e3ad328..d446577c3 100644 --- a/rslib/src/error/not_found.rs +++ b/rslib/src/error/not_found.rs @@ -1,10 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{any, fmt}; +use std::any; +use std::fmt; -use convert_case::{Case, Casing}; -use snafu::{Backtrace, OptionExt, Snafu}; +use convert_case::Case; +use convert_case::Casing; +use snafu::Backtrace; +use snafu::OptionExt; +use snafu::Snafu; use crate::prelude::*; diff --git a/rslib/src/error/search.rs b/rslib/src/error/search.rs index a05a1ce08..3eac7f994 100644 --- a/rslib/src/error/search.rs +++ b/rslib/src/error/search.rs @@ -4,7 +4,8 @@ use std::num::ParseIntError; use anki_i18n::I18n; -use nom::error::{ErrorKind as NomErrorKind, ParseError as NomParseError}; +use nom::error::ErrorKind as NomErrorKind; +use nom::error::ParseError as NomParseError; use snafu::Snafu; use super::AnkiError; diff --git a/rslib/src/findreplace.rs b/rslib/src/findreplace.rs index fd31aae27..62dc7a224 100644 --- a/rslib/src/findreplace.rs +++ b/rslib/src/findreplace.rs @@ -5,13 +5,12 @@ use std::borrow::Cow; use regex::Regex; -use crate::{ - collection::Collection, - error::Result, - notes::{NoteId, TransformNoteOutput}, - prelude::*, - text::normalize_to_nfc, -}; +use crate::collection::Collection; +use crate::error::Result; +use crate::notes::NoteId; +use crate::notes::TransformNoteOutput; +use crate::prelude::*; +use crate::text::normalize_to_nfc; pub struct FindReplaceContext { nids: Vec, @@ -115,7 +114,8 @@ impl Collection { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, decks::DeckId}; + use crate::collection::open_test_collection; + use crate::decks::DeckId; #[test] fn findreplace() -> Result<()> { diff --git a/rslib/src/import_export/gather.rs b/rslib/src/import_export/gather.rs index 8a3fa4999..19348997a 100644 --- a/rslib/src/import_export/gather.rs +++ b/rslib/src/import_export/gather.rs @@ -1,20 +1,23 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; +use std::collections::HashSet; use itertools::Itertools; -use super::{ExportProgress, IncrementableProgress}; -use crate::{ - decks::immediate_parent_name, - io::filename_is_safe, - latex::extract_latex, - prelude::*, - revlog::RevlogEntry, - search::{CardTableGuard, NoteTableGuard}, - text::{extract_media_refs, extract_underscored_css_imports, extract_underscored_references}, -}; +use super::ExportProgress; +use super::IncrementableProgress; +use crate::decks::immediate_parent_name; +use crate::io::filename_is_safe; +use crate::latex::extract_latex; +use crate::prelude::*; +use crate::revlog::RevlogEntry; +use crate::search::CardTableGuard; +use crate::search::NoteTableGuard; +use crate::text::extract_media_refs; +use crate::text::extract_underscored_css_imports; +use crate::text::extract_underscored_references; #[derive(Debug, Default)] pub(super) struct ExchangeData { @@ -197,8 +200,8 @@ impl Collection { /// If with_scheduling, also gather all original decks of cards in filtered /// decks, so they don't have to be converted to regular decks on import. - /// If not with_scheduling, skip exporting the default deck to avoid changing - /// the importing client's defaults. + /// If not with_scheduling, skip exporting the default deck to avoid + /// changing the importing client's defaults. fn gather_decks(&mut self, with_scheduling: bool) -> Result> { let decks = if with_scheduling { self.storage.get_decks_and_original_for_search_cards() @@ -267,7 +270,8 @@ impl Collection { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, search::SearchNode}; + use crate::collection::open_test_collection; + use crate::search::SearchNode; #[test] fn should_gather_valid_notes() { diff --git a/rslib/src/import_export/insert.rs b/rslib/src/import_export/insert.rs index 21ab1be1c..476ad42bc 100644 --- a/rslib/src/import_export/insert.rs +++ b/rslib/src/import_export/insert.rs @@ -2,7 +2,8 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::gather::ExchangeData; -use crate::{prelude::*, revlog::RevlogEntry}; +use crate::prelude::*; +use crate::revlog::RevlogEntry; impl Collection { pub(super) fn insert_data(&mut self, data: &ExchangeData) -> Result<()> { diff --git a/rslib/src/import_export/mod.rs b/rslib/src/import_export/mod.rs index d9f3c00bf..5697e88d9 100644 --- a/rslib/src/import_export/mod.rs +++ b/rslib/src/import_export/mod.rs @@ -8,14 +8,13 @@ pub mod text; use std::marker::PhantomData; -pub use crate::pb::import_export::import_response::{Log as NoteLog, Note as LogNote}; -use crate::{ - prelude::*, - text::{ - newlines_to_spaces, strip_html_preserving_media_filenames, truncate_to_char_boundary, - CowMapping, - }, -}; +pub use crate::pb::import_export::import_response::Log as NoteLog; +pub use crate::pb::import_export::import_response::Note as LogNote; +use crate::prelude::*; +use crate::text::newlines_to_spaces; +use crate::text::strip_html_preserving_media_filenames; +use crate::text::truncate_to_char_boundary; +use crate::text::CowMapping; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ImportProgress { @@ -36,8 +35,8 @@ pub enum ExportProgress { Media(usize), } -/// Wrapper around a progress function, usually passed by the [crate::backend::Backend], -/// to make repeated calls more ergonomic. +/// Wrapper around a progress function, usually passed by the +/// [crate::backend::Backend], to make repeated calls more ergonomic. pub(crate) struct IncrementableProgress

(Box bool>); impl

IncrementableProgress

{ @@ -46,7 +45,8 @@ impl

IncrementableProgress

{ Self(Box::new(progress_fn)) } - /// Returns an [Incrementor] with an `increment()` function for use in loops. + /// Returns an [Incrementor] with an `increment()` function for use in + /// loops. pub(crate) fn incrementor<'inc, 'progress: 'inc, 'map: 'inc>( &'progress mut self, mut count_map: impl 'map + FnMut(usize) -> P, diff --git a/rslib/src/import_export/package/apkg/export.rs b/rslib/src/import_export/package/apkg/export.rs index aad5fd5fa..3be69e3f3 100644 --- a/rslib/src/import_export/package/apkg/export.rs +++ b/rslib/src/import_export/package/apkg/export.rs @@ -1,24 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::HashSet, - path::{Path, PathBuf}, -}; +use std::collections::HashSet; +use std::path::Path; +use std::path::PathBuf; -use crate::{ - collection::CollectionBuilder, - import_export::{ - gather::ExchangeData, - package::{ - colpkg::export::{export_collection, MediaIter}, - Meta, - }, - ExportProgress, IncrementableProgress, - }, - io::{atomic_rename, new_tempfile, new_tempfile_in_parent_of}, - prelude::*, -}; +use crate::collection::CollectionBuilder; +use crate::import_export::gather::ExchangeData; +use crate::import_export::package::colpkg::export::export_collection; +use crate::import_export::package::colpkg::export::MediaIter; +use crate::import_export::package::Meta; +use crate::import_export::ExportProgress; +use crate::import_export::IncrementableProgress; +use crate::io::atomic_rename; +use crate::io::new_tempfile; +use crate::io::new_tempfile_in_parent_of; +use crate::prelude::*; impl Collection { /// Returns number of exported notes. diff --git a/rslib/src/import_export/package/apkg/import/cards.rs b/rslib/src/import_export/package/apkg/import/cards.rs index 563037ce1..338213f0b 100644 --- a/rslib/src/import_export/package/apkg/import/cards.rs +++ b/rslib/src/import_export/package/apkg/import/cards.rs @@ -1,18 +1,16 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::{HashMap, HashSet}, - mem, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::mem; use super::Context; -use crate::{ - card::{CardQueue, CardType}, - config::SchedulerVersion, - prelude::*, - revlog::RevlogEntry, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::config::SchedulerVersion; +use crate::prelude::*; +use crate::revlog::RevlogEntry; type CardAsNidAndOrd = (NoteId, u16); @@ -23,7 +21,8 @@ struct CardContext<'a> { imported_notes: &'a HashMap, remapped_decks: &'a HashMap, - /// The number of days the source collection is ahead of the target collection + /// The number of days the source collection is ahead of the target + /// collection collection_delta: i32, scheduler_version: SchedulerVersion, existing_cards: HashSet, diff --git a/rslib/src/import_export/package/apkg/import/decks.rs b/rslib/src/import_export/package/apkg/import/decks.rs index 154b39d83..bb77dfc62 100644 --- a/rslib/src/import_export/package/apkg/import/decks.rs +++ b/rslib/src/import_export/package/apkg/import/decks.rs @@ -1,10 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, mem}; +use std::collections::HashMap; +use std::mem; use super::Context; -use crate::{decks::NormalDeck, prelude::*}; +use crate::decks::NormalDeck; +use crate::prelude::*; struct DeckContext<'d> { target_col: &'d mut Collection, @@ -207,7 +209,8 @@ mod test { use std::collections::HashSet; use super::*; - use crate::{collection::open_test_collection, tests::new_deck_with_machine_name}; + use crate::collection::open_test_collection; + use crate::tests::new_deck_with_machine_name; #[test] fn parents() { diff --git a/rslib/src/import_export/package/apkg/import/media.rs b/rslib/src/import_export/package/apkg/import/media.rs index 0ba168d2f..72eb00500 100644 --- a/rslib/src/import_export/package/apkg/import/media.rs +++ b/rslib/src/import_export/package/apkg/import/media.rs @@ -1,23 +1,23 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, fs::File, mem}; +use std::collections::HashMap; +use std::fs::File; +use std::mem; use zip::ZipArchive; use super::Context; -use crate::{ - error::{FileIoSnafu, FileOp}, - import_export::{ - package::{ - colpkg::export::MediaCopier, - media::{extract_media_entries, SafeMediaEntry}, - }, - ImportProgress, IncrementableProgress, - }, - media::files::{add_hash_suffix_to_file_stem, sha1_of_reader}, - prelude::*, -}; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::import_export::package::colpkg::export::MediaCopier; +use crate::import_export::package::media::extract_media_entries; +use crate::import_export::package::media::SafeMediaEntry; +use crate::import_export::ImportProgress; +use crate::import_export::IncrementableProgress; +use crate::media::files::add_hash_suffix_to_file_stem; +use crate::media::files::sha1_of_reader; +use crate::prelude::*; /// Map of source media files, that do not already exist in the target. #[derive(Default)] @@ -26,7 +26,8 @@ pub(super) struct MediaUseMap { /// entry with possibly remapped filename) checked: HashMap, /// Static files (latex, underscored). Usage is not tracked, and if the name - /// already exists in the target, it is skipped regardless of content equality. + /// already exists in the target, it is skipped regardless of content + /// equality. unchecked: Vec, } diff --git a/rslib/src/import_export/package/apkg/import/mod.rs b/rslib/src/import_export/package/apkg/import/mod.rs index 0ede571c6..d1133eeec 100644 --- a/rslib/src/import_export/package/apkg/import/mod.rs +++ b/rslib/src/import_export/package/apkg/import/mod.rs @@ -6,24 +6,28 @@ mod decks; mod media; mod notes; -use std::{collections::HashSet, fs::File, path::Path}; +use std::collections::HashSet; +use std::fs::File; +use std::path::Path; pub(crate) use notes::NoteMeta; use rusqlite::OptionalExtension; use tempfile::NamedTempFile; use zip::ZipArchive; -use crate::{ - collection::CollectionBuilder, - error::{FileIoSnafu, FileOp}, - import_export::{ - gather::ExchangeData, package::Meta, ImportProgress, IncrementableProgress, NoteLog, - }, - io::{new_tempfile, open_file}, - media::MediaManager, - prelude::*, - search::SearchNode, -}; +use crate::collection::CollectionBuilder; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::import_export::gather::ExchangeData; +use crate::import_export::package::Meta; +use crate::import_export::ImportProgress; +use crate::import_export::IncrementableProgress; +use crate::import_export::NoteLog; +use crate::io::new_tempfile; +use crate::io::open_file; +use crate::media::MediaManager; +use crate::prelude::*; +use crate::search::SearchNode; struct Context<'a> { target_col: &'a mut Collection, diff --git a/rslib/src/import_export/package/apkg/import/notes.rs b/rslib/src/import_export/package/apkg/import/notes.rs index 29e0c17d9..ba8aca31c 100644 --- a/rslib/src/import_export/package/apkg/import/notes.rs +++ b/rslib/src/import_export/package/apkg/import/notes.rs @@ -1,23 +1,23 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, - mem, - sync::Arc, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::collections::HashSet; +use std::mem; +use std::sync::Arc; -use sha1::{Digest, Sha1}; +use sha1::Digest; +use sha1::Sha1; -use super::{media::MediaUseMap, Context}; -use crate::{ - import_export::{ - package::media::safe_normalized_file_name, ImportProgress, IncrementableProgress, NoteLog, - }, - prelude::*, - text::replace_media_refs, -}; +use super::media::MediaUseMap; +use super::Context; +use crate::import_export::package::media::safe_normalized_file_name; +use crate::import_export::ImportProgress; +use crate::import_export::IncrementableProgress; +use crate::import_export::NoteLog; +use crate::prelude::*; +use crate::text::replace_media_refs; struct NoteContext<'a> { target_col: &'a mut Collection, @@ -33,8 +33,8 @@ struct NoteContext<'a> { #[derive(Debug, Default)] pub(super) struct NoteImports { pub(super) id_map: HashMap, - /// All notes from the source collection as [Vec]s of their fields, and grouped - /// by import result kind. + /// All notes from the source collection as [Vec]s of their fields, and + /// grouped by import result kind. pub(super) log: NoteLog, } @@ -292,7 +292,8 @@ impl Notetype { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, import_export::package::media::SafeMediaEntry}; + use crate::collection::open_test_collection; + use crate::import_export::package::media::SafeMediaEntry; /// Import [Note] into [Collection], optionally taking a [MediaUseMap], /// or a [Notetype] remapping. @@ -317,7 +318,8 @@ mod test { }}; } - /// Assert that exactly one [Note] is logged, and that with the given state and fields. + /// Assert that exactly one [Note] is logged, and that with the given state + /// and fields. macro_rules! assert_note_logged { ($log:expr, $state:ident, $fields:expr) => { assert_eq!($log.$state.pop().unwrap().fields, $fields); diff --git a/rslib/src/import_export/package/apkg/tests.rs b/rslib/src/import_export/package/apkg/tests.rs index 539ce28aa..4bf484a34 100644 --- a/rslib/src/import_export/package/apkg/tests.rs +++ b/rslib/src/import_export/package/apkg/tests.rs @@ -3,14 +3,15 @@ #![cfg(test)] -use std::{collections::HashSet, fs::File, io::Write}; +use std::collections::HashSet; +use std::fs::File; +use std::io::Write; -use crate::{ - media::{files::sha1_of_data, MediaManager}, - prelude::*, - search::SearchNode, - tests::open_fs_test_collection, -}; +use crate::media::files::sha1_of_data; +use crate::media::MediaManager; +use crate::prelude::*; +use crate::search::SearchNode; +use crate::tests::open_fs_test_collection; const SAMPLE_JPG: &str = "sample.jpg"; const SAMPLE_MP3: &str = "sample.mp3"; diff --git a/rslib/src/import_export/package/colpkg/export.rs b/rslib/src/import_export/package/colpkg/export.rs index eb5ce637b..fa7b7f4e6 100644 --- a/rslib/src/import_export/package/colpkg/export.rs +++ b/rslib/src/import_export/package/colpkg/export.rs @@ -1,34 +1,42 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - collections::HashMap, - ffi::OsStr, - fs::File, - io, - io::{Read, Write}, - path::{Path, PathBuf}, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::ffi::OsStr; +use std::fs::File; +use std::io; +use std::io::Read; +use std::io::Write; +use std::path::Path; +use std::path::PathBuf; use prost::Message; -use sha1::{Digest, Sha1}; +use sha1::Digest; +use sha1::Sha1; use tempfile::NamedTempFile; -use zip::{write::FileOptions, CompressionMethod, ZipWriter}; -use zstd::{ - stream::{raw::Encoder as RawEncoder, zio}, - Encoder, -}; +use zip::write::FileOptions; +use zip::CompressionMethod; +use zip::ZipWriter; +use zstd::stream::raw::Encoder as RawEncoder; +use zstd::stream::zio; +use zstd::Encoder; -use super::super::{MediaEntries, MediaEntry, Meta, Version}; -use crate::{ - collection::CollectionBuilder, - import_export::{ExportProgress, IncrementableProgress}, - io::{atomic_rename, new_tempfile, new_tempfile_in_parent_of, open_file, read_dir_files}, - media::files::filename_if_normalized, - prelude::*, - storage::SchemaVersion, -}; +use super::super::MediaEntries; +use super::super::MediaEntry; +use super::super::Meta; +use super::super::Version; +use crate::collection::CollectionBuilder; +use crate::import_export::ExportProgress; +use crate::import_export::IncrementableProgress; +use crate::io::atomic_rename; +use crate::io::new_tempfile; +use crate::io::new_tempfile_in_parent_of; +use crate::io::open_file; +use crate::io::read_dir_files; +use crate::media::files::filename_if_normalized; +use crate::prelude::*; +use crate::storage::SchemaVersion; /// Enable multithreaded compression if over this size. For smaller files, /// multithreading makes things slower, and in initial tests, the crossover @@ -77,7 +85,8 @@ impl Collection { pub struct MediaIter(Box>>); impl MediaIter { - /// Iterator over all files in the given path, without traversing subfolders. + /// Iterator over all files in the given path, without traversing + /// subfolders. pub fn from_folder(path: &Path) -> Result { Ok(Self(Box::new( read_dir_files(path)?.map(|res| res.map(|entry| entry.path())), diff --git a/rslib/src/import_export/package/colpkg/import.rs b/rslib/src/import_export/package/colpkg/import.rs index a8c1a6fbd..cd2224a11 100644 --- a/rslib/src/import_export/package/colpkg/import.rs +++ b/rslib/src/import_export/package/colpkg/import.rs @@ -1,30 +1,31 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - fs::File, - io, - io::Write, - path::{Path, PathBuf}, -}; +use std::fs::File; +use std::io; +use std::io::Write; +use std::path::Path; +use std::path::PathBuf; -use zip::{read::ZipFile, ZipArchive}; -use zstd::{self, stream::copy_decode}; +use zip::read::ZipFile; +use zip::ZipArchive; +use zstd::stream::copy_decode; -use crate::{ - collection::CollectionBuilder, - error::{FileIoSnafu, FileOp, ImportError}, - import_export::{ - package::{ - media::{extract_media_entries, SafeMediaEntry}, - Meta, - }, - ImportProgress, IncrementableProgress, - }, - io::{atomic_rename, create_dir_all, new_tempfile_in_parent_of, open_file}, - media::MediaManager, - prelude::*, -}; +use crate::collection::CollectionBuilder; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::error::ImportError; +use crate::import_export::package::media::extract_media_entries; +use crate::import_export::package::media::SafeMediaEntry; +use crate::import_export::package::Meta; +use crate::import_export::ImportProgress; +use crate::import_export::IncrementableProgress; +use crate::io::atomic_rename; +use crate::io::create_dir_all; +use crate::io::new_tempfile_in_parent_of; +use crate::io::open_file; +use crate::media::MediaManager; +use crate::prelude::*; pub fn import_colpkg( colpkg_path: &str, diff --git a/rslib/src/import_export/package/colpkg/tests.rs b/rslib/src/import_export/package/colpkg/tests.rs index e4e3f1ecc..e798b2538 100644 --- a/rslib/src/import_export/package/colpkg/tests.rs +++ b/rslib/src/import_export/package/colpkg/tests.rs @@ -7,13 +7,13 @@ use std::path::Path; use tempfile::tempdir; -use crate::{ - collection::CollectionBuilder, - import_export::package::import_colpkg, - io::{create_dir, create_dir_all, read_file}, - media::MediaManager, - prelude::*, -}; +use crate::collection::CollectionBuilder; +use crate::import_export::package::import_colpkg; +use crate::io::create_dir; +use crate::io::create_dir_all; +use crate::io::read_file; +use crate::media::MediaManager; +use crate::prelude::*; fn collection_with_media(dir: &Path, name: &str) -> Result { let name = format!("{name}_src"); diff --git a/rslib/src/import_export/package/media.rs b/rslib/src/import_export/package/media.rs index 2faa083d0..104270d77 100644 --- a/rslib/src/import_export/package/media.rs +++ b/rslib/src/import_export/package/media.rs @@ -1,26 +1,29 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - collections::HashMap, - fs, - fs::File, - io, - path::{Path, PathBuf}, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::fs; +use std::fs::File; +use std::io; +use std::path::Path; +use std::path::PathBuf; use prost::Message; -use zip::{read::ZipFile, ZipArchive}; +use zip::read::ZipFile; +use zip::ZipArchive; use zstd::stream::copy_decode; -use super::{colpkg::export::MediaCopier, MediaEntries, MediaEntry, Meta}; -use crate::{ - error::ImportError, - io::{atomic_rename, filename_is_safe, new_tempfile_in}, - media::files::normalize_filename, - prelude::*, -}; +use super::colpkg::export::MediaCopier; +use super::MediaEntries; +use super::MediaEntry; +use super::Meta; +use crate::error::ImportError; +use crate::io::atomic_rename; +use crate::io::filename_is_safe; +use crate::io::new_tempfile_in; +use crate::media::files::normalize_filename; +use crate::prelude::*; /// Like [MediaEntry], but with a safe filename and set zip filename. pub(super) struct SafeMediaEntry { @@ -100,7 +103,8 @@ impl SafeMediaEntry { fs::metadata(other_path).map_or(false, |metadata| metadata.len() == self.size as u64) } - /// Copy the archived file to the target folder, setting its hash if necessary. + /// Copy the archived file to the target folder, setting its hash if + /// necessary. pub(super) fn copy_and_ensure_sha1_set( &mut self, archive: &mut ZipArchive, diff --git a/rslib/src/import_export/package/meta.rs b/rslib/src/import_export/package/meta.rs index c5beea630..81f8dea78 100644 --- a/rslib/src/import_export/package/meta.rs +++ b/rslib/src/import_export/package/meta.rs @@ -1,14 +1,19 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs::File, io, io::Read}; +use std::fs::File; +use std::io; +use std::io::Read; use prost::Message; use zip::ZipArchive; use zstd::stream::copy_decode; -pub(super) use crate::pb::import_export::{package_metadata::Version, PackageMetadata as Meta}; -use crate::{error::ImportError, prelude::*, storage::SchemaVersion}; +use crate::error::ImportError; +pub(super) use crate::pb::import_export::package_metadata::Version; +pub(super) use crate::pb::import_export::PackageMetadata as Meta; +use crate::prelude::*; +use crate::storage::SchemaVersion; impl Version { pub(super) fn collection_filename(&self) -> &'static str { @@ -44,7 +49,8 @@ impl Meta { } } - /// Extracts meta data from an archive and checks if its version is supported. + /// Extracts meta data from an archive and checks if its version is + /// supported. pub(super) fn from_archive(archive: &mut ZipArchive) -> Result { let meta_bytes = archive.by_name("meta").ok().and_then(|mut meta_file| { let mut buf = vec![]; diff --git a/rslib/src/import_export/package/mod.rs b/rslib/src/import_export/package/mod.rs index c52a8a063..68f3d2b0e 100644 --- a/rslib/src/import_export/package/mod.rs +++ b/rslib/src/import_export/package/mod.rs @@ -9,6 +9,8 @@ mod meta; pub(crate) use apkg::NoteMeta; pub(crate) use colpkg::export::export_colpkg_from_data; pub use colpkg::import::import_colpkg; -pub(self) use meta::{Meta, Version}; +pub(self) use meta::Meta; +pub(self) use meta::Version; -pub(self) use crate::pb::import_export::{media_entries::MediaEntry, MediaEntries}; +pub(self) use crate::pb::import_export::media_entries::MediaEntry; +pub(self) use crate::pb::import_export::MediaEntries; diff --git a/rslib/src/import_export/text/csv/export.rs b/rslib/src/import_export/text/csv/export.rs index a31ab8c6c..142b9a34b 100644 --- a/rslib/src/import_export/text/csv/export.rs +++ b/rslib/src/import_export/text/csv/export.rs @@ -1,22 +1,27 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashMap, fs::File, io::Write, sync::Arc}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::fs::File; +use std::io::Write; +use std::sync::Arc; use itertools::Itertools; use lazy_static::lazy_static; use regex::Regex; use super::metadata::Delimiter; -use crate::{ - import_export::{ExportProgress, IncrementableProgress}, - notetype::RenderCardOutput, - pb::import_export::ExportNoteCsvRequest, - prelude::*, - search::{SearchNode, SortMode}, - template::RenderedNode, - text::{html_to_text_line, CowMapping}, -}; +use crate::import_export::ExportProgress; +use crate::import_export::IncrementableProgress; +use crate::notetype::RenderCardOutput; +use crate::pb::import_export::ExportNoteCsvRequest; +use crate::prelude::*; +use crate::search::SearchNode; +use crate::search::SortMode; +use crate::template::RenderedNode; +use crate::text::html_to_text_line; +use crate::text::CowMapping; const DELIMITER: Delimiter = Delimiter::Tab; diff --git a/rslib/src/import_export/text/csv/import.rs b/rslib/src/import_export/text/csv/import.rs index b3be378de..2accd0345 100644 --- a/rslib/src/import_export/text/csv/import.rs +++ b/rslib/src/import_export/text/csv/import.rs @@ -1,19 +1,23 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; +use std::io::BufRead; +use std::io::BufReader; +use std::io::Read; +use std::io::Seek; +use std::io::SeekFrom; -use crate::{ - import_export::{ - text::{ - csv::metadata::{CsvDeck, CsvMetadata, CsvNotetype, Delimiter}, - ForeignData, ForeignNote, NameOrId, - }, - ImportProgress, NoteLog, - }, - io::open_file, - prelude::*, -}; +use crate::import_export::text::csv::metadata::CsvDeck; +use crate::import_export::text::csv::metadata::CsvMetadata; +use crate::import_export::text::csv::metadata::CsvNotetype; +use crate::import_export::text::csv::metadata::Delimiter; +use crate::import_export::text::ForeignData; +use crate::import_export::text::ForeignNote; +use crate::import_export::text::NameOrId; +use crate::import_export::ImportProgress; +use crate::import_export::NoteLog; +use crate::io::open_file; +use crate::prelude::*; impl Collection { pub fn import_csv( @@ -111,7 +115,8 @@ struct ColumnContext { notetype_column: Option, /// Source column indices for the fields of a notetype field_source_columns: FieldSourceColumns, - /// How fields are converted to strings. Used for escaping HTML if appropriate. + /// How fields are converted to strings. Used for escaping HTML if + /// appropriate. stringify: fn(&str) -> String, } @@ -211,8 +216,8 @@ fn stringify_fn(is_html: bool) -> fn(&str) -> String { } } -/// If the reader's first line starts with "tags:", which is allowed for historic -/// reasons, seek to the second line. +/// If the reader's first line starts with "tags:", which is allowed for +/// historic reasons, seek to the second line. fn remove_tags_line_from_reader(reader: &mut (impl Read + Seek)) -> Result<()> { let mut buf_reader = BufReader::new(reader); let mut first_line = String::new(); diff --git a/rslib/src/import_export/text/csv/metadata.rs b/rslib/src/import_export/text/csv/metadata.rs index 44d9f97a1..680bc34b1 100644 --- a/rslib/src/import_export/text/csv/metadata.rs +++ b/rslib/src/import_export/text/csv/metadata.rs @@ -1,31 +1,33 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::{HashMap, HashSet}, - io::{BufRead, BufReader, Read, Seek, SeekFrom}, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::io::BufRead; +use std::io::BufReader; +use std::io::Read; +use std::io::Seek; +use std::io::SeekFrom; use itertools::Itertools; use strum::IntoEnumIterator; use super::import::build_csv_reader; -pub use crate::pb::import_export::{ - csv_metadata::{ - Deck as CsvDeck, Delimiter, DupeResolution, MappedNotetype, Notetype as CsvNotetype, - }, - CsvMetadata, -}; -use crate::{ - config::I32ConfigKey, - error::ImportError, - import_export::text::NameOrId, - io::open_file, - notetype::NoteField, - pb::generic::StringList, - prelude::*, - text::{html_to_text_line, is_html}, -}; +use crate::config::I32ConfigKey; +use crate::error::ImportError; +use crate::import_export::text::NameOrId; +use crate::io::open_file; +use crate::notetype::NoteField; +use crate::pb::generic::StringList; +pub use crate::pb::import_export::csv_metadata::Deck as CsvDeck; +pub use crate::pb::import_export::csv_metadata::Delimiter; +pub use crate::pb::import_export::csv_metadata::DupeResolution; +pub use crate::pb::import_export::csv_metadata::MappedNotetype; +pub use crate::pb::import_export::csv_metadata::Notetype as CsvNotetype; +pub use crate::pb::import_export::CsvMetadata; +use crate::prelude::*; +use crate::text::html_to_text_line; +use crate::text::is_html; /// The maximum number of preview rows. const PREVIEW_LENGTH: usize = 5; @@ -91,7 +93,8 @@ impl Collection { Ok(meta_len) } - /// True if the line is a meta line, i.e. a comment, or starting with 'tags:'. + /// True if the line is a meta line, i.e. a comment, or starting with + /// 'tags:'. fn parse_first_line(&mut self, line: &str, metadata: &mut CsvMetadata) -> bool { if let Some(tags) = line.strip_prefix("tags:") { metadata.global_tags = collect_tags(tags); diff --git a/rslib/src/import_export/text/import.rs b/rslib/src/import_export/text/import.rs index c5bc28c67..fde83056a 100644 --- a/rslib/src/import_export/text/import.rs +++ b/rslib/src/import_export/text/import.rs @@ -1,27 +1,32 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, - sync::Arc, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::collections::HashSet; +use std::sync::Arc; use super::NameOrId; -use crate::{ - card::{CardQueue, CardType}, - config::I32ConfigKey, - import_export::{ - text::{ - DupeResolution, ForeignCard, ForeignData, ForeignNote, ForeignNotetype, ForeignTemplate, - }, - ImportProgress, IncrementableProgress, NoteLog, - }, - notes::{field_checksum, normalize_field}, - notetype::{CardGenContext, CardTemplate, NoteField, NotetypeConfig}, - prelude::*, - text::strip_html_preserving_media_filenames, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::config::I32ConfigKey; +use crate::import_export::text::DupeResolution; +use crate::import_export::text::ForeignCard; +use crate::import_export::text::ForeignData; +use crate::import_export::text::ForeignNote; +use crate::import_export::text::ForeignNotetype; +use crate::import_export::text::ForeignTemplate; +use crate::import_export::ImportProgress; +use crate::import_export::IncrementableProgress; +use crate::import_export::NoteLog; +use crate::notes::field_checksum; +use crate::notes::normalize_field; +use crate::notetype::CardGenContext; +use crate::notetype::CardTemplate; +use crate::notetype::NoteField; +use crate::notetype::NotetypeConfig; +use crate::prelude::*; +use crate::text::strip_html_preserving_media_filenames; impl ForeignData { pub fn import( @@ -521,7 +526,8 @@ impl ForeignNote { .map(|field| strip_html_preserving_media_filenames(field.as_str())) } - /// If the first field is set, returns its checksum. Field is expected to be normalized. + /// If the first field is set, returns its checksum. Field is expected to be + /// normalized. fn checksum(&self) -> Option { self.first_field_stripped() .map(|field| field_checksum(&field)) diff --git a/rslib/src/import_export/text/json.rs b/rslib/src/import_export/text/json.rs index e8fc9004d..dc5f6d84f 100644 --- a/rslib/src/import_export/text/json.rs +++ b/rslib/src/import_export/text/json.rs @@ -1,11 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - import_export::{text::ForeignData, ImportProgress, NoteLog}, - io::read_file, - prelude::*, -}; +use crate::import_export::text::ForeignData; +use crate::import_export::ImportProgress; +use crate::import_export::NoteLog; +use crate::io::read_file; +use crate::prelude::*; impl Collection { pub fn import_json_file( diff --git a/rslib/src/import_export/text/mod.rs b/rslib/src/import_export/text/mod.rs index d9b6adf7d..4e4a8120c 100644 --- a/rslib/src/import_export/text/mod.rs +++ b/rslib/src/import_export/text/mod.rs @@ -5,7 +5,8 @@ pub mod csv; mod import; mod json; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use super::LogNote; use crate::pb::import_export::csv_metadata::DupeResolution; diff --git a/rslib/src/io.rs b/rslib/src/io.rs index 0f4ce278e..3957802f5 100644 --- a/rslib/src/io.rs +++ b/rslib/src/io.rs @@ -1,17 +1,16 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - fs::File, - path::{Component, Path}, -}; +use std::fs::File; +use std::path::Component; +use std::path::Path; use tempfile::NamedTempFile; -use crate::{ - error::{FileIoError, FileIoSnafu, FileOp}, - prelude::*, -}; +use crate::error::FileIoError; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::prelude::*; pub(crate) type Result = std::result::Result; diff --git a/rslib/src/latex.rs b/rslib/src/latex.rs index f64276c10..833463124 100644 --- a/rslib/src/latex.rs +++ b/rslib/src/latex.rs @@ -4,9 +4,12 @@ use std::borrow::Cow; use lazy_static::lazy_static; -use regex::{Captures, Regex}; +use regex::Captures; +use regex::Regex; -use crate::{cloze::expand_clozes_to_reveal_latex, media::files::sha1_of_data, text::strip_html}; +use crate::cloze::expand_clozes_to_reveal_latex; +use crate::media::files::sha1_of_data; +use crate::text::strip_html; lazy_static! { pub(crate) static ref LATEX: Regex = Regex::new( @@ -107,7 +110,8 @@ fn image_link_for_fname(src: &str, fname: &str) -> String { #[cfg(test)] mod test { - use crate::latex::{extract_latex, ExtractedLatex}; + use crate::latex::extract_latex; + use crate::latex::ExtractedLatex; #[test] fn latex() { diff --git a/rslib/src/log.rs b/rslib/src/log.rs index ecaa858ad..82c672f18 100644 --- a/rslib/src/log.rs +++ b/rslib/src/log.rs @@ -1,12 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs, fs::OpenOptions, io}; +use std::fs; +use std::fs::OpenOptions; +use std::io; use once_cell::sync::OnceCell; use tracing::subscriber::set_global_default; -use tracing_appender::non_blocking::{NonBlocking, WorkerGuard}; -use tracing_subscriber::{fmt, fmt::Layer, layer::SubscriberExt, EnvFilter}; +use tracing_appender::non_blocking::NonBlocking; +use tracing_appender::non_blocking::WorkerGuard; +use tracing_subscriber::fmt; +use tracing_subscriber::fmt::Layer; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::EnvFilter; use crate::prelude::*; @@ -31,8 +37,8 @@ pub fn set_global_logger(path: Option<&str>) -> Result<()> { Ok(()) } -/// Holding on to this guard does not actually ensure the log file will be fully written, -/// as statics do not implement Drop. +/// Holding on to this guard does not actually ensure the log file will be fully +/// written, as statics do not implement Drop. static APPENDER_GUARD: OnceCell = OnceCell::new(); fn get_appender(path: &str) -> Result { diff --git a/rslib/src/markdown.rs b/rslib/src/markdown.rs index 34de6dc01..88bb211f3 100644 --- a/rslib/src/markdown.rs +++ b/rslib/src/markdown.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use pulldown_cmark::{html, Parser}; +use pulldown_cmark::html; +use pulldown_cmark::Parser; pub(crate) fn render_markdown(markdown: &str) -> String { let mut buf = String::with_capacity(markdown.len()); diff --git a/rslib/src/media/check.rs b/rslib/src/media/check.rs index 08c769fdd..e36ca3bf0 100644 --- a/rslib/src/media/check.rs +++ b/rslib/src/media/check.rs @@ -1,28 +1,32 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, - fs, io, - path::Path, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::collections::HashSet; +use std::fs; +use std::io; +use std::path::Path; use anki_i18n::without_unicode_isolation; use tracing::debug; -use crate::{ - collection::Collection, - error::{AnkiError, DbErrorKind, Result}, - latex::extract_latex_expanding_clozes, - media::{ - files::{data_for_file, filename_if_normalized, normalize_nfc_filename, trash_folder}, - MediaManager, - }, - notes::Note, - sync::media::MAX_INDIVIDUAL_MEDIA_FILE_SIZE, - text::{extract_media_refs, normalize_to_nfc, MediaRef, REMOTE_FILENAME}, -}; +use crate::collection::Collection; +use crate::error::AnkiError; +use crate::error::DbErrorKind; +use crate::error::Result; +use crate::latex::extract_latex_expanding_clozes; +use crate::media::files::data_for_file; +use crate::media::files::filename_if_normalized; +use crate::media::files::normalize_nfc_filename; +use crate::media::files::trash_folder; +use crate::media::MediaManager; +use crate::notes::Note; +use crate::sync::media::MAX_INDIVIDUAL_MEDIA_FILE_SIZE; +use crate::text::extract_media_refs; +use crate::text::normalize_to_nfc; +use crate::text::MediaRef; +use crate::text::REMOTE_FILENAME; #[derive(Debug, PartialEq, Eq, Clone)] pub struct MediaCheckOutput { @@ -500,21 +504,24 @@ pub(crate) mod test { pub(crate) const MEDIACHECK_ANKI2: &[u8] = include_bytes!("../../tests/support/mediacheck.anki2"); - use std::{collections::HashMap, fs, io, path::Path}; + use std::collections::HashMap; + use std::fs; + use std::io; + use std::path::Path; - use tempfile::{tempdir, TempDir}; + use tempfile::tempdir; + use tempfile::TempDir; use super::normalize_and_maybe_rename_files; - use crate::{ - collection::{Collection, CollectionBuilder}, - error::Result, - io::{create_dir, write_file}, - media::{ - check::{MediaCheckOutput, MediaChecker}, - files::trash_folder, - MediaManager, - }, - }; + use crate::collection::Collection; + use crate::collection::CollectionBuilder; + use crate::error::Result; + use crate::io::create_dir; + use crate::io::write_file; + use crate::media::check::MediaCheckOutput; + use crate::media::check::MediaChecker; + use crate::media::files::trash_folder; + use crate::media::MediaManager; fn common_setup() -> Result<(TempDir, MediaManager, Collection)> { let dir = tempdir()?; @@ -626,7 +633,8 @@ Unused: unused.jpg vec!["test.jpg".to_string()] ); - // if we repeat the process, restoring should do the same thing if the contents are equal + // if we repeat the process, restoring should do the same thing if the contents + // are equal write_file(trash_folder.join("test.jpg"), "test")?; let mut checker = MediaChecker::new(&mut col, &mgr, progress); diff --git a/rslib/src/media/files.rs b/rslib/src/media/files.rs index 99a52b8f2..89c6b8a38 100644 --- a/rslib/src/media/files.rs +++ b/rslib/src/media/files.rs @@ -1,27 +1,31 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - fs, io, - io::Read, - path::{Path, PathBuf}, - time, -}; +use std::borrow::Cow; +use std::fs; +use std::io; +use std::io::Read; +use std::path::Path; +use std::path::PathBuf; +use std::time; use lazy_static::lazy_static; use regex::Regex; -use sha1::{Digest, Sha1}; +use sha1::Digest; +use sha1::Sha1; use tracing::debug; use unic_ucd_category::GeneralCategory; -use unicode_normalization::{is_nfc, UnicodeNormalization}; +use unicode_normalization::is_nfc; +use unicode_normalization::UnicodeNormalization; -use crate::{ - error::{FileIoError, FileIoSnafu, FileOp}, - io::{create_dir, open_file, write_file}, - prelude::*, - sync::media::MAX_MEDIA_FILENAME_LENGTH, -}; +use crate::error::FileIoError; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::io::create_dir; +use crate::io::open_file; +use crate::io::write_file; +use crate::prelude::*; +use crate::sync::media::MAX_MEDIA_FILENAME_LENGTH; lazy_static! { static ref WINDOWS_DEVICE_NAME: Regex = Regex::new( @@ -152,8 +156,8 @@ pub(crate) fn filename_if_normalized(fname: &str) -> Option> { } } -/// Write desired_name into folder, renaming if existing file has different content. -/// Returns the used filename. +/// Write desired_name into folder, renaming if existing file has different +/// content. Returns the used filename. pub fn add_data_to_folder_uniquely<'a, P>( folder: P, desired_name: &'a str, @@ -432,13 +436,13 @@ mod test { use tempfile::tempdir; - use crate::{ - media::files::{ - add_data_to_folder_uniquely, add_hash_suffix_to_file_stem, normalize_filename, - remove_files, sha1_of_data, truncate_filename, - }, - sync::media::MAX_MEDIA_FILENAME_LENGTH, - }; + use crate::media::files::add_data_to_folder_uniquely; + use crate::media::files::add_hash_suffix_to_file_stem; + use crate::media::files::normalize_filename; + use crate::media::files::remove_files; + use crate::media::files::sha1_of_data; + use crate::media::files::truncate_filename; + use crate::sync::media::MAX_MEDIA_FILENAME_LENGTH; #[test] fn normalize() { diff --git a/rslib/src/media/mod.rs b/rslib/src/media/mod.rs index c24f509ab..06a9259b9 100644 --- a/rslib/src/media/mod.rs +++ b/rslib/src/media/mod.rs @@ -4,26 +4,24 @@ pub mod check; pub mod files; -use std::{ - borrow::Cow, - collections::HashMap, - path::{Path, PathBuf}, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::path::Path; +use std::path::PathBuf; -use crate::{ - io::create_dir_all, - media::files::{add_data_to_folder_uniquely, mtime_as_i64, remove_files, sha1_of_data}, - prelude::*, - sync::{ - http_client::HttpSyncClient, - login::SyncAuth, - media::{ - database::client::{changetracker::ChangeTracker, MediaDatabase, MediaEntry}, - progress::MediaSyncProgress, - syncer::MediaSyncer, - }, - }, -}; +use crate::io::create_dir_all; +use crate::media::files::add_data_to_folder_uniquely; +use crate::media::files::mtime_as_i64; +use crate::media::files::remove_files; +use crate::media::files::sha1_of_data; +use crate::prelude::*; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::SyncAuth; +use crate::sync::media::database::client::changetracker::ChangeTracker; +use crate::sync::media::database::client::MediaDatabase; +use crate::sync::media::database::client::MediaEntry; +use crate::sync::media::progress::MediaSyncProgress; +use crate::sync::media::syncer::MediaSyncer; pub type Sha1Hash = [u8; 20]; diff --git a/rslib/src/notes/mod.rs b/rslib/src/notes/mod.rs index dfb512499..bddb01c23 100644 --- a/rslib/src/notes/mod.rs +++ b/rslib/src/notes/mod.rs @@ -3,26 +3,27 @@ pub(crate) mod undo; -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::collections::HashSet; use itertools::Itertools; use num_integer::Integer; -use sha1::{Digest, Sha1}; +use sha1::Digest; +use sha1::Sha1; -use crate::{ - cloze::contains_cloze, - define_newtype, - notetype::{CardGenContext, NoteField}, - ops::StateChanges, - pb, - pb::notes::note_fields_check_response::State as NoteFieldsState, - prelude::*, - template::field_is_empty, - text::{ensure_string_in_nfc, normalize_to_nfc, strip_html_preserving_media_filenames}, -}; +use crate::cloze::contains_cloze; +use crate::define_newtype; +use crate::notetype::CardGenContext; +use crate::notetype::NoteField; +use crate::ops::StateChanges; +use crate::pb; +use crate::pb::notes::note_fields_check_response::State as NoteFieldsState; +use crate::prelude::*; +use crate::template::field_is_empty; +use crate::text::ensure_string_in_nfc; +use crate::text::normalize_to_nfc; +use crate::text::strip_html_preserving_media_filenames; define_newtype!(NoteId, i64); @@ -628,11 +629,14 @@ fn note_differs_from_db(existing_note: &mut Note, note: &mut Note) -> bool { #[cfg(test)] mod test { - use super::{anki_base91, field_checksum}; - use crate::{ - collection::open_test_collection, config::BoolKey, decks::DeckId, error::Result, - prelude::*, search::SortMode, - }; + use super::anki_base91; + use super::field_checksum; + use crate::collection::open_test_collection; + use crate::config::BoolKey; + use crate::decks::DeckId; + use crate::error::Result; + use crate::prelude::*; + use crate::search::SortMode; #[test] fn test_base91() { diff --git a/rslib/src/notes/undo.rs b/rslib/src/notes/undo.rs index ff44836a8..095886d8f 100644 --- a/rslib/src/notes/undo.rs +++ b/rslib/src/notes/undo.rs @@ -2,7 +2,8 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::NoteTags; -use crate::{prelude::*, undo::UndoableChange}; +use crate::prelude::*; +use crate::undo::UndoableChange; #[derive(Debug)] pub(crate) enum UndoableNoteChange { @@ -57,7 +58,8 @@ impl Collection { Ok(()) } - /// If note is edited multiple times in quick succession, avoid creating extra undo entries. + /// If note is edited multiple times in quick succession, avoid creating + /// extra undo entries. pub(crate) fn maybe_coalesce_note_undo_entry(&mut self, changes: &OpChanges) { if changes.op != Op::UpdateNote { return; diff --git a/rslib/src/notetype/cardgen.rs b/rslib/src/notetype/cardgen.rs index 6ebbc6584..18f3f443a 100644 --- a/rslib/src/notetype/cardgen.rs +++ b/rslib/src/notetype/cardgen.rs @@ -1,19 +1,20 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::{HashMap, HashSet}, - ops::Deref, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::ops::Deref; use itertools::Itertools; -use rand::{rngs::StdRng, Rng, SeedableRng}; +use rand::rngs::StdRng; +use rand::Rng; +use rand::SeedableRng; use super::Notetype; -use crate::{ - cloze::add_cloze_numbers_in_string, notetype::NotetypeKind, prelude::*, - template::ParsedTemplate, -}; +use crate::cloze::add_cloze_numbers_in_string; +use crate::notetype::NotetypeKind; +use crate::prelude::*; +use crate::template::ParsedTemplate; /// Info about an existing card required when generating new cards #[derive(Debug, PartialEq, Eq)] @@ -39,8 +40,8 @@ pub(crate) struct SingleCardGenContext { target_deck_id: Option, } -/// Info required to determine which cards should be generated when note added/updated, -/// and where they should be placed. +/// Info required to determine which cards should be generated when note +/// added/updated, and where they should be placed. pub(crate) struct CardGenContext> { pub usn: Usn, pub notetype: N, @@ -74,8 +75,9 @@ impl> CardGenContext { } } - /// If template[ord] generates a non-empty question given nonempty_fields, return the provided - /// deck id, or an overridden one. If question is empty, return None. + /// If template[ord] generates a non-empty question given nonempty_fields, + /// return the provided deck id, or an overridden one. If question is + /// empty, return None. fn is_nonempty(&self, card_ord: usize, nonempty_fields: &HashSet<&str>) -> bool { let card = &self.cards[card_ord]; let template = match card.template { @@ -325,7 +327,8 @@ impl Collection { } } - /// If deck ID does not exist or points to a filtered deck, fall back on default. + /// If deck ID does not exist or points to a filtered deck, fall back on + /// default. fn deck_for_adding(&mut self, did: Option) -> Result<(DeckId, DeckConfigId)> { if let Some(did) = did { if let Some(deck) = self.deck_conf_if_normal(did)? { diff --git a/rslib/src/notetype/checks.rs b/rslib/src/notetype/checks.rs index eaa2cdb58..8a74e5d6f 100644 --- a/rslib/src/notetype/checks.rs +++ b/rslib/src/notetype/checks.rs @@ -1,18 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, fmt::Write, ops::Deref}; +use std::borrow::Cow; +use std::fmt::Write; +use std::ops::Deref; use anki_i18n::without_unicode_isolation; use lazy_static::lazy_static; -use regex::{Captures, Match, Regex}; +use regex::Captures; +use regex::Match; +use regex::Regex; use super::CardTemplate; -use crate::{ - latex::LATEX, - prelude::*, - text::{HTML_MEDIA_TAGS, SOUND_TAG}, -}; +use crate::latex::LATEX; +use crate::prelude::*; +use crate::text::HTML_MEDIA_TAGS; +use crate::text::SOUND_TAG; #[derive(Debug, PartialEq, Eq)] struct Template<'a> { diff --git a/rslib/src/notetype/emptycards.rs b/rslib/src/notetype/emptycards.rs index b15e06455..ab875622b 100644 --- a/rslib/src/notetype/emptycards.rs +++ b/rslib/src/notetype/emptycards.rs @@ -1,12 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashSet, fmt::Write}; +use std::collections::HashSet; +use std::fmt::Write; -use super::{ - cardgen::group_generated_cards_by_note, CardGenContext, Notetype, NotetypeId, NotetypeKind, -}; -use crate::{card::CardId, collection::Collection, error::Result, notes::NoteId}; +use super::cardgen::group_generated_cards_by_note; +use super::CardGenContext; +use super::Notetype; +use super::NotetypeId; +use super::NotetypeKind; +use crate::card::CardId; +use crate::collection::Collection; +use crate::error::Result; +use crate::notes::NoteId; pub struct EmptyCardsForNote { pub nid: NoteId, @@ -61,7 +67,8 @@ impl Collection { .collect() } - /// Create a report on empty cards. Mutates the provided data to sort ordinals. + /// Create a report on empty cards. Mutates the provided data to sort + /// ordinals. pub fn empty_cards_report( &mut self, empty: &mut [(NotetypeId, Vec)], diff --git a/rslib/src/notetype/fields.rs b/rslib/src/notetype/fields.rs index 505447daa..1907a14f8 100644 --- a/rslib/src/notetype/fields.rs +++ b/rslib/src/notetype/fields.rs @@ -1,8 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{NoteFieldConfig, NoteFieldProto}; -use crate::{pb::generic::UInt32, prelude::*}; +use super::NoteFieldConfig; +use super::NoteFieldProto; +use crate::pb::generic::UInt32; +use crate::prelude::*; #[derive(Debug, PartialEq, Clone)] pub struct NoteField { diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 16999786a..e9218161d 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -13,43 +13,48 @@ mod stock; mod templates; pub(crate) mod undo; -use std::{ - collections::{HashMap, HashSet}, - iter::FromIterator, - sync::Arc, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::iter::FromIterator; +use std::sync::Arc; -pub(crate) use cardgen::{AlreadyGeneratedCardInfo, CardGenContext}; +pub(crate) use cardgen::AlreadyGeneratedCardInfo; +pub(crate) use cardgen::CardGenContext; pub use fields::NoteField; use lazy_static::lazy_static; -pub use notetypechange::{ChangeNotetypeInput, NotetypeChangeInfo}; +pub use notetypechange::ChangeNotetypeInput; +pub use notetypechange::NotetypeChangeInfo; use regex::Regex; pub(crate) use render::RenderCardOutput; -pub use schema11::{CardTemplateSchema11, NoteFieldSchema11, NotetypeSchema11}; +pub use schema11::CardTemplateSchema11; +pub use schema11::NoteFieldSchema11; +pub use schema11::NotetypeSchema11; pub use stock::all_stock_notetypes; pub use templates::CardTemplate; use unicase::UniCase; -pub use crate::pb::notetypes::{ - notetype::{ - config::{ - card_requirement::Kind as CardRequirementKind, CardRequirement, Kind as NotetypeKind, - }, - field::Config as NoteFieldConfig, - template::Config as CardTemplateConfig, - Config as NotetypeConfig, Field as NoteFieldProto, Template as CardTemplateProto, - }, - Notetype as NotetypeProto, -}; -use crate::{ - define_newtype, - error::{CardTypeError, CardTypeErrorDetails, CardTypeSnafu, MissingClozeSnafu}, - prelude::*, - search::{JoinSearches, Node, SearchNode}, - storage::comma_separated_ids, - template::{FieldRequirements, ParsedTemplate}, - text::ensure_string_in_nfc, -}; +use crate::define_newtype; +use crate::error::CardTypeError; +use crate::error::CardTypeErrorDetails; +use crate::error::CardTypeSnafu; +use crate::error::MissingClozeSnafu; +pub use crate::pb::notetypes::notetype::config::card_requirement::Kind as CardRequirementKind; +pub use crate::pb::notetypes::notetype::config::CardRequirement; +pub use crate::pb::notetypes::notetype::config::Kind as NotetypeKind; +pub use crate::pb::notetypes::notetype::field::Config as NoteFieldConfig; +pub use crate::pb::notetypes::notetype::template::Config as CardTemplateConfig; +pub use crate::pb::notetypes::notetype::Config as NotetypeConfig; +pub use crate::pb::notetypes::notetype::Field as NoteFieldProto; +pub use crate::pb::notetypes::notetype::Template as CardTemplateProto; +pub use crate::pb::notetypes::Notetype as NotetypeProto; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::Node; +use crate::search::SearchNode; +use crate::storage::comma_separated_ids; +use crate::template::FieldRequirements; +use crate::template::ParsedTemplate; +use crate::text::ensure_string_in_nfc; define_newtype!(NotetypeId, i64); @@ -171,8 +176,8 @@ impl Collection { }) } - /// Used to support the current importing code; does not mark notetype as modified, - /// and does not support undo. + /// Used to support the current importing code; does not mark notetype as + /// modified, and does not support undo. pub fn add_or_update_notetype_with_existing_id( &mut self, notetype: &mut Notetype, @@ -597,8 +602,9 @@ impl Notetype { matches!(self.config.kind(), NotetypeKind::Cloze) } - /// Return all clozable fields. A field is clozable when it belongs to a cloze - /// notetype and a 'cloze' filter is applied to it in the template. + /// Return all clozable fields. A field is clozable when it belongs to a + /// cloze notetype and a 'cloze' filter is applied to it in the + /// template. pub(crate) fn cloze_fields(&self) -> HashSet { if !self.is_cloze() { HashSet::new() @@ -614,7 +620,8 @@ impl Notetype { } } -/// True if the slice is empty or either template of the first tuple doesn't have a cloze field. +/// True if the slice is empty or either template of the first tuple doesn't +/// have a cloze field. fn missing_cloze_filter( parsed_templates: &[(Option, Option)], ) -> bool { diff --git a/rslib/src/notetype/notetypechange.rs b/rslib/src/notetype/notetypechange.rs index f685f197d..fb85a5bfe 100644 --- a/rslib/src/notetype/notetypechange.rs +++ b/rslib/src/notetype/notetypechange.rs @@ -3,14 +3,18 @@ //! Updates to notes/cards when a note is moved to a different notetype. -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; +use std::collections::HashSet; -use super::{CardGenContext, Notetype, NotetypeKind}; -use crate::{ - prelude::*, - search::{JoinSearches, Node, SearchNode, TemplateKind}, - storage::comma_separated_ids, -}; +use super::CardGenContext; +use super::Notetype; +use super::NotetypeKind; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::Node; +use crate::search::SearchNode; +use crate::search::TemplateKind; +use crate::storage::comma_separated_ids; #[derive(Debug)] pub struct ChangeNotetypeInput { @@ -243,8 +247,8 @@ impl Collection { /// Rewrite notes to match new notetype, and assigns new notetype id. /// /// `new_fields` should be the length of the new notetype's fields, and is a - /// list of the previous field index each field should be mapped to. If None, - /// the field is left empty. + /// list of the previous field index each field should be mapped to. If + /// None, the field is left empty. fn update_notes_for_new_notetype_and_generate_cards( &mut self, note_ids: &[NoteId], @@ -370,7 +374,8 @@ fn remap_fields(fields: &mut Vec, new_fields: &[Option]) { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, error::Result}; + use crate::collection::open_test_collection; + use crate::error::Result; #[test] fn field_map() -> Result<()> { @@ -527,7 +532,8 @@ mod test { let cards = col.storage.all_cards_of_note(note.id)?; assert_eq!(cards.len(), 2); - // but any cards above the available templates should be removed when converting from cloze->normal + // but any cards above the available templates should be removed when converting + // from cloze->normal let input = ChangeNotetypeInput { note_ids: vec![note.id], ..col.notetype_change_info(basic.id, cloze.id)?.input diff --git a/rslib/src/notetype/render.rs b/rslib/src/notetype/render.rs index 94023eef9..2d23377e8 100644 --- a/rslib/src/notetype/render.rs +++ b/rslib/src/notetype/render.rs @@ -1,13 +1,17 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashMap}; +use std::borrow::Cow; +use std::collections::HashMap; -use super::{CardTemplate, Notetype, NotetypeKind}; -use crate::{ - prelude::*, - template::{field_is_empty, render_card, ParsedTemplate, RenderedNode}, -}; +use super::CardTemplate; +use super::Notetype; +use super::NotetypeKind; +use crate::prelude::*; +use crate::template::field_is_empty; +use crate::template::render_card; +use crate::template::ParsedTemplate; +use crate::template::RenderedNode; pub struct RenderCardOutput { pub qnodes: Vec, @@ -37,8 +41,8 @@ impl Collection { } /// Render a card that may not yet have been added. - /// The provided ordinal will be used if the template has not yet been saved. - /// If fill_empty is set, note will be mutated. + /// The provided ordinal will be used if the template has not yet been + /// saved. If fill_empty is set, note will be mutated. pub fn render_uncommitted_card( &mut self, note: &mut Note, diff --git a/rslib/src/notetype/schema11.rs b/rslib/src/notetype/schema11.rs index 5a0efa75d..fd38f9394 100644 --- a/rslib/src/notetype/schema11.rs +++ b/rslib/src/notetype/schema11.rs @@ -3,22 +3,28 @@ use std::collections::HashMap; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use serde_json::Value; -use serde_repr::{Deserialize_repr, Serialize_repr}; +use serde_repr::Deserialize_repr; +use serde_repr::Serialize_repr; use serde_tuple::Serialize_tuple; -use super::{CardRequirementKind, NotetypeId}; -use crate::{ - decks::DeckId, - notetype::{ - CardRequirement, CardTemplate, CardTemplateConfig, NoteField, NoteFieldConfig, Notetype, - NotetypeConfig, - }, - serde::{default_on_invalid, deserialize_bool_from_anything, deserialize_number_from_string}, - timestamp::TimestampSecs, - types::Usn, -}; +use super::CardRequirementKind; +use super::NotetypeId; +use crate::decks::DeckId; +use crate::notetype::CardRequirement; +use crate::notetype::CardTemplate; +use crate::notetype::CardTemplateConfig; +use crate::notetype::NoteField; +use crate::notetype::NoteFieldConfig; +use crate::notetype::Notetype; +use crate::notetype::NotetypeConfig; +use crate::serde::default_on_invalid; +use crate::serde::deserialize_bool_from_anything; +use crate::serde::deserialize_number_from_string; +use crate::timestamp::TimestampSecs; +use crate::types::Usn; #[derive(Serialize_repr, Deserialize_repr, PartialEq, Eq, Debug, Clone)] #[repr(u8)] diff --git a/rslib/src/notetype/schemachange.rs b/rslib/src/notetype/schemachange.rs index 67d2c5141..a202f8580 100644 --- a/rslib/src/notetype/schemachange.rs +++ b/rslib/src/notetype/schemachange.rs @@ -5,11 +5,12 @@ use std::collections::HashMap; -use super::{CardGenContext, CardTemplate, Notetype}; -use crate::{ - prelude::*, - search::{JoinSearches, TemplateKind}, -}; +use super::CardGenContext; +use super::CardTemplate; +use super::Notetype; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::TemplateKind; /// True if any ordinals added, removed or reordered. fn ords_changed(ords: &[Option], previous_len: usize) -> bool { @@ -129,8 +130,8 @@ impl Collection { } /// Update cards after card templates added, removed or reordered. - /// Does not remove cards where the template still exists but creates an empty card. - /// Caller must create transaction. + /// Does not remove cards where the template still exists but creates an + /// empty card. Caller must create transaction. pub(crate) fn update_cards_for_changed_templates( &mut self, nt: &Notetype, @@ -193,8 +194,12 @@ impl Notetype { #[cfg(test)] mod test { - use super::{ords_changed, TemplateOrdChanges}; - use crate::{collection::open_test_collection, decks::DeckId, error::Result, search::SortMode}; + use super::ords_changed; + use super::TemplateOrdChanges; + use crate::collection::open_test_collection; + use crate::decks::DeckId; + use crate::error::Result; + use crate::search::SortMode; #[test] fn ord_changes() { diff --git a/rslib/src/notetype/stock.rs b/rslib/src/notetype/stock.rs index 7b4578e0e..5abc689e5 100644 --- a/rslib/src/notetype/stock.rs +++ b/rslib/src/notetype/stock.rs @@ -2,15 +2,14 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::NotetypeConfig; -use crate::{ - config::{ConfigEntry, ConfigKey}, - error::Result, - i18n::I18n, - notetype::Notetype, - pb::notetypes::stock_notetype::Kind, - storage::SqliteStorage, - timestamp::TimestampSecs, -}; +use crate::config::ConfigEntry; +use crate::config::ConfigKey; +use crate::error::Result; +use crate::i18n::I18n; +use crate::notetype::Notetype; +use crate::pb::notetypes::stock_notetype::Kind; +use crate::storage::SqliteStorage; +use crate::timestamp::TimestampSecs; impl SqliteStorage { pub(crate) fn add_stock_notetypes(&self, tr: &I18n) -> Result<()> { diff --git a/rslib/src/notetype/templates.rs b/rslib/src/notetype/templates.rs index 39631a616..894dbe3df 100644 --- a/rslib/src/notetype/templates.rs +++ b/rslib/src/notetype/templates.rs @@ -1,8 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{CardTemplateConfig, CardTemplateProto}; -use crate::{pb::generic::UInt32, prelude::*, template::ParsedTemplate}; +use super::CardTemplateConfig; +use super::CardTemplateProto; +use crate::pb::generic::UInt32; +use crate::prelude::*; +use crate::template::ParsedTemplate; #[derive(Debug, PartialEq, Clone)] pub struct CardTemplate { @@ -96,7 +99,8 @@ impl CardTemplate { } } - /// Return whether the name is valid. Remove quote characters if it leads to a valid name. + /// Return whether the name is valid. Remove quote characters if it leads to + /// a valid name. pub(crate) fn fix_name(&mut self) -> Result<()> { let bad_chars = |c| c == '"'; require!(!self.name.is_empty(), "Empty template name"); diff --git a/rslib/src/preferences.rs b/rslib/src/preferences.rs index 6ed4f7f1f..01ecb5769 100644 --- a/rslib/src/preferences.rs +++ b/rslib/src/preferences.rs @@ -1,17 +1,17 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - collection::Collection, - config::{BoolKey, StringKey}, - error::Result, - pb::config::{ - preferences::{scheduling::NewReviewMix as NewRevMixPB, Editing, Reviewing, Scheduling}, - Preferences, - }, - prelude::*, - scheduler::timing::local_minutes_west_for_stamp, -}; +use crate::collection::Collection; +use crate::config::BoolKey; +use crate::config::StringKey; +use crate::error::Result; +use crate::pb::config::preferences::scheduling::NewReviewMix as NewRevMixPB; +use crate::pb::config::preferences::Editing; +use crate::pb::config::preferences::Reviewing; +use crate::pb::config::preferences::Scheduling; +use crate::pb::config::Preferences; +use crate::prelude::*; +use crate::scheduler::timing::local_minutes_west_for_stamp; impl Collection { pub fn get_preferences(&self) -> Result { diff --git a/rslib/src/prelude.rs b/rslib/src/prelude.rs index afcce36f2..93efef532 100644 --- a/rslib/src/prelude.rs +++ b/rslib/src/prelude.rs @@ -3,23 +3,35 @@ pub use snafu::ResultExt; +pub use crate::card::Card; +pub use crate::card::CardId; +pub use crate::collection::Collection; +pub use crate::config::BoolKey; +pub use crate::deckconfig::DeckConfig; +pub use crate::deckconfig::DeckConfigId; +pub use crate::decks::Deck; +pub use crate::decks::DeckId; +pub use crate::decks::DeckKind; +pub use crate::decks::NativeDeckName; +pub use crate::error::AnkiError; +pub use crate::error::OrInvalid; +pub use crate::error::OrNotFound; +pub use crate::error::Result; +pub use crate::i18n::I18n; +pub use crate::invalid_input; +pub use crate::media::Sha1Hash; +pub use crate::notes::Note; +pub use crate::notes::NoteId; +pub use crate::notetype::Notetype; +pub use crate::notetype::NotetypeId; +pub use crate::ops::Op; +pub use crate::ops::OpChanges; +pub use crate::ops::OpOutput; +pub use crate::require; +pub use crate::revlog::RevlogId; +pub use crate::search::SearchBuilder; +pub use crate::search::TryIntoSearch; +pub use crate::timestamp::TimestampMillis; +pub use crate::timestamp::TimestampSecs; pub(crate) use crate::types::IntoNewtypeVec; -pub use crate::{ - card::{Card, CardId}, - collection::Collection, - config::BoolKey, - deckconfig::{DeckConfig, DeckConfigId}, - decks::{Deck, DeckId, DeckKind, NativeDeckName}, - error::{AnkiError, OrInvalid, OrNotFound, Result}, - i18n::I18n, - invalid_input, - media::Sha1Hash, - notes::{Note, NoteId}, - notetype::{Notetype, NotetypeId}, - ops::{Op, OpChanges, OpOutput}, - require, - revlog::RevlogId, - search::{SearchBuilder, TryIntoSearch}, - timestamp::{TimestampMillis, TimestampSecs}, - types::Usn, -}; +pub use crate::types::Usn; diff --git a/rslib/src/revlog/mod.rs b/rslib/src/revlog/mod.rs index ded0083d1..a43f3f8ee 100644 --- a/rslib/src/revlog/mod.rs +++ b/rslib/src/revlog/mod.rs @@ -5,14 +5,14 @@ pub(crate) mod undo; use num_enum::TryFromPrimitive; use serde::Deserialize; -use serde_repr::{Deserialize_repr, Serialize_repr}; +use serde_repr::Deserialize_repr; +use serde_repr::Serialize_repr; use serde_tuple::Serialize_tuple; -use crate::{ - define_newtype, - prelude::*, - serde::{default_on_invalid, deserialize_int_from_number}, -}; +use crate::define_newtype; +use crate::prelude::*; +use crate::serde::default_on_invalid; +use crate::serde::deserialize_int_from_number; define_newtype!(RevlogId, i64); @@ -47,7 +47,8 @@ pub struct RevlogEntry { /// Positive values are in days, negative values in seconds. #[serde(rename = "lastIvl", deserialize_with = "deserialize_int_from_number")] pub last_interval: i32, - /// Card's ease after answering, stored as 10x the %, eg 2500 represents 250%. + /// Card's ease after answering, stored as 10x the %, eg 2500 represents + /// 250%. #[serde(rename = "factor", deserialize_with = "deserialize_int_from_number")] pub ease_factor: u32, /// Amount of milliseconds taken to answer the card. diff --git a/rslib/src/scheduler/answering/current.rs b/rslib/src/scheduler/answering/current.rs index 9db8601f8..1ad21d908 100644 --- a/rslib/src/scheduler/answering/current.rs +++ b/rslib/src/scheduler/answering/current.rs @@ -2,14 +2,16 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::CardStateUpdater; -use crate::{ - card::CardType, - decks::DeckKind, - scheduler::states::{ - CardState, LearnState, NewState, NormalState, PreviewState, RelearnState, - ReschedulingFilterState, ReviewState, - }, -}; +use crate::card::CardType; +use crate::decks::DeckKind; +use crate::scheduler::states::CardState; +use crate::scheduler::states::LearnState; +use crate::scheduler::states::NewState; +use crate::scheduler::states::NormalState; +use crate::scheduler::states::PreviewState; +use crate::scheduler::states::RelearnState; +use crate::scheduler::states::ReschedulingFilterState; +use crate::scheduler::states::ReviewState; impl CardStateUpdater { pub(crate) fn current_card_state(&self) -> CardState { diff --git a/rslib/src/scheduler/answering/learning.rs b/rslib/src/scheduler/answering/learning.rs index 1e2d16b57..6a8f6195e 100644 --- a/rslib/src/scheduler/answering/learning.rs +++ b/rslib/src/scheduler/answering/learning.rs @@ -1,14 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use rand::{prelude::*, rngs::StdRng}; +use rand::prelude::*; +use rand::rngs::StdRng; -use super::{CardStateUpdater, RevlogEntryPartial}; -use crate::{ - card::{CardQueue, CardType}, - prelude::*, - scheduler::states::{CardState, IntervalKind, LearnState, NewState}, -}; +use super::CardStateUpdater; +use super::RevlogEntryPartial; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::prelude::*; +use crate::scheduler::states::CardState; +use crate::scheduler::states::IntervalKind; +use crate::scheduler::states::LearnState; +use crate::scheduler::states::NewState; impl CardStateUpdater { pub(super) fn apply_new_state( diff --git a/rslib/src/scheduler/answering/mod.rs b/rslib/src/scheduler/answering/mod.rs index f68dcd005..3e4923a80 100644 --- a/rslib/src/scheduler/answering/mod.rs +++ b/rslib/src/scheduler/answering/mod.rs @@ -8,23 +8,24 @@ mod relearning; mod review; mod revlog; -use rand::{prelude::*, rngs::StdRng}; +use rand::prelude::*; +use rand::rngs::StdRng; use revlog::RevlogEntryPartial; -use super::{ - states::{ - steps::LearningSteps, CardState, FilteredState, NormalState, SchedulingStates, StateContext, - }, - timespan::answer_button_time_collapsible, - timing::SchedTimingToday, -}; -use crate::{ - card::CardQueue, - deckconfig::{DeckConfig, LeechAction}, - decks::Deck, - pb, - prelude::*, -}; +use super::states::steps::LearningSteps; +use super::states::CardState; +use super::states::FilteredState; +use super::states::NormalState; +use super::states::SchedulingStates; +use super::states::StateContext; +use super::timespan::answer_button_time_collapsible; +use super::timing::SchedTimingToday; +use crate::card::CardQueue; +use crate::deckconfig::DeckConfig; +use crate::deckconfig::LeechAction; +use crate::decks::Deck; +use crate::pb; +use crate::prelude::*; #[derive(Copy, Clone)] pub enum Rating { @@ -119,7 +120,8 @@ impl CardStateUpdater { invalid_input!("should set finished=true, not return different state") } FilteredState::Rescheduling(_) => { - // card needs to be removed from normal filtered deck, then scheduled normally + // card needs to be removed from normal filtered deck, then scheduled + // normally self.card.remove_from_filtered_deck_before_reschedule(); } } @@ -449,9 +451,10 @@ fn get_fuzz_factor(seed: Option) -> Option { #[cfg(test)] mod test { use super::*; - use crate::{ - card::CardType, collection::open_test_collection, deckconfig::ReviewMix, search::SortMode, - }; + use crate::card::CardType; + use crate::collection::open_test_collection; + use crate::deckconfig::ReviewMix; + use crate::search::SortMode; fn current_state(col: &mut Collection, card_id: CardId) -> CardState { col.get_scheduling_states(card_id).unwrap().current diff --git a/rslib/src/scheduler/answering/preview.rs b/rslib/src/scheduler/answering/preview.rs index 42387748d..74caa0da5 100644 --- a/rslib/src/scheduler/answering/preview.rs +++ b/rslib/src/scheduler/answering/preview.rs @@ -1,12 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{CardStateUpdater, RevlogEntryPartial}; -use crate::{ - card::CardQueue, - config::SchedulerVersion, - scheduler::states::{CardState, IntervalKind, PreviewState}, -}; +use super::CardStateUpdater; +use super::RevlogEntryPartial; +use crate::card::CardQueue; +use crate::config::SchedulerVersion; +use crate::scheduler::states::CardState; +use crate::scheduler::states::IntervalKind; +use crate::scheduler::states::PreviewState; impl CardStateUpdater { pub(super) fn apply_preview_state( @@ -40,16 +41,14 @@ impl CardStateUpdater { #[cfg(test)] mod test { use super::*; - use crate::{ - card::CardType, - collection::open_test_collection, - prelude::*, - scheduler::{ - answering::{CardAnswer, Rating}, - states::{CardState, FilteredState}, - }, - timestamp::TimestampMillis, - }; + use crate::card::CardType; + use crate::collection::open_test_collection; + use crate::prelude::*; + use crate::scheduler::answering::CardAnswer; + use crate::scheduler::answering::Rating; + use crate::scheduler::states::CardState; + use crate::scheduler::states::FilteredState; + use crate::timestamp::TimestampMillis; #[test] fn preview() -> Result<()> { diff --git a/rslib/src/scheduler/answering/relearning.rs b/rslib/src/scheduler/answering/relearning.rs index 01596fefb..03b903a56 100644 --- a/rslib/src/scheduler/answering/relearning.rs +++ b/rslib/src/scheduler/answering/relearning.rs @@ -1,11 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{CardStateUpdater, RevlogEntryPartial}; -use crate::{ - card::{CardQueue, CardType}, - scheduler::states::{CardState, IntervalKind, RelearnState}, -}; +use super::CardStateUpdater; +use super::RevlogEntryPartial; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::scheduler::states::CardState; +use crate::scheduler::states::IntervalKind; +use crate::scheduler::states::RelearnState; impl CardStateUpdater { pub(super) fn apply_relearning_state( diff --git a/rslib/src/scheduler/answering/review.rs b/rslib/src/scheduler/answering/review.rs index f87e3288f..a46f61bfd 100644 --- a/rslib/src/scheduler/answering/review.rs +++ b/rslib/src/scheduler/answering/review.rs @@ -1,11 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{CardStateUpdater, RevlogEntryPartial}; -use crate::{ - card::{CardQueue, CardType}, - scheduler::states::{CardState, ReviewState}, -}; +use super::CardStateUpdater; +use super::RevlogEntryPartial; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::scheduler::states::CardState; +use crate::scheduler::states::ReviewState; impl CardStateUpdater { pub(super) fn apply_review_state( diff --git a/rslib/src/scheduler/answering/revlog.rs b/rslib/src/scheduler/answering/revlog.rs index be64a98bb..db14e60be 100644 --- a/rslib/src/scheduler/answering/revlog.rs +++ b/rslib/src/scheduler/answering/revlog.rs @@ -1,11 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - prelude::*, - revlog::{RevlogEntry, RevlogReviewKind}, - scheduler::states::{CardState, IntervalKind}, -}; +use crate::prelude::*; +use crate::revlog::RevlogEntry; +use crate::revlog::RevlogReviewKind; +use crate::scheduler::states::CardState; +use crate::scheduler::states::IntervalKind; pub struct RevlogEntryPartial { interval: IntervalKind, diff --git a/rslib/src/scheduler/bury_and_suspend.rs b/rslib/src/scheduler/bury_and_suspend.rs index d54c361d7..29e34ecd5 100644 --- a/rslib/src/scheduler/bury_and_suspend.rs +++ b/rslib/src/scheduler/bury_and_suspend.rs @@ -2,16 +2,14 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::timing::SchedTimingToday; -use crate::{ - card::CardQueue, - config::SchedulerVersion, - pb::scheduler::{ - bury_or_suspend_cards_request::Mode as BuryOrSuspendMode, - unbury_deck_request::Mode as UnburyDeckMode, - }, - prelude::*, - search::{JoinSearches, SearchNode, StateKind}, -}; +use crate::card::CardQueue; +use crate::config::SchedulerVersion; +use crate::pb::scheduler::bury_or_suspend_cards_request::Mode as BuryOrSuspendMode; +use crate::pb::scheduler::unbury_deck_request::Mode as UnburyDeckMode; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::SearchNode; +use crate::search::StateKind; impl Card { /// True if card was buried/suspended prior to the call. @@ -159,11 +157,12 @@ impl Collection { #[cfg(test)] mod test { - use crate::{ - card::{Card, CardQueue}, - collection::{open_test_collection, Collection}, - search::{SortMode, StateKind}, - }; + use crate::card::Card; + use crate::card::CardQueue; + use crate::collection::open_test_collection; + use crate::collection::Collection; + use crate::search::SortMode; + use crate::search::StateKind; #[test] fn unbury() { diff --git a/rslib/src/scheduler/congrats.rs b/rslib/src/scheduler/congrats.rs index e17d5e197..22f11c333 100644 --- a/rslib/src/scheduler/congrats.rs +++ b/rslib/src/scheduler/congrats.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{pb, prelude::*}; +use crate::pb; +use crate::prelude::*; #[derive(Debug)] pub(crate) struct CongratsInfo { diff --git a/rslib/src/scheduler/filtered/card.rs b/rslib/src/scheduler/filtered/card.rs index 630605a2d..69da3b087 100644 --- a/rslib/src/scheduler/filtered/card.rs +++ b/rslib/src/scheduler/filtered/card.rs @@ -2,11 +2,10 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::DeckFilterContext; -use crate::{ - card::{CardQueue, CardType}, - config::SchedulerVersion, - prelude::*, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::config::SchedulerVersion; +use crate::prelude::*; impl Card { pub(crate) fn restore_queue_from_type(&mut self) { @@ -26,7 +25,8 @@ impl Card { } pub(crate) fn move_into_filtered_deck(&mut self, ctx: &DeckFilterContext, position: i32) { - // filtered and v1 learning cards are excluded, so odue should be guaranteed to be zero + // filtered and v1 learning cards are excluded, so odue should be guaranteed to + // be zero if self.original_due != 0 { println!("bug: odue was set"); return; diff --git a/rslib/src/scheduler/filtered/custom_study.rs b/rslib/src/scheduler/filtered/custom_study.rs index e737ac80c..8617e7c35 100644 --- a/rslib/src/scheduler/filtered/custom_study.rs +++ b/rslib/src/scheduler/filtered/custom_study.rs @@ -4,15 +4,23 @@ use std::collections::HashSet; use super::FilteredDeckForUpdate; -use crate::{ - config::DeckConfigKey, - decks::{FilteredDeck, FilteredSearchOrder, FilteredSearchTerm}, - error::{CustomStudyError, FilteredDeckError}, - pb, - pb::scheduler::custom_study_request::{cram::CramKind, Cram, Value as CustomStudyValue}, - prelude::*, - search::{JoinSearches, Negated, PropertyKind, RatingKind, SearchNode, StateKind}, -}; +use crate::config::DeckConfigKey; +use crate::decks::FilteredDeck; +use crate::decks::FilteredSearchOrder; +use crate::decks::FilteredSearchTerm; +use crate::error::CustomStudyError; +use crate::error::FilteredDeckError; +use crate::pb; +use crate::pb::scheduler::custom_study_request::cram::CramKind; +use crate::pb::scheduler::custom_study_request::Cram; +use crate::pb::scheduler::custom_study_request::Value as CustomStudyValue; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::Negated; +use crate::search::PropertyKind; +use crate::search::RatingKind; +use crate::search::SearchNode; +use crate::search::StateKind; impl Collection { pub fn custom_study( @@ -291,13 +299,11 @@ fn tags_to_nodes(tags_to_include: &[String], tags_to_exclude: &[String]) -> Sear #[cfg(test)] mod test { use super::*; - use crate::{ - collection::open_test_collection, - pb::scheduler::{ - custom_study_request::{cram::CramKind, Cram, Value}, - CustomStudyRequest, - }, - }; + use crate::collection::open_test_collection; + use crate::pb::scheduler::custom_study_request::cram::CramKind; + use crate::pb::scheduler::custom_study_request::Cram; + use crate::pb::scheduler::custom_study_request::Value; + use crate::pb::scheduler::CustomStudyRequest; #[test] fn tag_remembering() -> Result<()> { diff --git a/rslib/src/scheduler/filtered/mod.rs b/rslib/src/scheduler/filtered/mod.rs index c52ce2d10..a97a36a7e 100644 --- a/rslib/src/scheduler/filtered/mod.rs +++ b/rslib/src/scheduler/filtered/mod.rs @@ -4,17 +4,16 @@ mod card; mod custom_study; -use crate::{ - config::{ConfigKey, SchedulerVersion}, - decks::{FilteredDeck, FilteredSearchTerm}, - error::FilteredDeckError, - prelude::*, - search::{ - writer::{deck_search, normalize_search}, - SortMode, - }, - storage::card::filtered::order_and_limit_for_search, -}; +use crate::config::ConfigKey; +use crate::config::SchedulerVersion; +use crate::decks::FilteredDeck; +use crate::decks::FilteredSearchTerm; +use crate::error::FilteredDeckError; +use crate::prelude::*; +use crate::search::writer::deck_search; +use crate::search::writer::normalize_search; +use crate::search::SortMode; +use crate::storage::card::filtered::order_and_limit_for_search; /// Contains the parts of a filtered deck required for modifying its settings in /// the UI. @@ -33,8 +32,8 @@ pub(crate) struct DeckFilterContext<'a> { } impl Collection { - /// Get an existing filtered deck, or create a new one if `deck_id` is 0. The new deck - /// will not be added to the DB. + /// Get an existing filtered deck, or create a new one if `deck_id` is 0. + /// The new deck will not be added to the DB. pub fn get_or_create_filtered_deck( &mut self, deck_id: DeckId, @@ -48,10 +47,10 @@ impl Collection { deck.try_into() } - /// If the provided `deck_id` is 0, add provided deck to the DB, and rebuild it. If the - /// searches are invalid or do not match anything, adding is aborted. - /// If an existing deck is provided, it will be updated. Invalid searches or an empty - /// match will abort the update. + /// If the provided `deck_id` is 0, add provided deck to the DB, and rebuild + /// it. If the searches are invalid or do not match anything, adding is + /// aborted. If an existing deck is provided, it will be updated. + /// Invalid searches or an empty match will abort the update. /// Returns the deck_id, which will have changed if the id was 0. pub fn add_or_update_filtered_deck( &mut self, diff --git a/rslib/src/scheduler/learning.rs b/rslib/src/scheduler/learning.rs index e57763b57..08c3139c3 100644 --- a/rslib/src/scheduler/learning.rs +++ b/rslib/src/scheduler/learning.rs @@ -1,10 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - card::{Card, CardQueue, CardType}, - deckconfig::INITIAL_EASE_FACTOR_THOUSANDS, -}; +use crate::card::Card; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::deckconfig::INITIAL_EASE_FACTOR_THOUSANDS; impl Card { /// Remove the card from the (re)learning queue. diff --git a/rslib/src/scheduler/mod.rs b/rslib/src/scheduler/mod.rs index 83fb23910..cd50ec55f 100644 --- a/rslib/src/scheduler/mod.rs +++ b/rslib/src/scheduler/mod.rs @@ -1,7 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{collection::Collection, config::SchedulerVersion, error::Result, prelude::*}; +use crate::collection::Collection; +use crate::config::SchedulerVersion; +use crate::error::Result; +use crate::prelude::*; pub mod answering; pub mod bury_and_suspend; @@ -18,10 +21,10 @@ mod upgrade; use chrono::FixedOffset; pub use reviews::parse_due_date_str; -use timing::{ - sched_timing_today, v1_creation_date_adjusted_to_hour, v1_rollover_from_creation_stamp, - SchedTimingToday, -}; +use timing::sched_timing_today; +use timing::v1_creation_date_adjusted_to_hour; +use timing::v1_rollover_from_creation_stamp; +use timing::SchedTimingToday; #[derive(Debug, Clone, Copy)] pub struct SchedulerInfo { diff --git a/rslib/src/scheduler/new.rs b/rslib/src/scheduler/new.rs index 1f2a9952d..afd0b6b03 100644 --- a/rslib/src/scheduler/new.rs +++ b/rslib/src/scheduler/new.rs @@ -1,21 +1,24 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; +use std::collections::HashSet; use rand::seq::SliceRandom; -pub use crate::pb::scheduler::{ - schedule_cards_as_new_request::Context as ScheduleAsNewContext, RepositionDefaultsResponse, - ScheduleCardsAsNewDefaultsResponse, -}; -use crate::{ - card::{CardQueue, CardType}, - config::{BoolKey, SchedulerVersion}, - deckconfig::NewCardInsertOrder, - prelude::*, - search::{JoinSearches, SearchNode, SortMode, StateKind}, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::config::BoolKey; +use crate::config::SchedulerVersion; +use crate::deckconfig::NewCardInsertOrder; +pub use crate::pb::scheduler::schedule_cards_as_new_request::Context as ScheduleAsNewContext; +pub use crate::pb::scheduler::RepositionDefaultsResponse; +pub use crate::pb::scheduler::ScheduleCardsAsNewDefaultsResponse; +use crate::prelude::*; +use crate::search::JoinSearches; +use crate::search::SearchNode; +use crate::search::SortMode; +use crate::search::StateKind; impl Card { pub(crate) fn original_or_current_due(&self) -> i32 { @@ -254,8 +257,8 @@ impl Collection { } } - /// This is handled by update_deck_configs() now; this function has been kept around - /// for now to support the old deck config screen. + /// This is handled by update_deck_configs() now; this function has been + /// kept around for now to support the old deck config screen. pub fn sort_deck_legacy(&mut self, deck: DeckId, random: bool) -> Result> { self.transact(Op::SortCards, |col| { col.sort_deck( diff --git a/rslib/src/scheduler/queue/builder/burying.rs b/rslib/src/scheduler/queue/builder/burying.rs index 2a8169d47..88976c6ec 100644 --- a/rslib/src/scheduler/queue/builder/burying.rs +++ b/rslib/src/scheduler/queue/builder/burying.rs @@ -1,7 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{BuryMode, Context, DueCard, NewCard, QueueBuilder}; +use super::BuryMode; +use super::Context; +use super::DueCard; +use super::NewCard; +use super::QueueBuilder; use crate::prelude::*; pub(super) enum DueOrNewCard { @@ -54,8 +58,8 @@ impl Context { impl QueueBuilder { /// If burying is enabled in `new_settings`, existing entry will be updated. - /// Returns a copy made before changing the entry, so that a card with burying - /// enabled will bury future siblings, but not itself. + /// Returns a copy made before changing the entry, so that a card with + /// burying enabled will bury future siblings, but not itself. pub(super) fn get_and_update_bury_mode_for_note( &mut self, card: DueOrNewCard, diff --git a/rslib/src/scheduler/queue/builder/gathering.rs b/rslib/src/scheduler/queue/builder/gathering.rs index 6a26798a2..6eadefb77 100644 --- a/rslib/src/scheduler/queue/builder/gathering.rs +++ b/rslib/src/scheduler/queue/builder/gathering.rs @@ -1,11 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{DueCard, NewCard, QueueBuilder}; -use crate::{ - deckconfig::NewCardGatherPriority, prelude::*, scheduler::queue::DueCardKind, - storage::card::NewCardSorting, -}; +use super::DueCard; +use super::NewCard; +use super::QueueBuilder; +use crate::deckconfig::NewCardGatherPriority; +use crate::prelude::*; +use crate::scheduler::queue::DueCardKind; +use crate::storage::card::NewCardSorting; impl QueueBuilder { pub(super) fn gather_cards(&mut self, col: &mut Collection) -> Result<()> { diff --git a/rslib/src/scheduler/queue/builder/mod.rs b/rslib/src/scheduler/queue/builder/mod.rs index e63af1028..d546b6d89 100644 --- a/rslib/src/scheduler/queue/builder/mod.rs +++ b/rslib/src/scheduler/queue/builder/mod.rs @@ -7,18 +7,24 @@ pub(crate) mod intersperser; pub(crate) mod sized_chain; mod sorting; -use std::collections::{HashMap, VecDeque}; +use std::collections::HashMap; +use std::collections::VecDeque; use intersperser::Intersperser; use sized_chain::SizedChain; -use super::{CardQueues, Counts, LearningQueueEntry, MainQueueEntry, MainQueueEntryKind}; -use crate::{ - deckconfig::{NewCardGatherPriority, NewCardSortOrder, ReviewCardOrder, ReviewMix}, - decks::limits::LimitTreeMap, - prelude::*, - scheduler::timing::SchedTimingToday, -}; +use super::CardQueues; +use super::Counts; +use super::LearningQueueEntry; +use super::MainQueueEntry; +use super::MainQueueEntryKind; +use crate::deckconfig::NewCardGatherPriority; +use crate::deckconfig::NewCardSortOrder; +use crate::deckconfig::ReviewCardOrder; +use crate::deckconfig::ReviewMix; +use crate::decks::limits::LimitTreeMap; +use crate::prelude::*; +use crate::scheduler::timing::SchedTimingToday; /// Temporary holder for review cards that will be built into a queue. #[derive(Debug, Clone, Copy)] @@ -263,11 +269,11 @@ impl Collection { #[cfg(test)] mod test { use super::*; - use crate::{ - card::{CardQueue, CardType}, - collection::open_test_collection, - pb::deckconfig::deck_config::config::{NewCardGatherPriority, NewCardSortOrder}, - }; + use crate::card::CardQueue; + use crate::card::CardType; + use crate::collection::open_test_collection; + use crate::pb::deckconfig::deck_config::config::NewCardGatherPriority; + use crate::pb::deckconfig::deck_config::config::NewCardSortOrder; impl Collection { fn set_deck_gather_order(&mut self, deck: &mut Deck, order: NewCardGatherPriority) { diff --git a/rslib/src/scheduler/queue/builder/sorting.rs b/rslib/src/scheduler/queue/builder/sorting.rs index d5f4fd5a5..580f1400f 100644 --- a/rslib/src/scheduler/queue/builder/sorting.rs +++ b/rslib/src/scheduler/queue/builder/sorting.rs @@ -1,11 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{cmp::Ordering, hash::Hasher}; +use std::cmp::Ordering; +use std::hash::Hasher; use fnv::FnvHasher; -use super::{NewCard, NewCardSortOrder, QueueBuilder}; +use super::NewCard; +use super::NewCardSortOrder; +use super::QueueBuilder; impl QueueBuilder { pub(super) fn sort_new(&mut self) { diff --git a/rslib/src/scheduler/queue/entry.rs b/rslib/src/scheduler/queue/entry.rs index 7c4111b6e..c9e587747 100644 --- a/rslib/src/scheduler/queue/entry.rs +++ b/rslib/src/scheduler/queue/entry.rs @@ -1,8 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{LearningQueueEntry, MainQueueEntry, MainQueueEntryKind}; -use crate::{card::CardQueue, prelude::*}; +use super::LearningQueueEntry; +use super::MainQueueEntry; +use super::MainQueueEntryKind; +use crate::card::CardQueue; +use crate::prelude::*; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) enum QueueEntry { diff --git a/rslib/src/scheduler/queue/learning.rs b/rslib/src/scheduler/queue/learning.rs index 40f5584de..12c09d27e 100644 --- a/rslib/src/scheduler/queue/learning.rs +++ b/rslib/src/scheduler/queue/learning.rs @@ -1,8 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{undo::CutoffSnapshot, CardQueues}; -use crate::{prelude::*, scheduler::timing::SchedTimingToday}; +use super::undo::CutoffSnapshot; +use super::CardQueues; +use crate::prelude::*; +use crate::scheduler::timing::SchedTimingToday; #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)] pub(crate) struct LearningQueueEntry { @@ -52,8 +54,9 @@ impl CardQueues { change } - /// Given the just-answered `card`, place it back in the learning queues if it's still - /// due today. Avoid placing it in a position where it would be shown again immediately. + /// Given the just-answered `card`, place it back in the learning queues if + /// it's still due today. Avoid placing it in a position where it would + /// be shown again immediately. pub(super) fn maybe_requeue_learning_card( &mut self, card: &Card, @@ -144,8 +147,8 @@ impl CardQueues { self.intraday_learning.insert(target_idx, entry); } - /// Remove an inserted intraday learning card after a lapse is undone, adjusting - /// counts. + /// Remove an inserted intraday learning card after a lapse is undone, + /// adjusting counts. pub(super) fn remove_intraday_learning_card( &mut self, card_id: CardId, diff --git a/rslib/src/scheduler/queue/mod.rs b/rslib/src/scheduler/queue/mod.rs index bb50efdb2..e906082f8 100644 --- a/rslib/src/scheduler/queue/mod.rs +++ b/rslib/src/scheduler/queue/mod.rs @@ -9,14 +9,20 @@ pub(crate) mod undo; use std::collections::VecDeque; -pub(crate) use builder::{DueCard, DueCardKind, NewCard}; -pub(crate) use entry::{QueueEntry, QueueEntryKind}; +pub(crate) use builder::DueCard; +pub(crate) use builder::DueCardKind; +pub(crate) use builder::NewCard; +pub(crate) use entry::QueueEntry; +pub(crate) use entry::QueueEntryKind; pub(crate) use learning::LearningQueueEntry; -pub(crate) use main::{MainQueueEntry, MainQueueEntryKind}; +pub(crate) use main::MainQueueEntry; +pub(crate) use main::MainQueueEntryKind; use self::undo::QueueUpdate; -use super::{states::SchedulingStates, timing::SchedTimingToday}; -use crate::{prelude::*, timestamp::TimestampSecs}; +use super::states::SchedulingStates; +use super::timing::SchedTimingToday; +use crate::prelude::*; +use crate::timestamp::TimestampSecs; #[derive(Debug)] pub(crate) struct CardQueues { @@ -215,8 +221,8 @@ impl Collection { Ok(self.state.card_queues.as_mut().unwrap()) } - // Returns queues if they are valid and have not been rebuilt. If build time has changed, - // they are cleared. + // Returns queues if they are valid and have not been rebuilt. If build time has + // changed, they are cleared. pub(crate) fn get_or_invalidate_queues( &mut self, build_time: TimestampMillis, diff --git a/rslib/src/scheduler/queue/undo.rs b/rslib/src/scheduler/queue/undo.rs index 748a29110..2583a6e4e 100644 --- a/rslib/src/scheduler/queue/undo.rs +++ b/rslib/src/scheduler/queue/undo.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{LearningQueueEntry, QueueEntry}; +use super::LearningQueueEntry; +use super::QueueEntry; use crate::prelude::*; #[derive(Debug)] @@ -63,12 +64,11 @@ impl Collection { #[cfg(test)] mod test { - use crate::{ - card::{CardQueue, CardType}, - collection::open_test_collection, - deckconfig::LeechAction, - prelude::*, - }; + use crate::card::CardQueue; + use crate::card::CardType; + use crate::collection::open_test_collection; + use crate::deckconfig::LeechAction; + use crate::prelude::*; fn add_note(col: &mut Collection, with_reverse: bool) -> Result { let nt = col diff --git a/rslib/src/scheduler/reviews.rs b/rslib/src/scheduler/reviews.rs index dfc62c672..4e6d1b5a1 100644 --- a/rslib/src/scheduler/reviews.rs +++ b/rslib/src/scheduler/reviews.rs @@ -4,16 +4,18 @@ use std::collections::HashMap; use lazy_static::lazy_static; -use rand::distributions::{Distribution, Uniform}; +use rand::distributions::Distribution; +use rand::distributions::Uniform; use regex::Regex; -use crate::{ - card::{Card, CardId, CardQueue, CardType}, - collection::Collection, - config::StringKey, - error::Result, - prelude::*, -}; +use crate::card::Card; +use crate::card::CardId; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::collection::Collection; +use crate::config::StringKey; +use crate::error::Result; +use crate::prelude::*; impl Card { /// Make card due in `days_from_today`. diff --git a/rslib/src/scheduler/states/filtered.rs b/rslib/src/scheduler/states/filtered.rs index 18b07eeba..1fba3da97 100644 --- a/rslib/src/scheduler/states/filtered.rs +++ b/rslib/src/scheduler/states/filtered.rs @@ -1,10 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{ - IntervalKind, PreviewState, ReschedulingFilterState, ReviewState, SchedulingStates, - StateContext, -}; +use super::IntervalKind; +use super::PreviewState; +use super::ReschedulingFilterState; +use super::ReviewState; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/rslib/src/scheduler/states/learning.rs b/rslib/src/scheduler/states/learning.rs index 02988b25a..19e246ae9 100644 --- a/rslib/src/scheduler/states/learning.rs +++ b/rslib/src/scheduler/states/learning.rs @@ -1,7 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{interval_kind::IntervalKind, CardState, ReviewState, SchedulingStates, StateContext}; +use super::interval_kind::IntervalKind; +use super::CardState; +use super::ReviewState; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/rslib/src/scheduler/states/mod.rs b/rslib/src/scheduler/states/mod.rs index 75a95bd33..48343bf80 100644 --- a/rslib/src/scheduler/states/mod.rs +++ b/rslib/src/scheduler/states/mod.rs @@ -80,7 +80,8 @@ impl CardState { /// Info required during state transitions. pub(crate) struct StateContext<'a> { - /// In range `0.0..1.0`. Used to pick the final interval from the fuzz range. + /// In range `0.0..1.0`. Used to pick the final interval from the fuzz + /// range. pub fuzz_factor: Option, // learning diff --git a/rslib/src/scheduler/states/new.rs b/rslib/src/scheduler/states/new.rs index cfb69c6ca..2ac8a480e 100644 --- a/rslib/src/scheduler/states/new.rs +++ b/rslib/src/scheduler/states/new.rs @@ -11,8 +11,9 @@ pub struct NewState { impl NewState { pub(crate) fn interval_kind(self) -> IntervalKind { - // todo: consider packing the due number in here; it would allow us to restore the - // original position of cards - though not as cheaply as if it were a card property. + // todo: consider packing the due number in here; it would allow us to restore + // the original position of cards - though not as cheaply as if it were + // a card property. IntervalKind::InSecs(0) } diff --git a/rslib/src/scheduler/states/normal.rs b/rslib/src/scheduler/states/normal.rs index 3b9f776a2..64fac68c1 100644 --- a/rslib/src/scheduler/states/normal.rs +++ b/rslib/src/scheduler/states/normal.rs @@ -1,10 +1,13 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{ - interval_kind::IntervalKind, LearnState, NewState, RelearnState, ReviewState, SchedulingStates, - StateContext, -}; +use super::interval_kind::IntervalKind; +use super::LearnState; +use super::NewState; +use super::RelearnState; +use super::ReviewState; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/rslib/src/scheduler/states/preview_filter.rs b/rslib/src/scheduler/states/preview_filter.rs index c60ac8957..ba904b61b 100644 --- a/rslib/src/scheduler/states/preview_filter.rs +++ b/rslib/src/scheduler/states/preview_filter.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{IntervalKind, SchedulingStates, StateContext}; +use super::IntervalKind; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/rslib/src/scheduler/states/relearning.rs b/rslib/src/scheduler/states/relearning.rs index d42e643e1..71a88e385 100644 --- a/rslib/src/scheduler/states/relearning.rs +++ b/rslib/src/scheduler/states/relearning.rs @@ -1,9 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{ - interval_kind::IntervalKind, CardState, LearnState, ReviewState, SchedulingStates, StateContext, -}; +use super::interval_kind::IntervalKind; +use super::CardState; +use super::LearnState; +use super::ReviewState; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/rslib/src/scheduler/states/rescheduling_filter.rs b/rslib/src/scheduler/states/rescheduling_filter.rs index 0520d01bd..6e9794f99 100644 --- a/rslib/src/scheduler/states/rescheduling_filter.rs +++ b/rslib/src/scheduler/states/rescheduling_filter.rs @@ -1,9 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{ - interval_kind::IntervalKind, normal::NormalState, CardState, SchedulingStates, StateContext, -}; +use super::interval_kind::IntervalKind; +use super::normal::NormalState; +use super::CardState; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/rslib/src/scheduler/states/review.rs b/rslib/src/scheduler/states/review.rs index 5bcd41c4e..120342cee 100644 --- a/rslib/src/scheduler/states/review.rs +++ b/rslib/src/scheduler/states/review.rs @@ -1,10 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{ - interval_kind::IntervalKind, CardState, LearnState, RelearnState, SchedulingStates, - StateContext, -}; +use super::interval_kind::IntervalKind; +use super::CardState; +use super::LearnState; +use super::RelearnState; +use super::SchedulingStates; +use super::StateContext; use crate::revlog::RevlogReviewKind; pub const INITIAL_EASE_FACTOR: f32 = 2.5; @@ -122,7 +124,8 @@ impl ReviewState { } } - /// Return the intervals for hard, good and easy, each of which depends on the previous. + /// Return the intervals for hard, good and easy, each of which depends on + /// the previous. fn passing_review_intervals(self, ctx: &StateContext) -> (u32, u32, u32) { if self.days_late() < 0 { self.passing_early_review_intervals(ctx) @@ -159,10 +162,10 @@ impl ReviewState { (hard_interval, good_interval, easy_interval) } - /// Mostly direct port from the Python version for now, so we can confirm implementation - /// is correct. - /// FIXME: this needs reworking in the future; it overly penalizes reviews done - /// shortly before the due date. + /// Mostly direct port from the Python version for now, so we can confirm + /// implementation is correct. + /// FIXME: this needs reworking in the future; it overly penalizes reviews + /// done shortly before the due date. fn passing_early_review_intervals(self, ctx: &StateContext) -> (u32, u32, u32) { let scheduled = self.scheduled_days as f32; let elapsed = (self.scheduled_days as f32) + (self.days_late() as f32); @@ -258,7 +261,8 @@ mod test { #[test] fn extreme_multiplier_fuzz() { let mut ctx = StateContext::defaults_for_testing(); - // our calculations should work correctly with a low ease or non-default multiplier + // our calculations should work correctly with a low ease or non-default + // multiplier let state = ReviewState { scheduled_days: 1, elapsed_days: 1, diff --git a/rslib/src/scheduler/states/steps.rs b/rslib/src/scheduler/states/steps.rs index 77ce872ce..61b669bac 100644 --- a/rslib/src/scheduler/states/steps.rs +++ b/rslib/src/scheduler/states/steps.rs @@ -55,8 +55,9 @@ impl<'a> LearningSteps<'a> { }) } - /// Special case the hard interval for the first step to avoid equality with the again interval. - /// Also ensure it's smaller than the good interval, at least with reasonable settings. + /// Special case the hard interval for the first step to avoid equality with + /// the again interval. Also ensure it's smaller than the good interval, + /// at least with reasonable settings. fn hard_delay_secs_for_first_step(self, again_secs: u32) -> u32 { if let Some(next) = self.secs_at_index(1) { // average of first (again) and second (good) steps @@ -90,9 +91,9 @@ impl<'a> LearningSteps<'a> { } } -/// If the given interval in seconds surpasses 1 day, rounds it to a whole number of days. -/// Ensures that the user gets the same results earlier and later in the day. -/// Returns seconds. +/// If the given interval in seconds surpasses 1 day, rounds it to a whole +/// number of days. Ensures that the user gets the same results earlier and +/// later in the day. Returns seconds. fn maybe_round_in_days(secs: u32) -> u32 { if secs > DAY { ((secs as f32 / DAY as f32).round() as u32).saturating_mul(DAY) diff --git a/rslib/src/scheduler/timespan.rs b/rslib/src/scheduler/timespan.rs index 26bc64d6d..3e9ba2144 100644 --- a/rslib/src/scheduler/timespan.rs +++ b/rslib/src/scheduler/timespan.rs @@ -166,10 +166,10 @@ impl Timespan { #[cfg(test)] mod test { - use crate::{ - i18n::I18n, - scheduler::timespan::{answer_button_time, time_span, MONTH}, - }; + use crate::i18n::I18n; + use crate::scheduler::timespan::answer_button_time; + use crate::scheduler::timespan::time_span; + use crate::scheduler::timespan::MONTH; #[test] fn answer_buttons() { diff --git a/rslib/src/scheduler/timing.rs b/rslib/src/scheduler/timing.rs index eeb52da6b..a57f3746f 100644 --- a/rslib/src/scheduler/timing.rs +++ b/rslib/src/scheduler/timing.rs @@ -1,7 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use chrono::{DateTime, Datelike, Duration, FixedOffset, Timelike}; +use chrono::DateTime; +use chrono::Datelike; +use chrono::Duration; +use chrono::FixedOffset; +use chrono::Timelike; use crate::prelude::*; @@ -196,7 +200,9 @@ pub(crate) fn sched_timing_today( #[cfg(test)] mod test { - use chrono::{FixedOffset, Local, TimeZone}; + use chrono::FixedOffset; + use chrono::Local; + use chrono::TimeZone; use super::*; @@ -284,11 +290,12 @@ mod test { .unwrap() .timestamp(); assert_eq!(elap(crt, now, mdt_offset, mst_offset, 4), 507); - // the previous implementation generated a different elapsed number of days with a change - // to DST, but the number shouldn't change + // the previous implementation generated a different elapsed number of days with + // a change to DST, but the number shouldn't change assert_eq!(elap(crt, now, mdt_offset, mdt_offset, 4), 507); - // collection created at 3am on the 6th, so day 1 starts at 4am on the 7th, and day 3 on the 9th. + // collection created at 3am on the 6th, so day 1 starts at 4am on the 7th, and + // day 3 on the 9th. let crt = mdt .with_ymd_and_hms(2018, 8, 6, 3, 0, 0) .latest() diff --git a/rslib/src/scheduler/upgrade.rs b/rslib/src/scheduler/upgrade.rs index f9a42918f..ca5be6465 100644 --- a/rslib/src/scheduler/upgrade.rs +++ b/rslib/src/scheduler/upgrade.rs @@ -4,12 +4,11 @@ use std::collections::HashMap; use super::timing::local_minutes_west_for_stamp; -use crate::{ - card::{CardQueue, CardType}, - config::SchedulerVersion, - prelude::*, - search::SortMode, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::config::SchedulerVersion; +use crate::prelude::*; +use crate::search::SortMode; struct V1FilteredDeckInfo { /// True if the filtered deck had rescheduling enabled. diff --git a/rslib/src/search/builder.rs b/rslib/src/search/builder.rs index e17ccfe3f..198bf4b29 100644 --- a/rslib/src/search/builder.rs +++ b/rslib/src/search/builder.rs @@ -5,17 +5,24 @@ use std::mem; use itertools::Itertools; -use super::{writer::write_nodes, Node, SearchNode, StateKind, TemplateKind}; -use crate::{prelude::*, text::escape_anki_wildcards_for_search_node}; +use super::writer::write_nodes; +use super::Node; +use super::SearchNode; +use super::StateKind; +use super::TemplateKind; +use crate::prelude::*; +use crate::text::escape_anki_wildcards_for_search_node; pub trait Negated { fn negated(self) -> Node; } pub trait JoinSearches { - /// Concatenates two sets of [Node]s, inserting [Node::And], and grouping, if appropriate. + /// Concatenates two sets of [Node]s, inserting [Node::And], and grouping, + /// if appropriate. fn and(self, other: impl Into) -> SearchBuilder; - /// Concatenates two sets of [Node]s, inserting [Node::Or], and grouping, if appropriate. + /// Concatenates two sets of [Node]s, inserting [Node::Or], and grouping, if + /// appropriate. fn or(self, other: impl Into) -> SearchBuilder; /// Concatenates two sets of [Node]s, inserting [Node::And] if appropriate, /// but without grouping either set. diff --git a/rslib/src/search/mod.rs b/rslib/src/search/mod.rs index 4588f5f3c..3217c6363 100644 --- a/rslib/src/search/mod.rs +++ b/rslib/src/search/mod.rs @@ -8,15 +8,25 @@ pub(crate) mod writer; use std::borrow::Cow; -pub use builder::{JoinSearches, Negated, SearchBuilder}; -pub use parser::{ - parse as parse_search, Node, PropertyKind, RatingKind, SearchNode, StateKind, TemplateKind, -}; -use rusqlite::{params_from_iter, types::FromSql}; -use sqlwriter::{RequiredTable, SqlWriter}; +pub use builder::JoinSearches; +pub use builder::Negated; +pub use builder::SearchBuilder; +pub use parser::parse as parse_search; +pub use parser::Node; +pub use parser::PropertyKind; +pub use parser::RatingKind; +pub use parser::SearchNode; +pub use parser::StateKind; +pub use parser::TemplateKind; +use rusqlite::params_from_iter; +use rusqlite::types::FromSql; +use sqlwriter::RequiredTable; +use sqlwriter::SqlWriter; pub use writer::replace_search_node; -use crate::{browser_table::Column, card::CardType, prelude::*}; +use crate::browser_table::Column; +use crate::card::CardType; +use crate::prelude::*; #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum ReturnItemType { diff --git a/rslib/src/search/parser.rs b/rslib/src/search/parser.rs index 861a56aa1..b40a01b46 100644 --- a/rslib/src/search/parser.rs +++ b/rslib/src/search/parser.rs @@ -2,21 +2,27 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use lazy_static::lazy_static; -use nom::{ - branch::alt, - bytes::complete::{escaped, is_not, tag}, - character::complete::{anychar, char, none_of, one_of}, - combinator::{map, verify}, - error::ErrorKind as NomErrorKind, - multi::many0, - sequence::{preceded, separated_pair}, -}; -use regex::{Captures, Regex}; +use nom::branch::alt; +use nom::bytes::complete::escaped; +use nom::bytes::complete::is_not; +use nom::bytes::complete::tag; +use nom::character::complete::anychar; +use nom::character::complete::char; +use nom::character::complete::none_of; +use nom::character::complete::one_of; +use nom::combinator::map; +use nom::combinator::verify; +use nom::error::ErrorKind as NomErrorKind; +use nom::multi::many0; +use nom::sequence::preceded; +use nom::sequence::separated_pair; +use regex::Captures; +use regex::Regex; -use crate::{ - error::{ParseError, Result, SearchErrorKind as FailKind}, - prelude::*, -}; +use crate::error::ParseError; +use crate::error::Result; +use crate::error::SearchErrorKind as FailKind; +use crate::prelude::*; type IResult<'a, O> = std::result::Result<(&'a str, O), nom::Err>>; type ParseResult<'a, O> = std::result::Result>>; @@ -589,8 +595,8 @@ fn parse_mid(s: &str) -> ParseResult { parse_i64(s, "mid:").map(|n| SearchNode::NotetypeId(n.into())) } -/// ensure a list of ids contains only numbers and commas, returning unchanged if true -/// used by nid: and cid: +/// ensure a list of ids contains only numbers and commas, returning unchanged +/// if true used by nid: and cid: fn check_id_list<'a, 'b>(s: &'a str, context: &'b str) -> ParseResult<'a, &'a str> { lazy_static! { static ref RE: Regex = Regex::new(r"^(\d+,)*\d+$").unwrap(); diff --git a/rslib/src/search/sqlwriter.rs b/rslib/src/search/sqlwriter.rs index afd86f915..2b6014277 100644 --- a/rslib/src/search/sqlwriter.rs +++ b/rslib/src/search/sqlwriter.rs @@ -1,28 +1,36 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, fmt::Write}; +use std::borrow::Cow; +use std::fmt::Write; use itertools::Itertools; -use super::{ - parser::{Node, PropertyKind, RatingKind, SearchNode, StateKind, TemplateKind}, - ReturnItemType, -}; -use crate::{ - card::{CardQueue, CardType}, - collection::Collection, - error::Result, - notes::field_checksum, - notetype::NotetypeId, - prelude::*, - storage::ids_to_string, - text::{ - glob_matcher, is_glob, normalize_to_nfc, strip_html_preserving_media_filenames, - to_custom_re, to_re, to_sql, to_text, without_combining, - }, - timestamp::TimestampSecs, -}; +use super::parser::Node; +use super::parser::PropertyKind; +use super::parser::RatingKind; +use super::parser::SearchNode; +use super::parser::StateKind; +use super::parser::TemplateKind; +use super::ReturnItemType; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::collection::Collection; +use crate::error::Result; +use crate::notes::field_checksum; +use crate::notetype::NotetypeId; +use crate::prelude::*; +use crate::storage::ids_to_string; +use crate::text::glob_matcher; +use crate::text::is_glob; +use crate::text::normalize_to_nfc; +use crate::text::strip_html_preserving_media_filenames; +use crate::text::to_custom_re; +use crate::text::to_re; +use crate::text::to_sql; +use crate::text::to_text; +use crate::text::without_combining; +use crate::timestamp::TimestampSecs; pub(crate) struct SqlWriter<'a> { col: &'a mut Collection, @@ -113,9 +121,9 @@ impl SqlWriter<'_> { } } - // NOTE: when adding any new nodes in the future, make sure that they are either a single - // search term, or they wrap multiple terms in parentheses, as can be seen in the sql() unit - // test at the bottom of the file. + // NOTE: when adding any new nodes in the future, make sure that they are either + // a single search term, or they wrap multiple terms in parentheses, as can + // be seen in the sql() unit test at the bottom of the file. fn write_search_node_to_sql(&mut self, node: &SearchNode) -> Result<()> { use normalize_to_nfc as norm; match node { @@ -689,11 +697,11 @@ impl SearchNode { mod test { use tempfile::tempdir; - use super::{super::parser::parse, *}; - use crate::{ - collection::{Collection, CollectionBuilder}, - io::write_file, - }; + use super::super::parser::parse; + use super::*; + use crate::collection::Collection; + use crate::collection::CollectionBuilder; + use crate::io::write_file; // shortcut fn s(req: &mut Collection, search: &str) -> (String, Vec) { diff --git a/rslib/src/search/writer.rs b/rslib/src/search/writer.rs index e87d84ce4..520ebd288 100644 --- a/rslib/src/search/writer.rs +++ b/rslib/src/search/writer.rs @@ -6,17 +6,22 @@ use std::mem; use lazy_static::lazy_static; use regex::Regex; -use crate::{ - decks::DeckId as DeckIdType, - notetype::NotetypeId as NotetypeIdType, - prelude::*, - search::parser::{parse, Node, PropertyKind, RatingKind, SearchNode, StateKind, TemplateKind}, - text::escape_anki_wildcards, -}; +use crate::decks::DeckId as DeckIdType; +use crate::notetype::NotetypeId as NotetypeIdType; +use crate::prelude::*; +use crate::search::parser::parse; +use crate::search::parser::Node; +use crate::search::parser::PropertyKind; +use crate::search::parser::RatingKind; +use crate::search::parser::SearchNode; +use crate::search::parser::StateKind; +use crate::search::parser::TemplateKind; +use crate::text::escape_anki_wildcards; -/// Given an existing parsed search, if the provided `replacement` is a single search node such -/// as a deck:xxx search, replace any instances of that search in `existing` with the new value. -/// Then return the possibly modified first search as a string. +/// Given an existing parsed search, if the provided `replacement` is a single +/// search node such as a deck:xxx search, replace any instances of that search +/// in `existing` with the new value. Then return the possibly modified first +/// search as a string. pub fn replace_search_node(mut existing: Vec, replacement: Node) -> String { if let Node::Search(search_node) = replacement { fn update_node_vec(old_nodes: &mut [Node], new_node: &SearchNode) { @@ -182,7 +187,8 @@ pub(crate) fn normalize_search(input: &str) -> Result { #[cfg(test)] mod test { use super::*; - use crate::{error::Result, search::parse_search as parse}; + use crate::error::Result; + use crate::search::parse_search as parse; #[test] fn normalizing() { diff --git a/rslib/src/serde.rs b/rslib/src/serde.rs index 853f20591..a6ff3b260 100644 --- a/rslib/src/serde.rs +++ b/rslib/src/serde.rs @@ -1,16 +1,16 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde::{Deserialize as DeTrait, Deserializer}; -pub(crate) use serde_aux::field_attributes::{ - deserialize_bool_from_anything, deserialize_number_from_string, -}; +use serde::Deserialize as DeTrait; +use serde::Deserializer; +pub(crate) use serde_aux::field_attributes::deserialize_bool_from_anything; +pub(crate) use serde_aux::field_attributes::deserialize_number_from_string; use serde_json::Value; use crate::timestamp::TimestampSecs; -/// Note: if you wish to cover the case where a field is missing, make sure you also -/// use the `serde(default)` flag. +/// Note: if you wish to cover the case where a field is missing, make sure you +/// also use the `serde(default)` flag. pub(crate) fn default_on_invalid<'de, T, D>(deserializer: D) -> Result where T: Default + DeTrait<'de>, diff --git a/rslib/src/stats/card.rs b/rslib/src/stats/card.rs index f9ba3bdb0..80f8dd81f 100644 --- a/rslib/src/stats/card.rs +++ b/rslib/src/stats/card.rs @@ -1,12 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - card::{CardQueue, CardType}, - pb, - prelude::*, - revlog::RevlogEntry, -}; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::pb; +use crate::prelude::*; +use crate::revlog::RevlogEntry; impl Collection { pub fn card_stats(&mut self, cid: CardId) -> Result { @@ -106,7 +105,8 @@ fn stats_revlog_entry(entry: &RevlogEntry) -> pb::stats::card_stats_response::St #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, search::SortMode}; + use crate::collection::open_test_collection; + use crate::search::SortMode; #[test] fn stats() -> Result<()> { diff --git a/rslib/src/stats/graphs/added.rs b/rslib/src/stats/graphs/added.rs index 0c50effda..95be760cf 100644 --- a/rslib/src/stats/graphs/added.rs +++ b/rslib/src/stats/graphs/added.rs @@ -8,7 +8,8 @@ impl GraphsContext { pub(super) fn added_days(&self) -> Added { let mut data = Added::default(); for card in &self.cards { - // this could perhaps be simplified; it currently tries to match the old TS code logic + // this could perhaps be simplified; it currently tries to match the old TS code + // logic let day = ((card.id.as_secs().elapsed_secs_since(self.next_day_start) as f64) / 86_400.0) .ceil() as i32; diff --git a/rslib/src/stats/graphs/buttons.rs b/rslib/src/stats/graphs/buttons.rs index 3bd45a900..c872f19ef 100644 --- a/rslib/src/stats/graphs/buttons.rs +++ b/rslib/src/stats/graphs/buttons.rs @@ -2,10 +2,10 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::GraphsContext; -use crate::{ - pb::stats::graphs_response::{buttons::ButtonCounts, Buttons}, - revlog::{RevlogEntry, RevlogReviewKind}, -}; +use crate::pb::stats::graphs_response::buttons::ButtonCounts; +use crate::pb::stats::graphs_response::Buttons; +use crate::revlog::RevlogEntry; +use crate::revlog::RevlogReviewKind; impl GraphsContext { pub(super) fn buttons(&self) -> Buttons { diff --git a/rslib/src/stats/graphs/card_counts.rs b/rslib/src/stats/graphs/card_counts.rs index 13e61700f..84f5c931a 100644 --- a/rslib/src/stats/graphs/card_counts.rs +++ b/rslib/src/stats/graphs/card_counts.rs @@ -1,11 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - card::{Card, CardQueue, CardType}, - pb::stats::graphs_response::{card_counts::Counts, CardCounts}, - stats::graphs::GraphsContext, -}; +use crate::card::Card; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::pb::stats::graphs_response::card_counts::Counts; +use crate::pb::stats::graphs_response::CardCounts; +use crate::stats::graphs::GraphsContext; impl GraphsContext { pub(super) fn card_counts(&self) -> CardCounts { diff --git a/rslib/src/stats/graphs/eases.rs b/rslib/src/stats/graphs/eases.rs index 2fff9f595..22453fe98 100644 --- a/rslib/src/stats/graphs/eases.rs +++ b/rslib/src/stats/graphs/eases.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{card::CardType, pb::stats::graphs_response::Eases, stats::graphs::GraphsContext}; +use crate::card::CardType; +use crate::pb::stats::graphs_response::Eases; +use crate::stats::graphs::GraphsContext; impl GraphsContext { pub(super) fn eases(&self) -> Eases { diff --git a/rslib/src/stats/graphs/future_due.rs b/rslib/src/stats/graphs/future_due.rs index 383f726d7..58b446178 100644 --- a/rslib/src/stats/graphs/future_due.rs +++ b/rslib/src/stats/graphs/future_due.rs @@ -14,8 +14,8 @@ impl GraphsContext { if c.queue as i8 <= 0 { continue; } - // The extra original_due check covers lapsed cards, which have their due date updated on - // graduation. + // The extra original_due check covers lapsed cards, which have their due date + // updated on graduation. let due = if c.is_filtered() && c.original_due != 0 { c.original_due } else { diff --git a/rslib/src/stats/graphs/hours.rs b/rslib/src/stats/graphs/hours.rs index fae6b8514..8b1c46af7 100644 --- a/rslib/src/stats/graphs/hours.rs +++ b/rslib/src/stats/graphs/hours.rs @@ -1,11 +1,10 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - pb::stats::graphs_response::{hours::Hour, Hours}, - revlog::RevlogReviewKind, - stats::graphs::GraphsContext, -}; +use crate::pb::stats::graphs_response::hours::Hour; +use crate::pb::stats::graphs_response::Hours; +use crate::revlog::RevlogReviewKind; +use crate::stats::graphs::GraphsContext; impl GraphsContext { pub(super) fn hours(&self) -> Hours { diff --git a/rslib/src/stats/graphs/intervals.rs b/rslib/src/stats/graphs/intervals.rs index 556b81e8f..4534044bb 100644 --- a/rslib/src/stats/graphs/intervals.rs +++ b/rslib/src/stats/graphs/intervals.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{card::CardType, pb::stats::graphs_response::Intervals, stats::graphs::GraphsContext}; +use crate::card::CardType; +use crate::pb::stats::graphs_response::Intervals; +use crate::stats::graphs::GraphsContext; impl GraphsContext { pub(super) fn intervals(&self) -> Intervals { diff --git a/rslib/src/stats/graphs/mod.rs b/rslib/src/stats/graphs/mod.rs index 43a82f328..38d482437 100644 --- a/rslib/src/stats/graphs/mod.rs +++ b/rslib/src/stats/graphs/mod.rs @@ -11,13 +11,12 @@ mod intervals; mod reviews; mod today; -use crate::{ - config::{BoolKey, Weekday}, - pb, - prelude::*, - revlog::RevlogEntry, - search::SortMode, -}; +use crate::config::BoolKey; +use crate::config::Weekday; +use crate::pb; +use crate::prelude::*; +use crate::revlog::RevlogEntry; +use crate::search::SortMode; struct GraphsContext { revlog: Vec, diff --git a/rslib/src/stats/graphs/reviews.rs b/rslib/src/stats/graphs/reviews.rs index c28eb56bd..808b101e2 100644 --- a/rslib/src/stats/graphs/reviews.rs +++ b/rslib/src/stats/graphs/reviews.rs @@ -2,7 +2,8 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::GraphsContext; -use crate::{pb::stats::graphs_response::ReviewCountsAndTimes, revlog::RevlogReviewKind}; +use crate::pb::stats::graphs_response::ReviewCountsAndTimes; +use crate::revlog::RevlogReviewKind; impl GraphsContext { pub(super) fn review_counts_and_times(&self) -> ReviewCountsAndTimes { diff --git a/rslib/src/stats/graphs/today.rs b/rslib/src/stats/graphs/today.rs index 0b3ba3542..d4c9e96e2 100644 --- a/rslib/src/stats/graphs/today.rs +++ b/rslib/src/stats/graphs/today.rs @@ -1,9 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - pb::stats::graphs_response::Today, revlog::RevlogReviewKind, stats::graphs::GraphsContext, -}; +use crate::pb::stats::graphs_response::Today; +use crate::revlog::RevlogReviewKind; +use crate::stats::graphs::GraphsContext; impl GraphsContext { pub(super) fn today(&self) -> Today { diff --git a/rslib/src/stats/today.rs b/rslib/src/stats/today.rs index e705a4191..d7f82fbf2 100644 --- a/rslib/src/stats/today.rs +++ b/rslib/src/stats/today.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{i18n::I18n, prelude::*, scheduler::timespan::Timespan}; +use crate::i18n::I18n; +use crate::prelude::*; +use crate::scheduler::timespan::Timespan; pub fn studied_today(cards: u32, secs: f32, tr: &I18n) -> String { let span = Timespan::from_secs(secs).natural_span(); diff --git a/rslib/src/storage/card/data.rs b/rslib/src/storage/card/data.rs index a97883e98..d917c5c07 100644 --- a/rslib/src/storage/card/data.rs +++ b/rslib/src/storage/card/data.rs @@ -3,14 +3,17 @@ use std::collections::HashMap; -use rusqlite::{ - types::{FromSql, FromSqlError, ToSqlOutput, ValueRef}, - ToSql, -}; -use serde_derive::{Deserialize, Serialize}; +use rusqlite::types::FromSql; +use rusqlite::types::FromSqlError; +use rusqlite::types::ToSqlOutput; +use rusqlite::types::ValueRef; +use rusqlite::ToSql; +use serde_derive::Deserialize; +use serde_derive::Serialize; use serde_json::Value; -use crate::{prelude::*, serde::default_on_invalid}; +use crate::prelude::*; +use crate::serde::default_on_invalid; /// Helper for serdeing the card data column. #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] diff --git a/rslib/src/storage/card/filtered.rs b/rslib/src/storage/card/filtered.rs index 243c462d3..d27a5cac6 100644 --- a/rslib/src/storage/card/filtered.rs +++ b/rslib/src/storage/card/filtered.rs @@ -1,10 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - card::CardQueue, - decks::{FilteredSearchOrder, FilteredSearchTerm}, -}; +use crate::card::CardQueue; +use crate::decks::FilteredSearchOrder; +use crate::decks::FilteredSearchTerm; pub(crate) fn order_and_limit_for_search(term: &FilteredSearchTerm, today: u32) -> String { let temp_string; diff --git a/rslib/src/storage/card/mod.rs b/rslib/src/storage/card/mod.rs index 163c51d5d..dded5db6e 100644 --- a/rslib/src/storage/card/mod.rs +++ b/rslib/src/storage/card/mod.rs @@ -4,29 +4,39 @@ pub(crate) mod data; pub(crate) mod filtered; -use std::{collections::HashSet, convert::TryFrom, fmt, result}; +use std::collections::HashSet; +use std::convert::TryFrom; +use std::fmt; +use std::result; -use rusqlite::{ - named_params, params, - types::{FromSql, FromSqlError, ValueRef}, - OptionalExtension, Row, -}; +use rusqlite::named_params; +use rusqlite::params; +use rusqlite::types::FromSql; +use rusqlite::types::FromSqlError; +use rusqlite::types::ValueRef; +use rusqlite::OptionalExtension; +use rusqlite::Row; use self::data::CardData; use super::ids_to_string; -use crate::{ - card::{Card, CardId, CardQueue, CardType}, - deckconfig::{DeckConfigId, ReviewCardOrder}, - decks::{Deck, DeckId, DeckKind}, - error::Result, - notes::NoteId, - scheduler::{ - congrats::CongratsInfo, - queue::{DueCard, DueCardKind, NewCard}, - }, - timestamp::{TimestampMillis, TimestampSecs}, - types::Usn, -}; +use crate::card::Card; +use crate::card::CardId; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::deckconfig::DeckConfigId; +use crate::deckconfig::ReviewCardOrder; +use crate::decks::Deck; +use crate::decks::DeckId; +use crate::decks::DeckKind; +use crate::error::Result; +use crate::notes::NoteId; +use crate::scheduler::congrats::CongratsInfo; +use crate::scheduler::queue::DueCard; +use crate::scheduler::queue::DueCardKind; +use crate::scheduler::queue::NewCard; +use crate::timestamp::TimestampMillis; +use crate::timestamp::TimestampSecs; +use crate::types::Usn; impl FromSql for CardType { fn column_result(value: ValueRef<'_>) -> result::Result { @@ -757,7 +767,9 @@ impl NewCardSorting { mod test { use std::path::Path; - use crate::{card::Card, i18n::I18n, storage::SqliteStorage}; + use crate::card::Card; + use crate::i18n::I18n; + use crate::storage::SqliteStorage; #[test] fn add_card() { diff --git a/rslib/src/storage/collection_timestamps.rs b/rslib/src/storage/collection_timestamps.rs index ce1818527..09b64cf5d 100644 --- a/rslib/src/storage/collection_timestamps.rs +++ b/rslib/src/storage/collection_timestamps.rs @@ -4,7 +4,8 @@ use rusqlite::params; use super::SqliteStorage; -use crate::{collection::timestamps::CollectionTimestamps, prelude::*}; +use crate::collection::timestamps::CollectionTimestamps; +use crate::prelude::*; impl SqliteStorage { pub(crate) fn get_collection_timestamps(&self) -> Result { diff --git a/rslib/src/storage/config/mod.rs b/rslib/src/storage/config/mod.rs index b8884eb83..c20b5c34a 100644 --- a/rslib/src/storage/config/mod.rs +++ b/rslib/src/storage/config/mod.rs @@ -8,7 +8,10 @@ use serde::de::DeserializeOwned; use serde_json::Value; use super::SqliteStorage; -use crate::{config::ConfigEntry, error::Result, timestamp::TimestampSecs, types::Usn}; +use crate::config::ConfigEntry; +use crate::error::Result; +use crate::timestamp::TimestampSecs; +use crate::types::Usn; impl SqliteStorage { pub(crate) fn set_config_entry(&self, entry: &ConfigEntry) -> Result<()> { diff --git a/rslib/src/storage/deck/mod.rs b/rslib/src/storage/deck/mod.rs index bdbfbfc80..121d32014 100644 --- a/rslib/src/storage/deck/mod.rs +++ b/rslib/src/storage/deck/mod.rs @@ -1,23 +1,26 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::{HashMap, HashSet}, - iter, -}; +use std::collections::HashMap; +use std::collections::HashSet; +use std::iter; use prost::Message; -use rusqlite::{named_params, params, Row}; +use rusqlite::named_params; +use rusqlite::params; +use rusqlite::Row; use unicase::UniCase; use super::SqliteStorage; -use crate::{ - card::CardQueue, - config::SchedulerVersion, - decks::{immediate_parent_name, DeckCommon, DeckKindContainer, DeckSchema11, DueCounts}, - error::DbErrorKind, - prelude::*, -}; +use crate::card::CardQueue; +use crate::config::SchedulerVersion; +use crate::decks::immediate_parent_name; +use crate::decks::DeckCommon; +use crate::decks::DeckKindContainer; +use crate::decks::DeckSchema11; +use crate::decks::DueCounts; +use crate::error::DbErrorKind; +use crate::prelude::*; fn row_to_deck(row: &Row) -> Result { let common = DeckCommon::decode(row.get_ref_unwrap(4).as_blob()?)?; @@ -269,7 +272,8 @@ impl SqliteStorage { .collect() } - /// Return the parents of `child`, with the most immediate parent coming first. + /// Return the parents of `child`, with the most immediate parent coming + /// first. pub(crate) fn parent_decks(&self, child: &Deck) -> Result> { let mut decks: Vec = vec![]; while let Some(parent_name) = immediate_parent_name( diff --git a/rslib/src/storage/deckconfig/mod.rs b/rslib/src/storage/deckconfig/mod.rs index 82fae17dd..5d086d491 100644 --- a/rslib/src/storage/deckconfig/mod.rs +++ b/rslib/src/storage/deckconfig/mod.rs @@ -4,14 +4,16 @@ use std::collections::HashMap; use prost::Message; -use rusqlite::{params, Row}; +use rusqlite::params; +use rusqlite::Row; use serde_json::Value; use super::SqliteStorage; -use crate::{ - deckconfig::{DeckConfSchema11, DeckConfig, DeckConfigId, DeckConfigInner}, - prelude::*, -}; +use crate::deckconfig::DeckConfSchema11; +use crate::deckconfig::DeckConfig; +use crate::deckconfig::DeckConfigId; +use crate::deckconfig::DeckConfigInner; +use crate::prelude::*; fn row_to_deckconf(row: &Row) -> Result { let config = DeckConfigInner::decode(row.get_ref_unwrap(4).as_blob()?)?; diff --git a/rslib/src/storage/graves/mod.rs b/rslib/src/storage/graves/mod.rs index 8fdc6db0b..d00721c71 100644 --- a/rslib/src/storage/graves/mod.rs +++ b/rslib/src/storage/graves/mod.rs @@ -7,7 +7,8 @@ use num_enum::TryFromPrimitive; use rusqlite::params; use super::SqliteStorage; -use crate::{prelude::*, sync::collection::graves::Graves}; +use crate::prelude::*; +use crate::sync::collection::graves::Graves; #[derive(TryFromPrimitive)] #[repr(u8)] diff --git a/rslib/src/storage/note/mod.rs b/rslib/src/storage/note/mod.rs index c6a1d6e3f..e2e23c548 100644 --- a/rslib/src/storage/note/mod.rs +++ b/rslib/src/storage/note/mod.rs @@ -1,18 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; +use std::collections::HashSet; -use rusqlite::{params, Row}; +use rusqlite::params; +use rusqlite::Row; -use crate::{ - error::Result, - import_export::package::NoteMeta, - notes::{Note, NoteId, NoteTags}, - notetype::NotetypeId, - tags::{join_tags, split_tags}, - timestamp::TimestampMillis, -}; +use crate::error::Result; +use crate::import_export::package::NoteMeta; +use crate::notes::Note; +use crate::notes::NoteId; +use crate::notes::NoteTags; +use crate::notetype::NotetypeId; +use crate::tags::join_tags; +use crate::tags::split_tags; +use crate::timestamp::TimestampMillis; pub(crate) fn split_fields(fields: &str) -> Vec { fields.split('\x1f').map(Into::into).collect() @@ -49,7 +52,8 @@ impl super::SqliteStorage { .collect() } - /// If fields have been modified, caller must call note.prepare_for_update() prior to calling this. + /// If fields have been modified, caller must call note.prepare_for_update() + /// prior to calling this. pub(crate) fn update_note(&self, note: &Note) -> Result<()> { assert_ne!(note.id.0, 0); let mut stmt = self.db.prepare_cached(include_str!("update.sql"))?; @@ -103,7 +107,8 @@ impl super::SqliteStorage { .map_err(Into::into) } - /// Add or update the provided note, preserving ID. Used by the syncing code. + /// Add or update the provided note, preserving ID. Used by the syncing + /// code. pub(crate) fn add_or_update_note(&self, note: &Note) -> Result<()> { let mut stmt = self.db.prepare_cached(include_str!("add_or_update.sql"))?; stmt.execute(params![ diff --git a/rslib/src/storage/notetype/mod.rs b/rslib/src/storage/notetype/mod.rs index dab440e04..30625eaff 100644 --- a/rslib/src/storage/notetype/mod.rs +++ b/rslib/src/storage/notetype/mod.rs @@ -1,21 +1,26 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; +use std::collections::HashSet; use prost::Message; -use rusqlite::{params, OptionalExtension, Row}; +use rusqlite::params; +use rusqlite::OptionalExtension; +use rusqlite::Row; use unicase::UniCase; -use super::{ids_to_string, SqliteStorage}; -use crate::{ - error::DbErrorKind, - notetype::{ - AlreadyGeneratedCardInfo, CardTemplate, CardTemplateConfig, NoteField, NoteFieldConfig, - NotetypeConfig, NotetypeSchema11, - }, - prelude::*, -}; +use super::ids_to_string; +use super::SqliteStorage; +use crate::error::DbErrorKind; +use crate::notetype::AlreadyGeneratedCardInfo; +use crate::notetype::CardTemplate; +use crate::notetype::CardTemplateConfig; +use crate::notetype::NoteField; +use crate::notetype::NoteFieldConfig; +use crate::notetype::NotetypeConfig; +use crate::notetype::NotetypeSchema11; +use crate::prelude::*; fn row_to_notetype_core(row: &Row) -> Result { let config = NotetypeConfig::decode(row.get_ref_unwrap(4).as_blob()?)?; diff --git a/rslib/src/storage/revlog/mod.rs b/rslib/src/storage/revlog/mod.rs index 7c3fc8585..f9d38eb40 100644 --- a/rslib/src/storage/revlog/mod.rs +++ b/rslib/src/storage/revlog/mod.rs @@ -3,18 +3,17 @@ use std::convert::TryFrom; -use rusqlite::{ - params, - types::{FromSql, FromSqlError, ValueRef}, - Row, -}; +use rusqlite::params; +use rusqlite::types::FromSql; +use rusqlite::types::FromSqlError; +use rusqlite::types::ValueRef; +use rusqlite::Row; use super::SqliteStorage; -use crate::{ - error::Result, - prelude::*, - revlog::{RevlogEntry, RevlogReviewKind}, -}; +use crate::error::Result; +use crate::prelude::*; +use crate::revlog::RevlogEntry; +use crate::revlog::RevlogReviewKind; pub(crate) struct StudiedToday { pub cards: u32, @@ -60,8 +59,8 @@ impl SqliteStorage { Ok(()) } - /// Adds the entry, if its id is unique. If it is not, and `uniquify` is true, - /// adds it with a new id. Returns the added id. + /// Adds the entry, if its id is unique. If it is not, and `uniquify` is + /// true, adds it with a new id. Returns the added id. /// (I.e., the option is safe to unwrap, if `uniquify` is true.) pub(crate) fn add_revlog_entry( &self, @@ -94,7 +93,8 @@ impl SqliteStorage { .transpose() } - /// Only intended to be used by the undo code, as Anki can not sync revlog deletions. + /// Only intended to be used by the undo code, as Anki can not sync revlog + /// deletions. pub(crate) fn remove_revlog_entry(&self, id: RevlogId) -> Result<()> { self.db .prepare_cached("delete from revlog where id = ?")? diff --git a/rslib/src/storage/sqlite.rs b/rslib/src/storage/sqlite.rs index 17f0b1f0c..b07f17942 100644 --- a/rslib/src/storage/sqlite.rs +++ b/rslib/src/storage/sqlite.rs @@ -1,31 +1,38 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, cmp::Ordering, collections::HashSet, hash::Hasher, path::Path, sync::Arc}; +use std::borrow::Cow; +use std::cmp::Ordering; +use std::collections::HashSet; +use std::hash::Hasher; +use std::path::Path; +use std::sync::Arc; use fnv::FnvHasher; use regex::Regex; -use rusqlite::{functions::FunctionFlags, params, Connection}; +use rusqlite::functions::FunctionFlags; +use rusqlite::params; +use rusqlite::Connection; use unicase::UniCase; -use super::{ - upgrades::{SCHEMA_MAX_VERSION, SCHEMA_MIN_VERSION, SCHEMA_STARTING_VERSION}, - SchemaVersion, -}; -use crate::{ - config::schema11::schema11_config_as_string, - error::DbErrorKind, - prelude::*, - scheduler::timing::{local_minutes_west_for_stamp, v1_creation_date}, - text::without_combining, -}; +use super::upgrades::SCHEMA_MAX_VERSION; +use super::upgrades::SCHEMA_MIN_VERSION; +use super::upgrades::SCHEMA_STARTING_VERSION; +use super::SchemaVersion; +use crate::config::schema11::schema11_config_as_string; +use crate::error::DbErrorKind; +use crate::prelude::*; +use crate::scheduler::timing::local_minutes_west_for_stamp; +use crate::scheduler::timing::v1_creation_date; +use crate::text::without_combining; fn unicase_compare(s1: &str, s2: &str) -> Ordering { UniCase::new(s1).cmp(&UniCase::new(s2)) } // fixme: rollback savepoint when tags not changed -// fixme: need to drop out of wal prior to vacuuming to fix page size of older collections +// fixme: need to drop out of wal prior to vacuuming to fix page size of older +// collections // currently public for dbproxy #[derive(Debug)] @@ -296,8 +303,8 @@ impl SqliteStorage { Ok(()) } - /// Flush data from WAL file into DB, so the DB is safe to copy. Caller must not call this - /// while there is an active transaction. + /// Flush data from WAL file into DB, so the DB is safe to copy. Caller must + /// not call this while there is an active transaction. pub(crate) fn checkpoint(&self) -> Result<()> { if !self.db.is_autocommit() { return Err(AnkiError::db_error( diff --git a/rslib/src/storage/sync.rs b/rslib/src/storage/sync.rs index ec0ff45d1..4bd0e5242 100644 --- a/rslib/src/storage/sync.rs +++ b/rslib/src/storage/sync.rs @@ -1,7 +1,9 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use rusqlite::{params, types::FromSql, ToSql}; +use rusqlite::params; +use rusqlite::types::FromSql; +use rusqlite::ToSql; use super::*; use crate::prelude::*; diff --git a/rslib/src/storage/sync_check.rs b/rslib/src/storage/sync_check.rs index 7c8066c8d..50e92f7d0 100644 --- a/rslib/src/storage/sync_check.rs +++ b/rslib/src/storage/sync_check.rs @@ -2,11 +2,10 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use super::*; -use crate::{ - error::SyncErrorKind, - prelude::*, - sync::collection::sanity::{SanityCheckCounts, SanityCheckDueCounts}, -}; +use crate::error::SyncErrorKind; +use crate::prelude::*; +use crate::sync::collection::sanity::SanityCheckCounts; +use crate::sync::collection::sanity::SanityCheckDueCounts; impl SqliteStorage { fn table_has_usn(&self, table: &str) -> Result { diff --git a/rslib/src/storage/tag/mod.rs b/rslib/src/storage/tag/mod.rs index 38e5a07bb..210246317 100644 --- a/rslib/src/storage/tag/mod.rs +++ b/rslib/src/storage/tag/mod.rs @@ -3,10 +3,13 @@ use std::collections::HashMap; -use rusqlite::{params, Row}; +use rusqlite::params; +use rusqlite::Row; use super::SqliteStorage; -use crate::{error::Result, tags::Tag, types::Usn}; +use crate::error::Result; +use crate::tags::Tag; +use crate::types::Usn; fn row_to_tag(row: &Row) -> Result { Ok(Tag { diff --git a/rslib/src/storage/upgrades/mod.rs b/rslib/src/storage/upgrades/mod.rs index 2f6a2b5d5..12ac1593c 100644 --- a/rslib/src/storage/upgrades/mod.rs +++ b/rslib/src/storage/upgrades/mod.rs @@ -8,7 +8,8 @@ pub(super) const SCHEMA_STARTING_VERSION: u8 = 11; /// The maximum schema version we can open. pub(super) const SCHEMA_MAX_VERSION: u8 = 18; -use super::{SchemaVersion, SqliteStorage}; +use super::SchemaVersion; +use super::SqliteStorage; use crate::error::Result; impl SqliteStorage { diff --git a/rslib/src/sync/collection/changes.rs b/rslib/src/sync/collection/changes.rs index 17812723c..474259b75 100644 --- a/rslib/src/sync/collection/changes.rs +++ b/rslib/src/sync/collection/changes.rs @@ -6,27 +6,25 @@ use std::collections::HashMap; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; use serde_json::Value; use serde_tuple::Serialize_tuple; -use tracing::{debug, trace}; +use tracing::debug; +use tracing::trace; -use crate::{ - deckconfig::DeckConfSchema11, - decks::DeckSchema11, - error::SyncErrorKind, - notetype::NotetypeSchema11, - prelude::*, - sync::{ - collection::{ - normal::{ClientSyncState, NormalSyncProgress, NormalSyncer}, - protocol::SyncProtocol, - start::ServerSyncState, - }, - request::IntoSyncRequest, - }, - tags::Tag, -}; +use crate::deckconfig::DeckConfSchema11; +use crate::decks::DeckSchema11; +use crate::error::SyncErrorKind; +use crate::notetype::NotetypeSchema11; +use crate::prelude::*; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::NormalSyncer; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::collection::start::ServerSyncState; +use crate::sync::request::IntoSyncRequest; +use crate::tags::Tag; #[derive(Serialize, Deserialize, Debug)] pub struct ApplyChangesRequest { @@ -58,10 +56,10 @@ impl NormalSyncer<'_, F> where F: FnMut(NormalSyncProgress, bool), { - // This was assumed to a cheap operation when originally written - it didn't anticipate - // the large deck trees and note types some users would create. They should be chunked - // in the future, like other objects. Syncing tags explicitly is also probably of limited - // usefulness. + // This was assumed to a cheap operation when originally written - it didn't + // anticipate the large deck trees and note types some users would create. + // They should be chunked in the future, like other objects. Syncing tags + // explicitly is also probably of limited usefulness. pub(in crate::sync) async fn process_unchunked_changes( &mut self, state: &ClientSyncState, @@ -213,8 +211,8 @@ impl Collection { Ok(changed) } - /// Currently this is all config, as legacy clients overwrite the local items - /// with the provided value. + /// Currently this is all config, as legacy clients overwrite the local + /// items with the provided value. fn changed_config(&self) -> Result> { let conf = self.storage.get_all_config()?; self.storage.clear_config_usns()?; diff --git a/rslib/src/sync/collection/chunks.rs b/rslib/src/sync/collection/chunks.rs index a3d9e2004..f786f3bfc 100644 --- a/rslib/src/sync/collection/chunks.rs +++ b/rslib/src/sync/collection/chunks.rs @@ -2,27 +2,29 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use itertools::Itertools; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; use serde_tuple::Serialize_tuple; use tracing::debug; -use crate::{ - card::{Card, CardQueue, CardType}, - notes::Note, - prelude::*, - revlog::RevlogEntry, - serde::deserialize_int_from_number, - storage::card::data::{card_data_string, CardData}, - sync::{ - collection::{ - normal::{ClientSyncState, NormalSyncProgress, NormalSyncer}, - protocol::{EmptyInput, SyncProtocol}, - start::ServerSyncState, - }, - request::IntoSyncRequest, - }, - tags::{join_tags, split_tags}, -}; +use crate::card::Card; +use crate::card::CardQueue; +use crate::card::CardType; +use crate::notes::Note; +use crate::prelude::*; +use crate::revlog::RevlogEntry; +use crate::serde::deserialize_int_from_number; +use crate::storage::card::data::card_data_string; +use crate::storage::card::data::CardData; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::NormalSyncer; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::collection::start::ServerSyncState; +use crate::sync::request::IntoSyncRequest; +use crate::tags::join_tags; +use crate::tags::split_tags; pub(in crate::sync) struct ChunkableIds { revlog: Vec, diff --git a/rslib/src/sync/collection/download.rs b/rslib/src/sync/collection/download.rs index bdbb49557..676d06cf0 100644 --- a/rslib/src/sync/collection/download.rs +++ b/rslib/src/sync/collection/download.rs @@ -1,21 +1,20 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - collection::CollectionBuilder, - io::{atomic_rename, new_tempfile_in_parent_of, read_file, write_file}, - prelude::*, - storage::SchemaVersion, - sync::{ - collection::{ - progress::FullSyncProgressFn, - protocol::{EmptyInput, SyncProtocol}, - }, - error::{HttpResult, OrHttpErr}, - http_client::HttpSyncClient, - login::SyncAuth, - }, -}; +use crate::collection::CollectionBuilder; +use crate::io::atomic_rename; +use crate::io::new_tempfile_in_parent_of; +use crate::io::read_file; +use crate::io::write_file; +use crate::prelude::*; +use crate::storage::SchemaVersion; +use crate::sync::collection::progress::FullSyncProgressFn; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::SyncAuth; impl Collection { /// Download collection from AnkiWeb. Caller must re-open afterwards. diff --git a/rslib/src/sync/collection/finish.rs b/rslib/src/sync/collection/finish.rs index 25d73cd01..b06f03b44 100644 --- a/rslib/src/sync/collection/finish.rs +++ b/rslib/src/sync/collection/finish.rs @@ -1,13 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - prelude::*, - sync::collection::{ - normal::{ClientSyncState, NormalSyncProgress, NormalSyncer}, - protocol::{EmptyInput, SyncProtocol}, - }, -}; +use crate::prelude::*; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::NormalSyncer; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; impl NormalSyncer<'_, F> where diff --git a/rslib/src/sync/collection/graves.rs b/rslib/src/sync/collection/graves.rs index 8213b3e13..c5f825643 100644 --- a/rslib/src/sync/collection/graves.rs +++ b/rslib/src/sync/collection/graves.rs @@ -1,12 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; -use crate::{ - prelude::*, - sync::collection::{chunks::CHUNK_SIZE, start::ServerSyncState}, -}; +use crate::prelude::*; +use crate::sync::collection::chunks::CHUNK_SIZE; +use crate::sync::collection::start::ServerSyncState; #[derive(Serialize, Deserialize, Debug, Default, Clone)] pub struct ApplyGravesRequest { diff --git a/rslib/src/sync/collection/meta.rs b/rslib/src/sync/collection/meta.rs index 9b62dc261..8ca35214e 100644 --- a/rslib/src/sync/collection/meta.rs +++ b/rslib/src/sync/collection/meta.rs @@ -3,27 +3,27 @@ use ammonia::Url; use axum::http::StatusCode; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; use tracing::debug; -use crate::{ - config::SchedulerVersion, - prelude::*, - sync::{ - collection::{ - normal::{ClientSyncState, SyncActionRequired}, - protocol::SyncProtocol, - }, - error::{HttpError, HttpResult, HttpSnafu, OrHttpErr}, - http_client::HttpSyncClient, - request::{IntoSyncRequest, SyncRequest}, - version::{ - SYNC_VERSION_09_V2_SCHEDULER, SYNC_VERSION_10_V2_TIMEZONE, SYNC_VERSION_MAX, - SYNC_VERSION_MIN, - }, - }, - version::sync_client_version, -}; +use crate::config::SchedulerVersion; +use crate::prelude::*; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::collection::normal::SyncActionRequired; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::error::HttpError; +use crate::sync::error::HttpResult; +use crate::sync::error::HttpSnafu; +use crate::sync::error::OrHttpErr; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::request::IntoSyncRequest; +use crate::sync::request::SyncRequest; +use crate::sync::version::SYNC_VERSION_09_V2_SCHEDULER; +use crate::sync::version::SYNC_VERSION_10_V2_TIMEZONE; +use crate::sync::version::SYNC_VERSION_MAX; +use crate::sync::version::SYNC_VERSION_MIN; +use crate::version::sync_client_version; #[derive(Serialize, Deserialize, Debug, Default)] pub struct SyncMeta { diff --git a/rslib/src/sync/collection/normal.rs b/rslib/src/sync/collection/normal.rs index d476f0ee8..eef6fae55 100644 --- a/rslib/src/sync/collection/normal.rs +++ b/rslib/src/sync/collection/normal.rs @@ -3,21 +3,18 @@ use tracing::debug; -use crate::{ - collection::Collection, - error, - error::{AnkiError, SyncError, SyncErrorKind}, - prelude::Usn, - sync::{ - collection::{ - progress::SyncStage, - protocol::{EmptyInput, SyncProtocol}, - status::online_sync_status_check, - }, - http_client::HttpSyncClient, - login::SyncAuth, - }, -}; +use crate::collection::Collection; +use crate::error; +use crate::error::AnkiError; +use crate::error::SyncError; +use crate::error::SyncErrorKind; +use crate::prelude::Usn; +use crate::sync::collection::progress::SyncStage; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::collection::status::online_sync_status_check; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::SyncAuth; pub struct NormalSyncer<'a, F> { pub(in crate::sync) col: &'a mut Collection, diff --git a/rslib/src/sync/collection/progress.rs b/rslib/src/sync/collection/progress.rs index 0e2ea52ba..d79e4ad2c 100644 --- a/rslib/src/sync/collection/progress.rs +++ b/rslib/src/sync/collection/progress.rs @@ -1,14 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - error, - sync::{ - collection::protocol::{EmptyInput, SyncProtocol}, - http_client::HttpSyncClient, - login::SyncAuth, - }, -}; +use crate::error; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::SyncAuth; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SyncStage { diff --git a/rslib/src/sync/collection/protocol.rs b/rslib/src/sync/collection/protocol.rs index e9a005990..4844f07b9 100644 --- a/rslib/src/sync/collection/protocol.rs +++ b/rslib/src/sync/collection/protocol.rs @@ -5,27 +5,29 @@ use std::marker::PhantomData; use ammonia::Url; use async_trait::async_trait; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use strum::IntoStaticStr; -use crate::{ - prelude::TimestampMillis, - sync::{ - collection::{ - changes::{ApplyChangesRequest, UnchunkedChanges}, - chunks::{ApplyChunkRequest, Chunk}, - graves::{ApplyGravesRequest, Graves}, - meta::{MetaRequest, SyncMeta}, - sanity::{SanityCheckRequest, SanityCheckResponse}, - start::StartRequest, - upload::UploadResponse, - }, - error::HttpResult, - login::{HostKeyRequest, HostKeyResponse}, - request::{IntoSyncRequest, SyncRequest}, - response::SyncResponse, - }, -}; +use crate::prelude::TimestampMillis; +use crate::sync::collection::changes::ApplyChangesRequest; +use crate::sync::collection::changes::UnchunkedChanges; +use crate::sync::collection::chunks::ApplyChunkRequest; +use crate::sync::collection::chunks::Chunk; +use crate::sync::collection::graves::ApplyGravesRequest; +use crate::sync::collection::graves::Graves; +use crate::sync::collection::meta::MetaRequest; +use crate::sync::collection::meta::SyncMeta; +use crate::sync::collection::sanity::SanityCheckRequest; +use crate::sync::collection::sanity::SanityCheckResponse; +use crate::sync::collection::start::StartRequest; +use crate::sync::collection::upload::UploadResponse; +use crate::sync::error::HttpResult; +use crate::sync::login::HostKeyRequest; +use crate::sync::login::HostKeyResponse; +use crate::sync::request::IntoSyncRequest; +use crate::sync::request::SyncRequest; +use crate::sync::response::SyncResponse; #[derive(IntoStaticStr, Deserialize, PartialEq, Eq, Debug)] #[serde(rename_all = "camelCase")] @@ -90,9 +92,9 @@ pub trait SyncProtocol: Send + Sync + 'static { } /// The sync protocol expects '{}' to be sent in requests without args. -/// Serde serializes/deserializes empty structs as 'null', so we add an empty value -/// to cause it to produce a map instead. This only applies to inputs; empty outputs -/// are returned as ()/null. +/// Serde serializes/deserializes empty structs as 'null', so we add an empty +/// value to cause it to produce a map instead. This only applies to inputs; +/// empty outputs are returned as ()/null. #[derive(Serialize, Deserialize, Default)] #[serde(deny_unknown_fields)] pub struct EmptyInput { diff --git a/rslib/src/sync/collection/sanity.rs b/rslib/src/sync/collection/sanity.rs index 181219bbf..5fa991f77 100644 --- a/rslib/src/sync/collection/sanity.rs +++ b/rslib/src/sync/collection/sanity.rs @@ -1,22 +1,19 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; use serde_tuple::Serialize_tuple; -use tracing::{debug, info}; +use tracing::debug; +use tracing::info; -use crate::{ - error::SyncErrorKind, - prelude::*, - serde::default_on_invalid, - sync::{ - collection::{ - normal::{NormalSyncProgress, NormalSyncer}, - protocol::SyncProtocol, - }, - request::IntoSyncRequest, - }, -}; +use crate::error::SyncErrorKind; +use crate::prelude::*; +use crate::serde::default_on_invalid; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::NormalSyncer; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::request::IntoSyncRequest; #[derive(Serialize, Deserialize, Debug)] pub struct SanityCheckResponse { diff --git a/rslib/src/sync/collection/start.rs b/rslib/src/sync/collection/start.rs index 682e34191..f15b0c369 100644 --- a/rslib/src/sync/collection/start.rs +++ b/rslib/src/sync/collection/start.rs @@ -1,21 +1,20 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde::{Deserialize, Deserializer, Serialize}; +use serde::Deserialize; +use serde::Deserializer; +use serde::Serialize; use tracing::debug; -use crate::{ - prelude::*, - sync::{ - collection::{ - chunks::ChunkableIds, - graves::{ApplyGravesRequest, Graves}, - normal::{ClientSyncState, NormalSyncProgress, NormalSyncer}, - protocol::SyncProtocol, - }, - request::IntoSyncRequest, - }, -}; +use crate::prelude::*; +use crate::sync::collection::chunks::ChunkableIds; +use crate::sync::collection::graves::ApplyGravesRequest; +use crate::sync::collection::graves::Graves; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::NormalSyncer; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::request::IntoSyncRequest; impl NormalSyncer<'_, F> where @@ -116,8 +115,8 @@ pub fn server_start( /// retain a bunch of information across requests. These are set either /// on start, or on subsequent methods. pub struct ServerSyncState { - /// The session key. This is sent on every http request, but is ignored for methods - /// where there is not active sync state. + /// The session key. This is sent on every http request, but is ignored for + /// methods where there is not active sync state. pub skey: String, pub(in crate::sync) server_usn: Usn, diff --git a/rslib/src/sync/collection/status.rs b/rslib/src/sync/collection/status.rs index 829dd9413..9c9b30a11 100644 --- a/rslib/src/sync/collection/status.rs +++ b/rslib/src/sync/collection/status.rs @@ -3,19 +3,16 @@ use tracing::debug; -use crate::{ - error::SyncErrorKind, - pb::sync::sync_status_response, - prelude::*, - sync::{ - collection::{meta::SyncMeta, normal::ClientSyncState}, - http_client::HttpSyncClient, - }, -}; +use crate::error::SyncErrorKind; +use crate::pb::sync::sync_status_response; +use crate::prelude::*; +use crate::sync::collection::meta::SyncMeta; +use crate::sync::collection::normal::ClientSyncState; +use crate::sync::http_client::HttpSyncClient; impl Collection { - /// Checks local collection only. If local collection is clean but changes are pending - /// on AnkiWeb, NoChanges will be returned. + /// Checks local collection only. If local collection is clean but changes + /// are pending on AnkiWeb, NoChanges will be returned. pub fn sync_status_offline(&mut self) -> Result { let stamps = self.storage.get_collection_timestamps()?; let required = if stamps.schema_changed_since_sync() { @@ -30,11 +27,13 @@ impl Collection { } } -/// Should be called if a call to sync_status_offline() returns NoChanges, to check -/// if AnkiWeb has pending changes. Caller should persist new endpoint if returned. +/// Should be called if a call to sync_status_offline() returns NoChanges, to +/// check if AnkiWeb has pending changes. Caller should persist new endpoint if +/// returned. /// -/// This routine is outside of the collection, as we don't want to block collection access -/// for a potentially slow network request that happens in the background. +/// This routine is outside of the collection, as we don't want to block +/// collection access for a potentially slow network request that happens in the +/// background. pub async fn online_sync_status_check( local: SyncMeta, server: &mut HttpSyncClient, diff --git a/rslib/src/sync/collection/tests.rs b/rslib/src/sync/collection/tests.rs index 0b2f19eb7..a332de1eb 100644 --- a/rslib/src/sync/collection/tests.rs +++ b/rslib/src/sync/collection/tests.rs @@ -9,41 +9,46 @@ use axum::http::StatusCode; use once_cell::sync::Lazy; use reqwest::Url; use serde_json::json; -use tempfile::{tempdir, TempDir}; -use tokio::sync::{Mutex, MutexGuard}; -use tracing::{Instrument, Span}; -use wiremock::{ - matchers::{method, path}, - Mock, MockServer, ResponseTemplate, -}; +use tempfile::tempdir; +use tempfile::TempDir; +use tokio::sync::Mutex; +use tokio::sync::MutexGuard; +use tracing::Instrument; +use tracing::Span; +use wiremock::matchers::method; +use wiremock::matchers::path; +use wiremock::Mock; +use wiremock::MockServer; +use wiremock::ResponseTemplate; -use crate::{ - card::CardQueue, - collection::CollectionBuilder, - deckconfig::DeckConfig, - decks::DeckKind, - error::{SyncError, SyncErrorKind}, - log::set_global_logger, - notetype::all_stock_notetypes, - prelude::*, - revlog::RevlogEntry, - search::SortMode, - sync::{ - collection::{ - graves::ApplyGravesRequest, - meta::MetaRequest, - normal::{NormalSyncProgress, NormalSyncer, SyncActionRequired, SyncOutput}, - progress::FullSyncProgress, - protocol::{EmptyInput, SyncProtocol}, - start::StartRequest, - upload::{UploadResponse, CORRUPT_MESSAGE}, - }, - http_client::HttpSyncClient, - http_server::SimpleServer, - login::{HostKeyRequest, SyncAuth}, - request::IntoSyncRequest, - }, -}; +use crate::card::CardQueue; +use crate::collection::CollectionBuilder; +use crate::deckconfig::DeckConfig; +use crate::decks::DeckKind; +use crate::error::SyncError; +use crate::error::SyncErrorKind; +use crate::log::set_global_logger; +use crate::notetype::all_stock_notetypes; +use crate::prelude::*; +use crate::revlog::RevlogEntry; +use crate::search::SortMode; +use crate::sync::collection::graves::ApplyGravesRequest; +use crate::sync::collection::meta::MetaRequest; +use crate::sync::collection::normal::NormalSyncProgress; +use crate::sync::collection::normal::NormalSyncer; +use crate::sync::collection::normal::SyncActionRequired; +use crate::sync::collection::normal::SyncOutput; +use crate::sync::collection::progress::FullSyncProgress; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::collection::start::StartRequest; +use crate::sync::collection::upload::UploadResponse; +use crate::sync::collection::upload::CORRUPT_MESSAGE; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::http_server::SimpleServer; +use crate::sync::login::HostKeyRequest; +use crate::sync::login::SyncAuth; +use crate::sync::request::IntoSyncRequest; struct TestAuth { username: String, @@ -281,8 +286,8 @@ async fn sanity_check_should_roll_back_and_force_full_sync() -> Result<()> { let mut col1 = ctx.col1(); - // add a deck but don't mark it as requiring a sync, which will trigger the sanity - // check to fail + // add a deck but don't mark it as requiring a sync, which will trigger the + // sanity check to fail let mut deck = col1.get_or_create_normal_deck("unsynced deck")?; col1.add_or_update_deck(&mut deck)?; col1.storage diff --git a/rslib/src/sync/collection/upload.rs b/rslib/src/sync/collection/upload.rs index 294e144bc..4c533a4ad 100644 --- a/rslib/src/sync/collection/upload.rs +++ b/rslib/src/sync/collection/upload.rs @@ -1,30 +1,34 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs, io::Write}; +use std::fs; +use std::io::Write; -use axum::response::{IntoResponse, Response}; -use flate2::{write::GzEncoder, Compression}; +use axum::response::IntoResponse; +use axum::response::Response; +use flate2::write::GzEncoder; +use flate2::Compression; use futures::StreamExt; use tokio_util::io::ReaderStream; -use crate::{ - collection::CollectionBuilder, - error::SyncErrorKind, - io::{atomic_rename, new_tempfile_in_parent_of, write_file}, - prelude::*, - storage::SchemaVersion, - sync::{ - collection::{progress::FullSyncProgressFn, protocol::SyncProtocol}, - error::{HttpResult, OrHttpErr}, - http_client::HttpSyncClient, - login::SyncAuth, - request::{IntoSyncRequest, MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED}, - }, -}; +use crate::collection::CollectionBuilder; +use crate::error::SyncErrorKind; +use crate::io::atomic_rename; +use crate::io::new_tempfile_in_parent_of; +use crate::io::write_file; +use crate::prelude::*; +use crate::storage::SchemaVersion; +use crate::sync::collection::progress::FullSyncProgressFn; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::SyncAuth; +use crate::sync::request::IntoSyncRequest; +use crate::sync::request::MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED; -/// Old clients didn't display a useful message on HTTP 400, and were expected to show the error message -/// returned by the server. +/// Old clients didn't display a useful message on HTTP 400, and were expected +/// to show the error message returned by the server. pub const CORRUPT_MESSAGE: &str = "Your upload was corrupt. Please use Check Database, or restore from backup."; diff --git a/rslib/src/sync/error.rs b/rslib/src/sync/error.rs index a06182368..fb7d1bbb1 100644 --- a/rslib/src/sync/error.rs +++ b/rslib/src/sync/error.rs @@ -1,11 +1,12 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use axum::{ - http::StatusCode, - response::{IntoResponse, Redirect, Response}, -}; -use snafu::{OptionExt, Snafu}; +use axum::http::StatusCode; +use axum::response::IntoResponse; +use axum::response::Redirect; +use axum::response::Response; +use snafu::OptionExt; +use snafu::Snafu; pub type HttpResult = std::result::Result; diff --git a/rslib/src/sync/http_client/full_sync.rs b/rslib/src/sync/http_client/full_sync.rs index 157012bcc..11c61661b 100644 --- a/rslib/src/sync/http_client/full_sync.rs +++ b/rslib/src/sync/http_client/full_sync.rs @@ -1,21 +1,22 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{future::Future, time::Duration}; +use std::future::Future; +use std::time::Duration; -use tokio::{select, time::interval}; +use tokio::select; +use tokio::time::interval; -use crate::sync::{ - collection::{ - progress::{FullSyncProgress, FullSyncProgressFn}, - protocol::{EmptyInput, SyncMethod}, - upload::UploadResponse, - }, - error::HttpResult, - http_client::{io_monitor::IoMonitor, HttpSyncClient}, - request::SyncRequest, - response::SyncResponse, -}; +use crate::sync::collection::progress::FullSyncProgress; +use crate::sync::collection::progress::FullSyncProgressFn; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncMethod; +use crate::sync::collection::upload::UploadResponse; +use crate::sync::error::HttpResult; +use crate::sync::http_client::io_monitor::IoMonitor; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::request::SyncRequest; +use crate::sync::response::SyncResponse; impl HttpSyncClient { pub fn set_full_sync_progress_fn(&mut self, func: Option) { diff --git a/rslib/src/sync/http_client/io_monitor.rs b/rslib/src/sync/http_client/io_monitor.rs index 701c70263..2cf0d080d 100644 --- a/rslib/src/sync/http_client/io_monitor.rs +++ b/rslib/src/sync/http_client/io_monitor.rs @@ -1,33 +1,37 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - io::{Cursor, ErrorKind}, - sync::{Arc, Mutex}, - time::Duration, -}; +use std::io::Cursor; +use std::io::ErrorKind; +use std::sync::Arc; +use std::sync::Mutex; +use std::time::Duration; use bytes::Bytes; -use futures::{Stream, StreamExt, TryStreamExt}; -use reqwest::{ - header::{CONTENT_TYPE, LOCATION}, - Body, RequestBuilder, Response, StatusCode, -}; -use tokio::{ - io::AsyncReadExt, - select, - time::{interval, Instant}, -}; -use tokio_util::io::{ReaderStream, StreamReader}; +use futures::Stream; +use futures::StreamExt; +use futures::TryStreamExt; +use reqwest::header::CONTENT_TYPE; +use reqwest::header::LOCATION; +use reqwest::Body; +use reqwest::RequestBuilder; +use reqwest::Response; +use reqwest::StatusCode; +use tokio::io::AsyncReadExt; +use tokio::select; +use tokio::time::interval; +use tokio::time::Instant; +use tokio_util::io::ReaderStream; +use tokio_util::io::StreamReader; -use crate::{ - error::Result, - sync::{ - error::{HttpError, HttpResult, HttpSnafu, OrHttpErr}, - request::header_and_stream::{decode_zstd_body_stream, encode_zstd_body_stream}, - response::ORIGINAL_SIZE, - }, -}; +use crate::error::Result; +use crate::sync::error::HttpError; +use crate::sync::error::HttpResult; +use crate::sync::error::HttpSnafu; +use crate::sync::error::OrHttpErr; +use crate::sync::request::header_and_stream::decode_zstd_body_stream; +use crate::sync::request::header_and_stream::encode_zstd_body_stream; +use crate::sync::response::ORIGINAL_SIZE; /// Serves two purposes: /// - allows us to monitor data sending/receiving and abort if @@ -96,8 +100,8 @@ impl IoMonitor { } } - /// Takes care of encoding provided request data and setting content type to binary, and returns - /// the decompressed response body. + /// Takes care of encoding provided request data and setting content type to + /// binary, and returns the decompressed response body. pub async fn zstd_request_with_timeout( &self, request: RequestBuilder, @@ -155,8 +159,8 @@ impl IoMonitor { } } -/// Reqwest can't retry a redirected request as the body has been consumed, so we need -/// to bubble it up to the sync driver to retry. +/// Reqwest can't retry a redirected request as the body has been consumed, so +/// we need to bubble it up to the sync driver to retry. fn map_redirect_to_error(resp: &Response) -> HttpResult<()> { if resp.status() == StatusCode::PERMANENT_REDIRECT { let location = resp @@ -184,12 +188,15 @@ impl IoMonitor {} #[cfg(test)] mod test { use async_stream::stream; - use futures::{pin_mut, StreamExt}; - use tokio::{select, time::sleep}; - use wiremock::{ - matchers::{method, path}, - Mock, MockServer, ResponseTemplate, - }; + use futures::pin_mut; + use futures::StreamExt; + use tokio::select; + use tokio::time::sleep; + use wiremock::matchers::method; + use wiremock::matchers::path; + use wiremock::Mock; + use wiremock::MockServer; + use wiremock::ResponseTemplate; use super::*; use crate::sync::error::HttpError; diff --git a/rslib/src/sync/http_client/mod.rs b/rslib/src/sync/http_client/mod.rs index c5741a3e0..6698240e0 100644 --- a/rslib/src/sync/http_client/mod.rs +++ b/rslib/src/sync/http_client/mod.rs @@ -5,24 +5,26 @@ pub(crate) mod full_sync; pub(crate) mod io_monitor; mod protocol; -use std::{sync::Mutex, time::Duration}; +use std::sync::Mutex; +use std::time::Duration; -use reqwest::{Client, Error, StatusCode, Url}; +use reqwest::Client; +use reqwest::Error; +use reqwest::StatusCode; +use reqwest::Url; -use crate::{ - notes, - sync::{ - collection::{progress::FullSyncProgressFn, protocol::AsSyncEndpoint}, - error::{HttpError, HttpResult, HttpSnafu}, - http_client::io_monitor::IoMonitor, - login::SyncAuth, - request::{ - header_and_stream::{SyncHeader, SYNC_HEADER_NAME}, - SyncRequest, - }, - response::SyncResponse, - }, -}; +use crate::notes; +use crate::sync::collection::progress::FullSyncProgressFn; +use crate::sync::collection::protocol::AsSyncEndpoint; +use crate::sync::error::HttpError; +use crate::sync::error::HttpResult; +use crate::sync::error::HttpSnafu; +use crate::sync::http_client::io_monitor::IoMonitor; +use crate::sync::login::SyncAuth; +use crate::sync::request::header_and_stream::SyncHeader; +use crate::sync::request::header_and_stream::SYNC_HEADER_NAME; +use crate::sync::request::SyncRequest; +use crate::sync::response::SyncResponse; pub struct HttpSyncClient { /// Set to the empty string for initial login diff --git a/rslib/src/sync/http_client/protocol.rs b/rslib/src/sync/http_client/protocol.rs index cbb955437..0c84b1b84 100644 --- a/rslib/src/sync/http_client/protocol.rs +++ b/rslib/src/sync/http_client/protocol.rs @@ -3,33 +3,38 @@ use async_trait::async_trait; -use crate::{ - prelude::TimestampMillis, - sync::{ - collection::{ - changes::{ApplyChangesRequest, UnchunkedChanges}, - chunks::{ApplyChunkRequest, Chunk}, - graves::{ApplyGravesRequest, Graves}, - meta::{MetaRequest, SyncMeta}, - protocol::{EmptyInput, SyncMethod, SyncProtocol}, - sanity::{SanityCheckRequest, SanityCheckResponse}, - start::StartRequest, - upload::UploadResponse, - }, - error::HttpResult, - http_client::HttpSyncClient, - login::{HostKeyRequest, HostKeyResponse}, - media::{ - begin::{SyncBeginRequest, SyncBeginResponse}, - changes::{MediaChangesRequest, MediaChangesResponse}, - download::DownloadFilesRequest, - protocol::{JsonResult, MediaSyncMethod, MediaSyncProtocol}, - sanity, upload, - }, - request::SyncRequest, - response::SyncResponse, - }, -}; +use crate::prelude::TimestampMillis; +use crate::sync::collection::changes::ApplyChangesRequest; +use crate::sync::collection::changes::UnchunkedChanges; +use crate::sync::collection::chunks::ApplyChunkRequest; +use crate::sync::collection::chunks::Chunk; +use crate::sync::collection::graves::ApplyGravesRequest; +use crate::sync::collection::graves::Graves; +use crate::sync::collection::meta::MetaRequest; +use crate::sync::collection::meta::SyncMeta; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncMethod; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::collection::sanity::SanityCheckRequest; +use crate::sync::collection::sanity::SanityCheckResponse; +use crate::sync::collection::start::StartRequest; +use crate::sync::collection::upload::UploadResponse; +use crate::sync::error::HttpResult; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::login::HostKeyRequest; +use crate::sync::login::HostKeyResponse; +use crate::sync::media::begin::SyncBeginRequest; +use crate::sync::media::begin::SyncBeginResponse; +use crate::sync::media::changes::MediaChangesRequest; +use crate::sync::media::changes::MediaChangesResponse; +use crate::sync::media::download::DownloadFilesRequest; +use crate::sync::media::protocol::JsonResult; +use crate::sync::media::protocol::MediaSyncMethod; +use crate::sync::media::protocol::MediaSyncProtocol; +use crate::sync::media::sanity; +use crate::sync::media::upload; +use crate::sync::request::SyncRequest; +use crate::sync::response::SyncResponse; #[async_trait] impl SyncProtocol for HttpSyncClient { diff --git a/rslib/src/sync/http_server/handlers.rs b/rslib/src/sync/http_server/handlers.rs index 248fb78c6..3fe7dcdfd 100644 --- a/rslib/src/sync/http_server/handlers.rs +++ b/rslib/src/sync/http_server/handlers.rs @@ -4,39 +4,50 @@ use std::sync::Arc; use async_trait::async_trait; -use media::{sanity::MediaSanityCheckResponse, upload::MediaUploadResponse}; +use media::sanity::MediaSanityCheckResponse; +use media::upload::MediaUploadResponse; -use crate::{ - prelude::*, - sync::{ - collection::{ - changes::{server_apply_changes, ApplyChangesRequest, UnchunkedChanges}, - chunks::{server_apply_chunk, server_chunk, ApplyChunkRequest, Chunk}, - download::server_download, - finish::server_finish, - graves::{server_apply_graves, ApplyGravesRequest, Graves}, - meta::{server_meta, MetaRequest, SyncMeta}, - protocol::{EmptyInput, SyncProtocol}, - sanity::{ - server_sanity_check, SanityCheckRequest, SanityCheckResponse, SanityCheckStatus, - }, - start::{server_start, StartRequest}, - upload::{handle_received_upload, UploadResponse}, - }, - error::{HttpResult, OrHttpErr}, - http_server::SimpleServer, - login::{HostKeyRequest, HostKeyResponse}, - media, - media::{ - begin::{SyncBeginRequest, SyncBeginResponse}, - changes::{MediaChangesRequest, MediaChangesResponse}, - download::DownloadFilesRequest, - protocol::{JsonResult, MediaSyncProtocol}, - }, - request::SyncRequest, - response::SyncResponse, - }, -}; +use crate::prelude::*; +use crate::sync::collection::changes::server_apply_changes; +use crate::sync::collection::changes::ApplyChangesRequest; +use crate::sync::collection::changes::UnchunkedChanges; +use crate::sync::collection::chunks::server_apply_chunk; +use crate::sync::collection::chunks::server_chunk; +use crate::sync::collection::chunks::ApplyChunkRequest; +use crate::sync::collection::chunks::Chunk; +use crate::sync::collection::download::server_download; +use crate::sync::collection::finish::server_finish; +use crate::sync::collection::graves::server_apply_graves; +use crate::sync::collection::graves::ApplyGravesRequest; +use crate::sync::collection::graves::Graves; +use crate::sync::collection::meta::server_meta; +use crate::sync::collection::meta::MetaRequest; +use crate::sync::collection::meta::SyncMeta; +use crate::sync::collection::protocol::EmptyInput; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::collection::sanity::server_sanity_check; +use crate::sync::collection::sanity::SanityCheckRequest; +use crate::sync::collection::sanity::SanityCheckResponse; +use crate::sync::collection::sanity::SanityCheckStatus; +use crate::sync::collection::start::server_start; +use crate::sync::collection::start::StartRequest; +use crate::sync::collection::upload::handle_received_upload; +use crate::sync::collection::upload::UploadResponse; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_server::SimpleServer; +use crate::sync::login::HostKeyRequest; +use crate::sync::login::HostKeyResponse; +use crate::sync::media; +use crate::sync::media::begin::SyncBeginRequest; +use crate::sync::media::begin::SyncBeginResponse; +use crate::sync::media::changes::MediaChangesRequest; +use crate::sync::media::changes::MediaChangesResponse; +use crate::sync::media::download::DownloadFilesRequest; +use crate::sync::media::protocol::JsonResult; +use crate::sync::media::protocol::MediaSyncProtocol; +use crate::sync::request::SyncRequest; +use crate::sync::response::SyncResponse; #[async_trait] impl SyncProtocol for Arc { diff --git a/rslib/src/sync/http_server/logging.rs b/rslib/src/sync/http_server/logging.rs index 9100e10ed..05bfb87cb 100644 --- a/rslib/src/sync/http_server/logging.rs +++ b/rslib/src/sync/http_server/logging.rs @@ -3,9 +3,13 @@ use std::time::Duration; -use axum::{body::Body, http::Request, response::Response, Router}; +use axum::body::Body; +use axum::http::Request; +use axum::response::Response; +use axum::Router; use tower_http::trace::TraceLayer; -use tracing::{info_span, Span}; +use tracing::info_span; +use tracing::Span; pub fn with_logging_layer(router: Router) -> Router { router.layer( diff --git a/rslib/src/sync/http_server/media_manager/download.rs b/rslib/src/sync/http_server/media_manager/download.rs index 7e4442bd8..575d3efee 100644 --- a/rslib/src/sync/http_server/media_manager/download.rs +++ b/rslib/src/sync/http_server/media_manager/download.rs @@ -1,18 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs, io::ErrorKind}; +use std::fs; +use std::io::ErrorKind; use snafu::ResultExt; -use crate::{ - error::{FileIoSnafu, FileOp}, - sync::{ - error::{HttpResult, OrHttpErr}, - http_server::media_manager::ServerMediaManager, - media::{database::server::entry::MediaEntry, zip::zip_files_for_download}, - }, -}; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_server::media_manager::ServerMediaManager; +use crate::sync::media::database::server::entry::MediaEntry; +use crate::sync::media::zip::zip_files_for_download; impl ServerMediaManager { pub fn zip_files_for_download(&mut self, files: Vec) -> HttpResult> { diff --git a/rslib/src/sync/http_server/media_manager/mod.rs b/rslib/src/sync/http_server/media_manager/mod.rs index c95e980a3..ca5214a20 100644 --- a/rslib/src/sync/http_server/media_manager/mod.rs +++ b/rslib/src/sync/http_server/media_manager/mod.rs @@ -4,19 +4,16 @@ pub mod download; pub mod upload; -use std::path::{Path, PathBuf}; +use std::path::Path; +use std::path::PathBuf; -use crate::{ - io::create_dir_all, - prelude::*, - sync::{ - error::{HttpResult, OrHttpErr}, - media::{ - changes::MediaChange, database::server::ServerMediaDatabase, - sanity::MediaSanityCheckResponse, - }, - }, -}; +use crate::io::create_dir_all; +use crate::prelude::*; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::media::changes::MediaChange; +use crate::sync::media::database::server::ServerMediaDatabase; +use crate::sync::media::sanity::MediaSanityCheckResponse; pub(crate) struct ServerMediaManager { pub media_folder: PathBuf, diff --git a/rslib/src/sync/http_server/media_manager/upload.rs b/rslib/src/sync/http_server/media_manager/upload.rs index c2e393368..be71070f0 100644 --- a/rslib/src/sync/http_server/media_manager/upload.rs +++ b/rslib/src/sync/http_server/media_manager/upload.rs @@ -1,24 +1,24 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{fs, io::ErrorKind, path::Path}; +use std::fs; +use std::io::ErrorKind; +use std::path::Path; use snafu::ResultExt; use tracing::info; -use crate::{ - error, - error::{FileIoError, FileIoSnafu, FileOp}, - io::write_file, - sync::{ - error::{HttpResult, OrHttpErr}, - http_server::media_manager::ServerMediaManager, - media::{ - database::server::entry::upload::UploadedChangeResult, upload::MediaUploadResponse, - zip::unzip_and_validate_files, - }, - }, -}; +use crate::error; +use crate::error::FileIoError; +use crate::error::FileIoSnafu; +use crate::error::FileOp; +use crate::io::write_file; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_server::media_manager::ServerMediaManager; +use crate::sync::media::database::server::entry::upload::UploadedChangeResult; +use crate::sync::media::upload::MediaUploadResponse; +use crate::sync::media::zip::unzip_and_validate_files; impl ServerMediaManager { pub fn process_uploaded_changes( diff --git a/rslib/src/sync/http_server/mod.rs b/rslib/src/sync/http_server/mod.rs index 21f04a9ac..9e585c3c7 100644 --- a/rslib/src/sync/http_server/mod.rs +++ b/rslib/src/sync/http_server/mod.rs @@ -7,37 +7,40 @@ mod media_manager; mod routes; mod user; -use std::{ - collections::HashMap, - env, - future::Future, - net::{SocketAddr, TcpListener}, - path::{Path, PathBuf}, - pin::Pin, - sync::{Arc, Mutex}, -}; +use std::collections::HashMap; +use std::env; +use std::future::Future; +use std::net::SocketAddr; +use std::net::TcpListener; +use std::path::Path; +use std::path::PathBuf; +use std::pin::Pin; +use std::sync::Arc; +use std::sync::Mutex; -use axum::{extract::DefaultBodyLimit, Router}; -use snafu::{whatever, OptionExt, ResultExt, Whatever}; +use axum::extract::DefaultBodyLimit; +use axum::Router; +use snafu::whatever; +use snafu::OptionExt; +use snafu::ResultExt; +use snafu::Whatever; use tracing::Span; -use crate::{ - error, - io::create_dir_all, - media::files::sha1_of_data, - sync::{ - error::{HttpResult, OrHttpErr}, - http_server::{ - logging::with_logging_layer, - media_manager::ServerMediaManager, - routes::{collection_sync_router, media_sync_router}, - user::User, - }, - login::{HostKeyRequest, HostKeyResponse}, - request::{SyncRequest, MAXIMUM_SYNC_PAYLOAD_BYTES}, - response::SyncResponse, - }, -}; +use crate::error; +use crate::io::create_dir_all; +use crate::media::files::sha1_of_data; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_server::logging::with_logging_layer; +use crate::sync::http_server::media_manager::ServerMediaManager; +use crate::sync::http_server::routes::collection_sync_router; +use crate::sync::http_server::routes::media_sync_router; +use crate::sync::http_server::user::User; +use crate::sync::login::HostKeyRequest; +use crate::sync::login::HostKeyResponse; +use crate::sync::request::SyncRequest; +use crate::sync::request::MAXIMUM_SYNC_PAYLOAD_BYTES; +use crate::sync::response::SyncResponse; pub struct SimpleServer { state: Mutex, diff --git a/rslib/src/sync/http_server/routes.rs b/rslib/src/sync/http_server/routes.rs index 95cfca69c..a8fd90342 100644 --- a/rslib/src/sync/http_server/routes.rs +++ b/rslib/src/sync/http_server/routes.rs @@ -1,23 +1,25 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use axum::{ - extract::{Path, Query, State}, - response::Response, - routing::{get, post}, - Router, -}; +use axum::extract::Path; +use axum::extract::Query; +use axum::extract::State; +use axum::response::Response; +use axum::routing::get; +use axum::routing::post; +use axum::Router; -use crate::sync::{ - collection::protocol::{SyncMethod, SyncProtocol}, - error::{HttpResult, OrHttpErr}, - media::{ - begin::{SyncBeginQuery, SyncBeginRequest}, - protocol::{MediaSyncMethod, MediaSyncProtocol}, - }, - request::{IntoSyncRequest, SyncRequest}, - version::SyncVersion, -}; +use crate::sync::collection::protocol::SyncMethod; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::media::begin::SyncBeginQuery; +use crate::sync::media::begin::SyncBeginRequest; +use crate::sync::media::protocol::MediaSyncMethod; +use crate::sync::media::protocol::MediaSyncProtocol; +use crate::sync::request::IntoSyncRequest; +use crate::sync::request::SyncRequest; +use crate::sync::version::SyncVersion; macro_rules! sync_method { ($server:ident, $req:ident, $method:ident) => {{ @@ -52,8 +54,8 @@ pub fn collection_sync_router() -> Router

{ Router::new().route("/:method", post(sync_handler::

)) } -/// The Rust code used to send a GET with query params, which was inconsistent with the -/// rest of our code - map the request into our standard structure. +/// The Rust code used to send a GET with query params, which was inconsistent +/// with the rest of our code - map the request into our standard structure. async fn media_begin_get( Query(req): Query, server: State

, @@ -69,8 +71,8 @@ async fn media_begin_get( media_begin_post(server, req).await } -/// Older clients would send client info in the multipart instead of the inner JSON; -/// Inject it into the json if provided. +/// Older clients would send client info in the multipart instead of the inner +/// JSON; Inject it into the json if provided. async fn media_begin_post( server: State

, mut req: SyncRequest, diff --git a/rslib/src/sync/http_server/user.rs b/rslib/src/sync/http_server/user.rs index 52e478903..df7ae7596 100644 --- a/rslib/src/sync/http_server/user.rs +++ b/rslib/src/sync/http_server/user.rs @@ -5,15 +5,13 @@ use std::path::PathBuf; use tracing::info; -use crate::{ - collection::{Collection, CollectionBuilder}, - error, - sync::{ - collection::start::ServerSyncState, - error::{HttpResult, OrHttpErr}, - http_server::media_manager::ServerMediaManager, - }, -}; +use crate::collection::Collection; +use crate::collection::CollectionBuilder; +use crate::error; +use crate::sync::collection::start::ServerSyncState; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::http_server::media_manager::ServerMediaManager; pub(in crate::sync) struct User { pub name: String, @@ -34,9 +32,9 @@ impl User { op(self.col.as_mut().unwrap()) } - /// Run op with the existing sync state created by start_new_sync(). If there is no - /// existing state, or the current state's key does not match, abort the request with - /// a conflict. + /// Run op with the existing sync state created by start_new_sync(). If + /// there is no existing state, or the current state's key does not + /// match, abort the request with a conflict. pub(crate) fn with_sync_state(&mut self, skey: &str, op: F) -> HttpResult where F: FnOnce(&mut Collection, &mut ServerSyncState) -> error::Result, @@ -53,9 +51,10 @@ impl User { self.ensure_col_open()?; let state = self.sync_state.as_mut().unwrap(); let col = self.col.as_mut().or_internal_err("open col")?; - // Failures in a sync op are usually caused by referential integrity issues (eg they've sent - // a note without sending its associated notetype). Returning HTTP 400 will inform the client that - // a DB check+full sync is required to fix the issue. + // Failures in a sync op are usually caused by referential integrity issues (eg + // they've sent a note without sending its associated notetype). + // Returning HTTP 400 will inform the client that a DB check+full sync + // is required to fix the issue. op(col, state) .map_err(|e| { self.col = None; diff --git a/rslib/src/sync/login.rs b/rslib/src/sync/login.rs index 7be27c3ba..701604e50 100644 --- a/rslib/src/sync/login.rs +++ b/rslib/src/sync/login.rs @@ -2,14 +2,13 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use reqwest::Url; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; -use crate::{ - prelude::*, - sync::{ - collection::protocol::SyncProtocol, http_client::HttpSyncClient, request::IntoSyncRequest, - }, -}; +use crate::prelude::*; +use crate::sync::collection::protocol::SyncProtocol; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::request::IntoSyncRequest; #[derive(Clone, Default)] pub struct SyncAuth { diff --git a/rslib/src/sync/media/begin.rs b/rslib/src/sync/media/begin.rs index 3cf7913f1..e76492520 100644 --- a/rslib/src/sync/media/begin.rs +++ b/rslib/src/sync/media/begin.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use crate::prelude::*; @@ -27,8 +28,8 @@ pub struct SyncBeginRequest { pub struct SyncBeginResponse { pub usn: Usn, /// The server used to send back a session key used for following requests, - /// but this is no longer required. To avoid breaking older clients, the host - /// key is returned in its place. + /// but this is no longer required. To avoid breaking older clients, the + /// host key is returned in its place. #[serde(rename = "sk")] pub host_key: String, } diff --git a/rslib/src/sync/media/changes.rs b/rslib/src/sync/media/changes.rs index 53a8336a6..ca3c5451c 100644 --- a/rslib/src/sync/media/changes.rs +++ b/rslib/src/sync/media/changes.rs @@ -1,11 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use serde_tuple::Serialize_tuple; use tracing::debug; -use crate::{error, prelude::Usn, sync::media::database::client::MediaDatabase}; +use crate::error; +use crate::prelude::Usn; +use crate::sync::media::database::client::MediaDatabase; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -119,9 +122,9 @@ mod test { #[test] fn required_change() { - use crate::sync::media::changes::{ - determine_required_change as d, LocalState as L, RequiredChange as R, - }; + use crate::sync::media::changes::determine_required_change as d; + use crate::sync::media::changes::LocalState as L; + use crate::sync::media::changes::RequiredChange as R; assert_eq!(d("", "", L::NotInDb), R::None); assert_eq!(d("", "", L::InDbNotPending), R::Delete); assert_eq!(d("", "1", L::InDbAndPending), R::Download); diff --git a/rslib/src/sync/media/database/client/changetracker.rs b/rslib/src/sync/media/database/client/changetracker.rs index 3c2601b12..a67458c28 100644 --- a/rslib/src/sync/media/database/client/changetracker.rs +++ b/rslib/src/sync/media/database/client/changetracker.rs @@ -1,19 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, path::Path, time}; +use std::collections::HashMap; +use std::path::Path; +use std::time; use tracing::debug; -use crate::{ - io::read_dir_files, - media::files::{filename_if_normalized, mtime_as_i64, sha1_of_file, NONSYNCABLE_FILENAME}, - prelude::*, - sync::media::{ - database::client::{MediaDatabase, MediaEntry}, - MAX_INDIVIDUAL_MEDIA_FILE_SIZE, - }, -}; +use crate::io::read_dir_files; +use crate::media::files::filename_if_normalized; +use crate::media::files::mtime_as_i64; +use crate::media::files::sha1_of_file; +use crate::media::files::NONSYNCABLE_FILENAME; +use crate::prelude::*; +use crate::sync::media::database::client::MediaDatabase; +use crate::sync::media::database::client::MediaEntry; +use crate::sync::media::MAX_INDIVIDUAL_MEDIA_FILE_SIZE; struct FilesystemEntry { fname: String, @@ -236,17 +238,20 @@ where #[cfg(test)] mod test { - use std::{fs, path::Path, time, time::Duration}; + use std::fs; + use std::path::Path; + use std::time; + use std::time::Duration; use tempfile::tempdir; use super::*; - use crate::{ - error::Result, - io::{create_dir, write_file}, - media::{files::sha1_of_data, MediaManager}, - sync::media::database::client::MediaEntry, - }; + use crate::error::Result; + use crate::io::create_dir; + use crate::io::write_file; + use crate::media::files::sha1_of_data; + use crate::media::MediaManager; + use crate::sync::media::database::client::MediaEntry; // helper fn change_mtime(p: &Path) { diff --git a/rslib/src/sync/media/database/client/mod.rs b/rslib/src/sync/media/database/client/mod.rs index 2bdcc85f6..3f0174fad 100644 --- a/rslib/src/sync/media/database/client/mod.rs +++ b/rslib/src/sync/media/database/client/mod.rs @@ -1,16 +1,20 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, path::Path}; +use std::collections::HashMap; +use std::path::Path; -use rusqlite::{params, Connection, OptionalExtension, Row}; +use rusqlite::params; +use rusqlite::Connection; +use rusqlite::OptionalExtension; +use rusqlite::Row; use tracing::debug; -use crate::{ - error, - media::{files::AddedFile, Sha1Hash}, - prelude::{Usn, *}, -}; +use crate::error; +use crate::media::files::AddedFile; +use crate::media::Sha1Hash; +use crate::prelude::Usn; +use crate::prelude::*; pub mod changetracker; @@ -319,12 +323,11 @@ fn initial_db_setup(db: &mut Connection) -> error::Result<()> { mod test { use tempfile::TempDir; - use crate::{ - error::Result, - io::new_tempfile, - media::{files::sha1_of_data, MediaManager}, - sync::media::database::client::MediaEntry, - }; + use crate::error::Result; + use crate::io::new_tempfile; + use crate::media::files::sha1_of_data; + use crate::media::MediaManager; + use crate::sync::media::database::client::MediaEntry; #[test] fn database() -> Result<()> { diff --git a/rslib/src/sync/media/database/server/entry/changes.rs b/rslib/src/sync/media/database/server/entry/changes.rs index 4edb6ec50..81991823d 100644 --- a/rslib/src/sync/media/database/server/entry/changes.rs +++ b/rslib/src/sync/media/database/server/entry/changes.rs @@ -3,10 +3,9 @@ use rusqlite::Row; -use crate::{ - prelude::*, - sync::media::{changes::MediaChange, database::server::ServerMediaDatabase}, -}; +use crate::prelude::*; +use crate::sync::media::changes::MediaChange; +use crate::sync::media::database::server::ServerMediaDatabase; impl MediaChange { fn from_row(row: &Row) -> Result { diff --git a/rslib/src/sync/media/database/server/entry/download.rs b/rslib/src/sync/media/database/server/entry/download.rs index 6b3b4e91c..05b8188b6 100644 --- a/rslib/src/sync/media/database/server/entry/download.rs +++ b/rslib/src/sync/media/database/server/entry/download.rs @@ -3,23 +3,21 @@ use rusqlite::params; -use crate::{ - error, - sync::{ - error::{HttpResult, OrHttpErr}, - media::{ - database::server::{entry::MediaEntry, ServerMediaDatabase}, - MAX_MEDIA_FILES_IN_ZIP, MEDIA_SYNC_TARGET_ZIP_BYTES, - }, - }, -}; +use crate::error; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::media::database::server::entry::MediaEntry; +use crate::sync::media::database::server::ServerMediaDatabase; +use crate::sync::media::MAX_MEDIA_FILES_IN_ZIP; +use crate::sync::media::MEDIA_SYNC_TARGET_ZIP_BYTES; impl ServerMediaDatabase { - /// Return a list of entries in the same order as the provided files, truncating - /// the list if the configured total bytes is exceeded. + /// Return a list of entries in the same order as the provided files, + /// truncating the list if the configured total bytes is exceeded. /// - /// If any file entries were missing or deleted, we don't have any way in the current - /// sync protocol to signal that they should be skipped, so we abort with a conflict. + /// If any file entries were missing or deleted, we don't have any way in + /// the current sync protocol to signal that they should be skipped, so + /// we abort with a conflict. pub fn get_entries_for_download(&self, files: &[String]) -> HttpResult> { if files.len() > MAX_MEDIA_FILES_IN_ZIP { None.or_bad_request("too many files requested")?; @@ -41,9 +39,10 @@ impl ServerMediaDatabase { Ok(entries) } - /// Delete provided file from media DB, leaving no record of deletion. It was probably - /// missing due to an interrupted deletion, but removing the entry errs on the side of - /// caution, ensuring the deletion doesn't propagate to other clients. + /// Delete provided file from media DB, leaving no record of deletion. It + /// was probably missing due to an interrupted deletion, but removing + /// the entry errs on the side of caution, ensuring the deletion doesn't + /// propagate to other clients. pub fn forget_missing_file(&mut self, entry: &MediaEntry) -> error::Result<()> { assert!(entry.size > 0); self.with_transaction(|db, meta| { diff --git a/rslib/src/sync/media/database/server/entry/mod.rs b/rslib/src/sync/media/database/server/entry/mod.rs index d2b882f11..f109b58fb 100644 --- a/rslib/src/sync/media/database/server/entry/mod.rs +++ b/rslib/src/sync/media/database/server/entry/mod.rs @@ -3,13 +3,15 @@ use std::mem; -use rusqlite::{params, OptionalExtension, Row}; +use rusqlite::params; +use rusqlite::OptionalExtension; +use rusqlite::Row; -use crate::{ - error, - prelude::{TimestampSecs, Usn}, - sync::media::database::server::{meta::StoreMetadata, ServerMediaDatabase}, -}; +use crate::error; +use crate::prelude::TimestampSecs; +use crate::prelude::Usn; +use crate::sync::media::database::server::meta::StoreMetadata; +use crate::sync::media::database::server::ServerMediaDatabase; pub mod changes; mod download; @@ -30,8 +32,9 @@ impl ServerMediaDatabase { .map_err(Into::into) } - /// Saves entry to the DB, overwriting any existing entry. Does no validation on its own; - /// caller is responsible for mutating meta (which will update mtime as well). + /// Saves entry to the DB, overwriting any existing entry. Does no + /// validation on its own; caller is responsible for mutating meta + /// (which will update mtime as well). pub fn set_entry(&mut self, entry: &mut MediaEntry) -> error::Result<()> { self.db .prepare_cached(include_str!("set_entry.sql"))? diff --git a/rslib/src/sync/media/database/server/entry/upload.rs b/rslib/src/sync/media/database/server/entry/upload.rs index 74d3a0221..73042f424 100644 --- a/rslib/src/sync/media/database/server/entry/upload.rs +++ b/rslib/src/sync/media/database/server/entry/upload.rs @@ -1,13 +1,11 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - error, - sync::media::{ - database::server::{meta::StoreMetadata, ServerMediaDatabase}, - zip::{UploadedChange, UploadedChangeKind}, - }, -}; +use crate::error; +use crate::sync::media::database::server::meta::StoreMetadata; +use crate::sync::media::database::server::ServerMediaDatabase; +use crate::sync::media::zip::UploadedChange; +use crate::sync::media::zip::UploadedChangeKind; pub enum UploadedChangeResult { FileAlreadyDeleted { diff --git a/rslib/src/sync/media/database/server/meta/mod.rs b/rslib/src/sync/media/database/server/meta/mod.rs index 2fc4f5011..0f2e9f973 100644 --- a/rslib/src/sync/media/database/server/meta/mod.rs +++ b/rslib/src/sync/media/database/server/meta/mod.rs @@ -1,13 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use rusqlite::{params, Row}; +use rusqlite::params; +use rusqlite::Row; -use crate::{ - error, - prelude::{TimestampSecs, Usn}, - sync::media::database::server::{entry::MediaEntry, ServerMediaDatabase}, -}; +use crate::error; +use crate::prelude::TimestampSecs; +use crate::prelude::Usn; +use crate::sync::media::database::server::entry::MediaEntry; +use crate::sync::media::database::server::ServerMediaDatabase; #[derive(Debug, PartialEq, Eq)] pub struct StoreMetadata { @@ -61,8 +62,9 @@ impl StoreMetadata { } impl ServerMediaDatabase { - /// Perform an exclusive transaction. Will implicitly commit if no error returned, - /// after flushing the updated metadata. Returns the latest usn. + /// Perform an exclusive transaction. Will implicitly commit if no error + /// returned, after flushing the updated metadata. Returns the latest + /// usn. pub fn with_transaction(&mut self, op: F) -> error::Result where F: FnOnce(&mut Self, &mut StoreMetadata) -> error::Result<()>, diff --git a/rslib/src/sync/media/download.rs b/rslib/src/sync/media/download.rs index 20d57c654..345f39907 100644 --- a/rslib/src/sync/media/download.rs +++ b/rslib/src/sync/media/download.rs @@ -1,15 +1,19 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashMap, io, io::Read, path::Path}; +use std::collections::HashMap; +use std::io; +use std::io::Read; +use std::path::Path; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use serde::Serialize; -use crate::{ - error, - error::{AnkiError, SyncErrorKind}, - media::files::{add_file_from_ankiweb, AddedFile}, -}; +use crate::error; +use crate::error::AnkiError; +use crate::error::SyncErrorKind; +use crate::media::files::add_file_from_ankiweb; +use crate::media::files::AddedFile; #[derive(Debug, Serialize, Deserialize)] pub struct DownloadFilesRequest { diff --git a/rslib/src/sync/media/protocol.rs b/rslib/src/sync/media/protocol.rs index 70806d260..a9733ceb9 100644 --- a/rslib/src/sync/media/protocol.rs +++ b/rslib/src/sync/media/protocol.rs @@ -4,26 +4,24 @@ use async_trait::async_trait; use reqwest::Url; use serde::de::DeserializeOwned; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use strum::IntoStaticStr; -use crate::{ - error, - error::AnkiError, - sync::{ - collection::protocol::AsSyncEndpoint, - error::HttpResult, - media::{ - begin::{SyncBeginRequest, SyncBeginResponse}, - changes::{MediaChangesRequest, MediaChangesResponse}, - download::DownloadFilesRequest, - sanity::{MediaSanityCheckResponse, SanityCheckRequest}, - upload::MediaUploadResponse, - }, - request::SyncRequest, - response::SyncResponse, - }, -}; +use crate::error; +use crate::error::AnkiError; +use crate::sync::collection::protocol::AsSyncEndpoint; +use crate::sync::error::HttpResult; +use crate::sync::media::begin::SyncBeginRequest; +use crate::sync::media::begin::SyncBeginResponse; +use crate::sync::media::changes::MediaChangesRequest; +use crate::sync::media::changes::MediaChangesResponse; +use crate::sync::media::download::DownloadFilesRequest; +use crate::sync::media::sanity::MediaSanityCheckResponse; +use crate::sync::media::sanity::SanityCheckRequest; +use crate::sync::media::upload::MediaUploadResponse; +use crate::sync::request::SyncRequest; +use crate::sync::response::SyncResponse; #[derive(IntoStaticStr, Deserialize, PartialEq, Eq, Debug)] #[serde(rename_all = "camelCase")] diff --git a/rslib/src/sync/media/sanity.rs b/rslib/src/sync/media/sanity.rs index dda940750..ee6fe0b3c 100644 --- a/rslib/src/sync/media/sanity.rs +++ b/rslib/src/sync/media/sanity.rs @@ -1,7 +1,8 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; #[derive(Serialize, Deserialize)] pub struct SanityCheckRequest { diff --git a/rslib/src/sync/media/syncer.rs b/rslib/src/sync/media/syncer.rs index 26d860688..24d849132 100644 --- a/rslib/src/sync/media/syncer.rs +++ b/rslib/src/sync/media/syncer.rs @@ -4,30 +4,31 @@ use tracing::debug; use version::sync_client_version; -use crate::{ - error::{AnkiError, Result, SyncErrorKind}, - media::{files::mtime_as_i64, MediaManager}, - prelude::*, - sync::{ - http_client::HttpSyncClient, - media::{ - begin::{SyncBeginRequest, SyncBeginResponse}, - changes, - changes::MediaChangesRequest, - database::client::{changetracker::ChangeTracker, MediaDatabaseMetadata, MediaEntry}, - download, - download::DownloadFilesRequest, - progress::MediaSyncProgress, - protocol::MediaSyncProtocol, - sanity::{MediaSanityCheckResponse, SanityCheckRequest}, - upload::gather_zip_data_for_upload, - zip::zip_files_for_upload, - MAX_MEDIA_FILES_IN_ZIP, - }, - request::IntoSyncRequest, - }, - version, -}; +use crate::error::AnkiError; +use crate::error::Result; +use crate::error::SyncErrorKind; +use crate::media::files::mtime_as_i64; +use crate::media::MediaManager; +use crate::prelude::*; +use crate::sync::http_client::HttpSyncClient; +use crate::sync::media::begin::SyncBeginRequest; +use crate::sync::media::begin::SyncBeginResponse; +use crate::sync::media::changes; +use crate::sync::media::changes::MediaChangesRequest; +use crate::sync::media::database::client::changetracker::ChangeTracker; +use crate::sync::media::database::client::MediaDatabaseMetadata; +use crate::sync::media::database::client::MediaEntry; +use crate::sync::media::download; +use crate::sync::media::download::DownloadFilesRequest; +use crate::sync::media::progress::MediaSyncProgress; +use crate::sync::media::protocol::MediaSyncProtocol; +use crate::sync::media::sanity::MediaSanityCheckResponse; +use crate::sync::media::sanity::SanityCheckRequest; +use crate::sync::media::upload::gather_zip_data_for_upload; +use crate::sync::media::zip::zip_files_for_upload; +use crate::sync::media::MAX_MEDIA_FILES_IN_ZIP; +use crate::sync::request::IntoSyncRequest; +use crate::version; pub struct MediaSyncer

where diff --git a/rslib/src/sync/media/tests.rs b/rslib/src/sync/media/tests.rs index c68bbecd8..06a9bff65 100644 --- a/rslib/src/sync/media/tests.rs +++ b/rslib/src/sync/media/tests.rs @@ -3,33 +3,34 @@ #![cfg(test)] -use std::{fs, net::IpAddr, thread::sleep, time::Duration}; +use std::fs; +use std::net::IpAddr; +use std::thread::sleep; +use std::time::Duration; use nom::AsBytes; -use reqwest::{multipart, Client}; +use reqwest::multipart; +use reqwest::Client; -use crate::{ - error::Result, - media::MediaManager, - prelude::AnkiError, - sync::{ - collection::{ - protocol::AsSyncEndpoint, - tests::{with_active_server, SyncTestContext}, - }, - media::{ - begin::{SyncBeginQuery, SyncBeginRequest}, - progress::MediaSyncProgress, - protocol::{MediaSyncMethod, MediaSyncProtocol}, - sanity::{MediaSanityCheckResponse, SanityCheckRequest}, - syncer::MediaSyncer, - zip::zip_files_for_upload, - }, - request::{IntoSyncRequest, SyncRequest}, - version::SyncVersion, - }, - version::sync_client_version, -}; +use crate::error::Result; +use crate::media::MediaManager; +use crate::prelude::AnkiError; +use crate::sync::collection::protocol::AsSyncEndpoint; +use crate::sync::collection::tests::with_active_server; +use crate::sync::collection::tests::SyncTestContext; +use crate::sync::media::begin::SyncBeginQuery; +use crate::sync::media::begin::SyncBeginRequest; +use crate::sync::media::progress::MediaSyncProgress; +use crate::sync::media::protocol::MediaSyncMethod; +use crate::sync::media::protocol::MediaSyncProtocol; +use crate::sync::media::sanity::MediaSanityCheckResponse; +use crate::sync::media::sanity::SanityCheckRequest; +use crate::sync::media::syncer::MediaSyncer; +use crate::sync::media::zip::zip_files_for_upload; +use crate::sync::request::IntoSyncRequest; +use crate::sync::request::SyncRequest; +use crate::sync::version::SyncVersion; +use crate::version::sync_client_version; /// Older Rust versions sent hkey/version in GET query string. #[tokio::test] @@ -51,8 +52,8 @@ async fn begin_supports_get() -> Result<()> { .await } -/// Older clients used a `v` variable in the begin multipart instead of placing the -/// version in the JSON payload. +/// Older clients used a `v` variable in the begin multipart instead of placing +/// the version in the JSON payload. #[tokio::test] async fn begin_supports_version_in_form() -> Result<()> { with_active_server(|client_| async move { @@ -159,9 +160,9 @@ impl SyncTestContext { } /// As local change detection depends on a millisecond timestamp, - /// we need to wait a little while between steps to ensure changes are observed. Theoretically - /// 1ms should suffice, but I was seeing flaky tests on a ZFS system with the delay set to a - /// few milliseconds. + /// we need to wait a little while between steps to ensure changes are + /// observed. Theoretically 1ms should suffice, but I was seeing flaky + /// tests on a ZFS system with the delay set to a few milliseconds. fn sleep(&self) { sleep(Duration::from_millis(10)) } @@ -227,8 +228,8 @@ async fn parallel_requests() -> Result<()> { media2.add_file("auto", b"auto").unwrap(); ctx.sync_media1().await?; // Normally the second client would notice the addition of the file when - // fetching changes from the server; here we manually upload the change to simulate - // two parallel syncs going on. + // fetching changes from the server; here we manually upload the change to + // simulate two parallel syncs going on. let get_usn = || async { Ok::<_, AnkiError>( ctx.client diff --git a/rslib/src/sync/media/upload.rs b/rslib/src/sync/media/upload.rs index f00ec502e..499a2c066 100644 --- a/rslib/src/sync/media/upload.rs +++ b/rslib/src/sync/media/upload.rs @@ -1,27 +1,27 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, path::Path}; +use std::borrow::Cow; +use std::path::Path; use serde_derive::Deserialize; use serde_tuple::Serialize_tuple; use tracing::debug; -use crate::{ - media::files::{data_for_file, normalize_filename}, - prelude::*, - sync::media::{ - database::client::{MediaDatabase, MediaEntry}, - MAX_INDIVIDUAL_MEDIA_FILE_SIZE, MEDIA_SYNC_TARGET_ZIP_BYTES, - }, -}; +use crate::media::files::data_for_file; +use crate::media::files::normalize_filename; +use crate::prelude::*; +use crate::sync::media::database::client::MediaDatabase; +use crate::sync::media::database::client::MediaEntry; +use crate::sync::media::MAX_INDIVIDUAL_MEDIA_FILE_SIZE; +use crate::sync::media::MEDIA_SYNC_TARGET_ZIP_BYTES; #[derive(Serialize_tuple, Deserialize, Debug)] pub struct MediaUploadResponse { - /// Always equal to number of uploaded files now. Old AnkiWeb versions used to - /// terminate processing early if too much time had elapsed, so older clients - /// will upload the same material again if this is less than the count they - /// uploaded. + /// Always equal to number of uploaded files now. Old AnkiWeb versions used + /// to terminate processing early if too much time had elapsed, so older + /// clients will upload the same material again if this is less than the + /// count they uploaded. pub processed: usize, pub current_usn: Usn, } @@ -31,7 +31,8 @@ type ZipDataForUpload = Vec<(String, Option>)>; /// Gather [(filename, data)] for provided entries, up to configured limit. /// Data is None if file is deleted. -/// Returns None if one or more of the entries were inaccessible or in the wrong format. +/// Returns None if one or more of the entries were inaccessible or in the wrong +/// format. pub fn gather_zip_data_for_upload( ctx: &MediaDatabase, media_folder: &Path, diff --git a/rslib/src/sync/media/zip.rs b/rslib/src/sync/media/zip.rs index 064137bf4..0ad558d2d 100644 --- a/rslib/src/sync/media/zip.rs +++ b/rslib/src/sync/media/zip.rs @@ -1,22 +1,21 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - collections::HashMap, - io, - io::{Read, Write}, -}; +use std::collections::HashMap; +use std::io; +use std::io::Read; +use std::io::Write; use serde::Deserialize; use serde_tuple::Serialize_tuple; use unicode_normalization::is_nfc; -use zip::{self, write::FileOptions, ZipWriter}; +use zip::write::FileOptions; +use zip::ZipWriter; -use crate::{ - media::files::sha1_of_data, - prelude::*, - sync::media::{MAX_INDIVIDUAL_MEDIA_FILE_SIZE, MAX_MEDIA_FILENAME_LENGTH_SERVER}, -}; +use crate::media::files::sha1_of_data; +use crate::prelude::*; +use crate::sync::media::MAX_INDIVIDUAL_MEDIA_FILE_SIZE; +use crate::sync::media::MAX_MEDIA_FILENAME_LENGTH_SERVER; pub struct ZipFileMetadata { pub filename: String, @@ -25,8 +24,8 @@ pub struct ZipFileMetadata { } /// Write provided `[(filename, data)]` into a zip file, returning its data. -/// The metadata is in a different format to the upload case, since deletions don't need -/// to be represented. +/// The metadata is in a different format to the upload case, since deletions +/// don't need to be represented. pub fn zip_files_for_download(files: Vec<(String, Vec)>) -> Result> { let options = FileOptions::default().compression_method(zip::CompressionMethod::Stored); let mut zip = ZipWriter::new(io::Cursor::new(vec![])); diff --git a/rslib/src/sync/request/header_and_stream.rs b/rslib/src/sync/request/header_and_stream.rs index 2de54cb30..c36356b25 100644 --- a/rslib/src/sync/request/header_and_stream.rs +++ b/rslib/src/sync/request/header_and_stream.rs @@ -1,30 +1,32 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - fmt::Display, - io::{Cursor, ErrorKind}, - marker::PhantomData, - net::IpAddr, -}; +use std::fmt::Display; +use std::io::Cursor; +use std::io::ErrorKind; +use std::marker::PhantomData; +use std::net::IpAddr; -use axum::{ - extract::BodyStream, - headers::{Header, HeaderName, HeaderValue}, - http::StatusCode, -}; +use axum::extract::BodyStream; +use axum::headers::Header; +use axum::headers::HeaderName; +use axum::headers::HeaderValue; +use axum::http::StatusCode; use bytes::Bytes; -use futures::{Stream, TryStreamExt}; +use futures::Stream; +use futures::TryStreamExt; use serde::de::DeserializeOwned; -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; use tokio::io::AsyncReadExt; use tokio_util::io::ReaderStream; -use crate::sync::{ - error::{HttpResult, HttpSnafu, OrHttpErr}, - request::{SyncRequest, MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED}, - version::SyncVersion, -}; +use crate::sync::error::HttpResult; +use crate::sync::error::HttpSnafu; +use crate::sync::error::OrHttpErr; +use crate::sync::request::SyncRequest; +use crate::sync::request::MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED; +use crate::sync::version::SyncVersion; impl SyncRequest { pub(super) async fn from_header_and_stream( diff --git a/rslib/src/sync/request/mod.rs b/rslib/src/sync/request/mod.rs index b6f0c7a37..acc56eead 100644 --- a/rslib/src/sync/request/mod.rs +++ b/rslib/src/sync/request/mod.rs @@ -4,29 +4,32 @@ pub mod header_and_stream; mod multipart; -use std::{any::Any, env, marker::PhantomData, net::IpAddr}; +use std::any::Any; +use std::env; +use std::marker::PhantomData; +use std::net::IpAddr; use async_trait::async_trait; -use axum::{ - extract::{BodyStream, FromRequest, Multipart}, - http::Request, - RequestPartsExt, TypedHeader, -}; +use axum::extract::BodyStream; +use axum::extract::FromRequest; +use axum::extract::Multipart; +use axum::http::Request; +use axum::RequestPartsExt; +use axum::TypedHeader; use axum_client_ip::ClientIp; use header_and_stream::SyncHeader; use hyper::Body; use once_cell::sync::Lazy; -use serde::{de::DeserializeOwned, Serialize}; +use serde::de::DeserializeOwned; +use serde::Serialize; use serde_json::Error; use tracing::Span; -use crate::{ - sync::{ - error::{HttpError, HttpResult, OrHttpErr}, - version::SyncVersion, - }, - version::sync_client_version_short, -}; +use crate::sync::error::HttpError; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::version::SyncVersion; +use crate::version::sync_client_version_short; /// Stores the bytes of a sync request, the associated type they /// represent, and authentication info provided in headers/multipart @@ -42,8 +45,8 @@ pub struct SyncRequest { pub ip: IpAddr, /// Non-empty on every non-login request. pub sync_key: String, - /// May not be set on some requests by legacy clients. Used by stateful sync methods to check - /// for concurrent access. + /// May not be set on some requests by legacy clients. Used by stateful sync + /// methods to check for concurrent access. pub session_key: String, /// Set by legacy clients when posting to msync/begin pub media_client_version: Option, @@ -148,8 +151,8 @@ where where Self: Sized + 'static, { - // A not-very-elegant workaround for the fact that a separate impl for vec would - // conflict with this generic one. + // A not-very-elegant workaround for the fact that a separate impl for vec + // would conflict with this generic one. let is_data = (&self as &dyn Any).is::>(); let data = if is_data { let boxed_self = (Box::new(self) as Box) @@ -180,8 +183,8 @@ pub static MAXIMUM_SYNC_PAYLOAD_BYTES: Lazy = Lazy::new(|| { * 1024 * 1024 }); -/// Client ignores this when a non-AnkiWeb endpoint is configured. Controls the maximum -/// size of a payload after decompression, which effectively limits the how large a collection -/// file can be uploaded. +/// Client ignores this when a non-AnkiWeb endpoint is configured. Controls the +/// maximum size of a payload after decompression, which effectively limits the +/// how large a collection file can be uploaded. pub static MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED: Lazy = Lazy::new(|| (*MAXIMUM_SYNC_PAYLOAD_BYTES * 3) as u64); diff --git a/rslib/src/sync/request/multipart.rs b/rslib/src/sync/request/multipart.rs index 85babee8a..842a94a88 100644 --- a/rslib/src/sync/request/multipart.rs +++ b/rslib/src/sync/request/multipart.rs @@ -1,18 +1,22 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{io::Read, marker::PhantomData, net::IpAddr}; +use std::io::Read; +use std::marker::PhantomData; +use std::net::IpAddr; use axum::extract::Multipart; -use bytes::{Buf, Bytes}; +use bytes::Buf; +use bytes::Bytes; use flate2::read::GzDecoder; use tokio::task::spawn_blocking; -use crate::sync::{ - error::{HttpResult, OrHttpErr}, - request::{SyncRequest, MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED}, - version::{SyncVersion, SYNC_VERSION_10_V2_TIMEZONE}, -}; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::request::SyncRequest; +use crate::sync::request::MAXIMUM_SYNC_PAYLOAD_BYTES_UNCOMPRESSED; +use crate::sync::version::SyncVersion; +use crate::sync::version::SYNC_VERSION_10_V2_TIMEZONE; impl SyncRequest { pub(super) async fn from_multipart( diff --git a/rslib/src/sync/response.rs b/rslib/src/sync/response.rs index d00f3e2a9..09c51b3d8 100644 --- a/rslib/src/sync/response.rs +++ b/rslib/src/sync/response.rs @@ -3,22 +3,19 @@ use std::marker::PhantomData; -use axum::{ - body::StreamBody, - headers::HeaderName, - response::{IntoResponse, Response}, -}; -use serde::{de::DeserializeOwned, Serialize}; +use axum::body::StreamBody; +use axum::headers::HeaderName; +use axum::response::IntoResponse; +use axum::response::Response; +use serde::de::DeserializeOwned; +use serde::Serialize; -use crate::{ - prelude::*, - sync::{ - collection::upload::UploadResponse, - error::{HttpResult, OrHttpErr}, - request::header_and_stream::encode_zstd_body, - version::SyncVersion, - }, -}; +use crate::prelude::*; +use crate::sync::collection::upload::UploadResponse; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; +use crate::sync::request::header_and_stream::encode_zstd_body; +use crate::sync::version::SyncVersion; pub static ORIGINAL_SIZE: HeaderName = HeaderName::from_static("anki-original-size"); diff --git a/rslib/src/sync/version.rs b/rslib/src/sync/version.rs index a7c6ad5b7..38842f993 100644 --- a/rslib/src/sync/version.rs +++ b/rslib/src/sync/version.rs @@ -1,26 +1,26 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use serde_derive::{Deserialize, Serialize}; +use serde_derive::Deserialize; +use serde_derive::Serialize; -use crate::{ - storage::SchemaVersion, - sync::error::{HttpResult, OrHttpErr}, -}; +use crate::storage::SchemaVersion; +use crate::sync::error::HttpResult; +use crate::sync::error::OrHttpErr; pub const SYNC_VERSION_MIN: u8 = SYNC_VERSION_08_SESSIONKEY; pub const SYNC_VERSION_MAX: u8 = SYNC_VERSION_11_DIRECT_POST; -/// Added in 2013. Introduced a session key to identify parallel attempts at syncing. -/// At the end of 2022, only used by 0.045% of syncers. Half are AnkiUniversal users, -/// as it never added support for the V2 scheduler. +/// Added in 2013. Introduced a session key to identify parallel attempts at +/// syncing. At the end of 2022, only used by 0.045% of syncers. Half are +/// AnkiUniversal users, as it never added support for the V2 scheduler. pub const SYNC_VERSION_08_SESSIONKEY: u8 = 8; /// Added Jan 2018. No functional changes to protocol, but marks that the client /// supports the V2 scheduler. /// -/// In July 2018 a separate chunked graves method was added, but was optional. At -/// the end of 2022, AnkiDroid is still using the old approach of passing all +/// In July 2018 a separate chunked graves method was added, but was optional. +/// At the end of 2022, AnkiDroid is still using the old approach of passing all /// graves to the start method in the legacy schema path. pub const SYNC_VERSION_09_V2_SCHEDULER: u8 = 9; diff --git a/rslib/src/tags/bulkadd.rs b/rslib/src/tags/bulkadd.rs index acc7b0ea6..80c87ad28 100644 --- a/rslib/src/tags/bulkadd.rs +++ b/rslib/src/tags/bulkadd.rs @@ -7,8 +7,10 @@ use std::collections::HashSet; use unicase::UniCase; -use super::{join_tags, split_tags}; -use crate::{notes::NoteTags, prelude::*}; +use super::join_tags; +use super::split_tags; +use crate::notes::NoteTags; +use crate::prelude::*; impl Collection { pub fn add_tags_to_notes(&mut self, nids: &[NoteId], tags: &str) -> Result> { diff --git a/rslib/src/tags/findreplace.rs b/rslib/src/tags/findreplace.rs index a11e35ce8..1f5d7e2ee 100644 --- a/rslib/src/tags/findreplace.rs +++ b/rslib/src/tags/findreplace.rs @@ -3,10 +3,15 @@ use std::borrow::Cow; -use regex::{NoExpand, Regex, Replacer}; +use regex::NoExpand; +use regex::Regex; +use regex::Replacer; -use super::{is_tag_separator, join_tags, split_tags}; -use crate::{notes::NoteTags, prelude::*}; +use super::is_tag_separator; +use super::join_tags; +use super::split_tags; +use crate::notes::NoteTags; +use crate::prelude::*; impl Collection { /// Replace occurrences of a search with a new value in tags. @@ -96,7 +101,8 @@ where #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, decks::DeckId}; + use crate::collection::open_test_collection; + use crate::decks::DeckId; #[test] fn find_replace() -> Result<()> { diff --git a/rslib/src/tags/matcher.rs b/rslib/src/tags/matcher.rs index 3f7ded47e..b4961015e 100644 --- a/rslib/src/tags/matcher.rs +++ b/rslib/src/tags/matcher.rs @@ -1,11 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashSet}; +use std::borrow::Cow; +use std::collections::HashSet; -use regex::{Captures, Regex}; +use regex::Captures; +use regex::Regex; -use super::{join_tags, split_tags}; +use super::join_tags; +use super::split_tags; use crate::prelude::*; pub(crate) struct TagMatcher { regex: Regex, @@ -77,7 +80,8 @@ impl TagMatcher { join_tags(tags.as_slice()) } - /// The `replacement` function should return the text to use as a replacement. + /// The `replacement` function should return the text to use as a + /// replacement. pub fn replace_with_fn(&mut self, space_separated_tags: &str, replacer: F) -> String where F: Fn(&str) -> String, diff --git a/rslib/src/tags/notes.rs b/rslib/src/tags/notes.rs index bfd74a4e6..9d24356e9 100644 --- a/rslib/src/tags/notes.rs +++ b/rslib/src/tags/notes.rs @@ -6,7 +6,8 @@ use std::collections::HashSet; use unicase::UniCase; use super::split_tags; -use crate::{prelude::*, search::SearchNode}; +use crate::prelude::*; +use crate::search::SearchNode; impl Collection { pub(crate) fn all_tags_in_deck(&mut self, deck_id: DeckId) -> Result>> { @@ -17,8 +18,9 @@ impl Collection { .storage .for_each_note_tag_in_searched_notes(|tags| { for tag in split_tags(tags) { - // A benchmark on a large deck indicates that nothing is gained by using a Cow and skipping - // an allocation in the duplicate case, and this approach is simpler. + // A benchmark on a large deck indicates that nothing is gained by using a Cow + // and skipping an allocation in the duplicate case, and + // this approach is simpler. all_tags.insert(UniCase::new(tag.to_string())); } })?; diff --git a/rslib/src/tags/register.rs b/rslib/src/tags/register.rs index 3c576e70f..bfb1fbc80 100644 --- a/rslib/src/tags/register.rs +++ b/rslib/src/tags/register.rs @@ -1,12 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{borrow::Cow, collections::HashSet}; +use std::borrow::Cow; +use std::collections::HashSet; use unicase::UniCase; -use super::{immediate_parent_name_str, is_tag_separator, split_tags, Tag}; -use crate::{prelude::*, text::normalize_to_nfc, types::Usn}; +use super::immediate_parent_name_str; +use super::is_tag_separator; +use super::split_tags; +use super::Tag; +use crate::prelude::*; +use crate::text::normalize_to_nfc; +use crate::types::Usn; impl Collection { /// Given a list of tags, fix case, ordering and duplicates. @@ -82,10 +88,10 @@ impl Collection { Ok(out_tags) } - /// Adjust tag casing to match any existing parents, and register it if it's not already - /// in the tags list. True if the tag was added and not already in tag list. - /// In the case the tag is already registered, tag will be mutated to match the existing - /// name. + /// Adjust tag casing to match any existing parents, and register it if it's + /// not already in the tags list. True if the tag was added and not + /// already in tag list. In the case the tag is already registered, tag + /// will be mutated to match the existing name. pub(crate) fn register_tag(&mut self, tag: &mut Tag) -> Result { let is_new = self.prepare_tag_for_registering(tag)?; if is_new { @@ -94,8 +100,8 @@ impl Collection { Ok(is_new) } - /// Create a tag object, normalize text, and match parents/existing case if available. - /// True if tag is new. + /// Create a tag object, normalize text, and match parents/existing case if + /// available. True if tag is new. pub(super) fn prepare_tag_for_registering(&self, tag: &mut Tag) -> Result { let normalized_name = normalize_tag_name(&tag.name)?; if let Some(existing_tag) = self.storage.get_tag(&normalized_name)? { @@ -189,7 +195,8 @@ pub(super) fn normalize_tag_name(name: &str) -> Result> { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, decks::DeckId}; + use crate::collection::open_test_collection; + use crate::decks::DeckId; #[test] fn tags() -> Result<()> { diff --git a/rslib/src/tags/remove.rs b/rslib/src/tags/remove.rs index d43b401d7..edfd6ea8c 100644 --- a/rslib/src/tags/remove.rs +++ b/rslib/src/tags/remove.rs @@ -5,7 +5,8 @@ use super::matcher::TagMatcher; use crate::prelude::*; impl Collection { - /// Take tags as a whitespace-separated string and remove them from all notes and the tag list. + /// Take tags as a whitespace-separated string and remove them from all + /// notes and the tag list. pub fn remove_tags(&mut self, tags: &str) -> Result> { self.transact(Op::RemoveTag, |col| col.remove_tags_inner(tags)) } @@ -96,7 +97,8 @@ impl Collection { #[cfg(test)] mod test { use super::*; - use crate::{collection::open_test_collection, tags::Tag}; + use crate::collection::open_test_collection; + use crate::tags::Tag; #[test] fn clearing() -> Result<()> { diff --git a/rslib/src/tags/rename.rs b/rslib/src/tags/rename.rs index fed028c18..d37f78af9 100644 --- a/rslib/src/tags/rename.rs +++ b/rslib/src/tags/rename.rs @@ -1,12 +1,14 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use super::{is_tag_separator, matcher::TagMatcher}; -use crate::{prelude::*, tags::register::normalize_tag_name}; +use super::is_tag_separator; +use super::matcher::TagMatcher; +use crate::prelude::*; +use crate::tags::register::normalize_tag_name; impl Collection { - /// Rename a given tag and its children on all notes that reference it, returning changed - /// note count. + /// Rename a given tag and its children on all notes that reference it, + /// returning changed note count. pub fn rename_tag(&mut self, old_prefix: &str, new_prefix: &str) -> Result> { self.transact(Op::RenameTag, |col| { col.rename_tag_inner(old_prefix, new_prefix) diff --git a/rslib/src/tags/reparent.rs b/rslib/src/tags/reparent.rs index 5512bed7a..960fbd0ab 100644 --- a/rslib/src/tags/reparent.rs +++ b/rslib/src/tags/reparent.rs @@ -3,7 +3,8 @@ use std::collections::HashMap; -use super::{join_tags, matcher::TagMatcher}; +use super::join_tags; +use super::matcher::TagMatcher; use crate::prelude::*; impl Collection { diff --git a/rslib/src/tags/tree.rs b/rslib/src/tags/tree.rs index 0dc4b5a0a..7f68b9671 100644 --- a/rslib/src/tags/tree.rs +++ b/rslib/src/tags/tree.rs @@ -1,12 +1,15 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{collections::HashSet, iter::Peekable}; +use std::collections::HashSet; +use std::iter::Peekable; use unicase::UniCase; -use super::{immediate_parent_name_unicase, Tag}; -use crate::{pb::tags::TagTreeNode, prelude::*}; +use super::immediate_parent_name_unicase; +use super::Tag; +use crate::pb::tags::TagTreeNode; +use crate::prelude::*; impl Collection { pub fn tag_tree(&mut self) -> Result { diff --git a/rslib/src/tags/undo.rs b/rslib/src/tags/undo.rs index 98f431da1..7a7e26d6b 100644 --- a/rslib/src/tags/undo.rs +++ b/rslib/src/tags/undo.rs @@ -39,8 +39,9 @@ impl Collection { self.storage.register_tag(tag) } - /// Remove a single tag from the tag list, saving an undo entry. Does not alter notes. - /// FIXME: caller will need to update usn when we make tags incrementally syncable. + /// Remove a single tag from the tag list, saving an undo entry. Does not + /// alter notes. FIXME: caller will need to update usn when we make tags + /// incrementally syncable. pub(super) fn remove_single_tag_undoable(&mut self, tag: Tag) -> Result<()> { self.storage.remove_single_tag(&tag.name)?; self.save_undo(UndoableTagChange::Removed(Box::new(tag))); diff --git a/rslib/src/template.rs b/rslib/src/template.rs index e422cb043..a3acfa300 100644 --- a/rslib/src/template.rs +++ b/rslib/src/template.rs @@ -1,28 +1,28 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use std::{ - borrow::Cow, - collections::{HashMap, HashSet}, - fmt::Write, - iter, -}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::collections::HashSet; +use std::fmt::Write; +use std::iter; use lazy_static::lazy_static; -use nom::{ - branch::alt, - bytes::complete::{tag, take_until}, - combinator::{map, rest, verify}, - sequence::delimited, -}; +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::bytes::complete::take_until; +use nom::combinator::map; +use nom::combinator::rest; +use nom::combinator::verify; +use nom::sequence::delimited; use regex::Regex; -use crate::{ - cloze::add_cloze_numbers_in_string, - error::{AnkiError, Result, TemplateError}, - i18n::I18n, - template_filters::apply_filters, -}; +use crate::cloze::add_cloze_numbers_in_string; +use crate::error::AnkiError; +use crate::error::Result; +use crate::error::TemplateError; +use crate::i18n::I18n; +use crate::template_filters::apply_filters; pub type FieldMap<'a> = HashMap<&'a str, u16>; type TemplateResult = std::result::Result; @@ -326,9 +326,9 @@ impl ParsedTemplate { } } -/// If check_negated is false, negated conditionals resolve to their children, even -/// if the referenced key is non-empty. This allows the legacy required field cache to -/// generate results closer to older Anki versions. +/// If check_negated is false, negated conditionals resolve to their children, +/// even if the referenced key is non-empty. This allows the legacy required +/// field cache to generate results closer to older Anki versions. fn template_is_empty( nonempty_fields: &HashSet<&str>, nodes: &[ParsedNode], @@ -685,8 +685,8 @@ impl ParsedTemplate { //---------------------------------------- impl ParsedTemplate { - /// Given a map of old to new field names, update references to the new names. - /// Returns true if any changes made. + /// Given a map of old to new field names, update references to the new + /// names. Returns true if any changes made. pub(crate) fn rename_and_remove_fields(&mut self, fields: &HashMap>) { let old_nodes = std::mem::take(&mut self.0); self.0 = rename_and_remove_fields(old_nodes, fields); @@ -846,12 +846,15 @@ fn is_cloze_conditional(key: &str) -> bool { mod test { use std::collections::HashMap; - use super::{FieldMap, ParsedNode::*, ParsedTemplate as PT}; - use crate::{ - error::TemplateError, - i18n::I18n, - template::{field_is_empty, nonempty_fields, FieldRequirements, RenderContext}, - }; + use super::FieldMap; + use super::ParsedNode::*; + use super::ParsedTemplate as PT; + use crate::error::TemplateError; + use crate::i18n::I18n; + use crate::template::field_is_empty; + use crate::template::nonempty_fields; + use crate::template::FieldRequirements; + use crate::template::RenderContext; #[test] fn field_empty() { diff --git a/rslib/src/template_filters.rs b/rslib/src/template_filters.rs index ddd8814ed..44e9e50d6 100644 --- a/rslib/src/template_filters.rs +++ b/rslib/src/template_filters.rs @@ -5,18 +5,19 @@ use std::borrow::Cow; use blake3::Hasher; use lazy_static::lazy_static; -use regex::{Captures, Regex}; +use regex::Captures; +use regex::Regex; -use crate::{ - cloze::{cloze_filter, cloze_only_filter}, - template::RenderContext, - text::strip_html, -}; +use crate::cloze::cloze_filter; +use crate::cloze::cloze_only_filter; +use crate::template::RenderContext; +use crate::text::strip_html; // Filtering //---------------------------------------- -/// Applies built in filters, returning the resulting text and remaining filters. +/// Applies built in filters, returning the resulting text and remaining +/// filters. /// /// The first non-standard filter that is encountered will terminate processing, /// so non-standard filters must come at the end. diff --git a/rslib/src/tests.rs b/rslib/src/tests.rs index 81a38d448..736b67ef7 100644 --- a/rslib/src/tests.rs +++ b/rslib/src/tests.rs @@ -3,16 +3,16 @@ #![cfg(test)] -use tempfile::{tempdir, TempDir}; +use tempfile::tempdir; +use tempfile::TempDir; -use crate::{ - collection::{open_test_collection, CollectionBuilder}, - deckconfig::UpdateDeckConfigsRequest, - io::create_dir, - media::MediaManager, - pb::deckconfig::deck_configs_for_update::current_deck::Limits, - prelude::*, -}; +use crate::collection::open_test_collection; +use crate::collection::CollectionBuilder; +use crate::deckconfig::UpdateDeckConfigsRequest; +use crate::io::create_dir; +use crate::media::MediaManager; +use crate::pb::deckconfig::deck_configs_for_update::current_deck::Limits; +use crate::prelude::*; pub(crate) fn open_fs_test_collection(name: &str) -> (Collection, TempDir) { let tempdir = tempdir().unwrap(); diff --git a/rslib/src/text.rs b/rslib/src/text.rs index 07675a127..274f44365 100644 --- a/rslib/src/text.rs +++ b/rslib/src/text.rs @@ -3,13 +3,19 @@ use std::borrow::Cow; -use ascii_percent_encoding::{percent_decode_str, utf8_percent_encode, AsciiSet, CONTROLS}; +use ascii_percent_encoding::percent_decode_str; +use ascii_percent_encoding::utf8_percent_encode; +use ascii_percent_encoding::AsciiSet; +use ascii_percent_encoding::CONTROLS; use lazy_static::lazy_static; -use regex::{Captures, Regex}; +use regex::Captures; +use regex::Regex; use unicase::eq as uni_eq; -use unicode_normalization::{ - char::is_combining_mark, is_nfc, is_nfkd_quick, IsNormalized, UnicodeNormalization, -}; +use unicode_normalization::char::is_combining_mark; +use unicode_normalization::is_nfc; +use unicode_normalization::is_nfkd_quick; +use unicode_normalization::IsNormalized; +use unicode_normalization::UnicodeNormalization; pub trait Trimming { fn trim(self) -> Self; diff --git a/rslib/src/timestamp.rs b/rslib/src/timestamp.rs index 31b9b5cbd..91bc81d1d 100644 --- a/rslib/src/timestamp.rs +++ b/rslib/src/timestamp.rs @@ -5,7 +5,8 @@ use std::time; use chrono::prelude::*; -use crate::{define_newtype, prelude::*}; +use crate::define_newtype; +use crate::prelude::*; define_newtype!(TimestampSecs, i64); define_newtype!(TimestampMillis, i64); @@ -88,8 +89,9 @@ impl TimestampMillis { fn elapsed() -> time::Duration { if *crate::PYTHON_UNIT_TESTS { - // shift clock around rollover time to accommodate Python tests that make bad assumptions. - // we should update the tests in the future and remove this hack. + // shift clock around rollover time to accommodate Python tests that make bad + // assumptions. we should update the tests in the future and remove this + // hack. let mut elap = time::SystemTime::now() .duration_since(time::SystemTime::UNIX_EPOCH) .unwrap(); diff --git a/rslib/src/typeanswer.rs b/rslib/src/typeanswer.rs index bba4f5b0b..59e125734 100644 --- a/rslib/src/typeanswer.rs +++ b/rslib/src/typeanswer.rs @@ -3,16 +3,16 @@ use std::borrow::Cow; -use difflib::sequencematcher::{Opcode, SequenceMatcher}; +use difflib::sequencematcher::Opcode; +use difflib::sequencematcher::SequenceMatcher; use itertools::Itertools; use lazy_static::lazy_static; use regex::Regex; use unic_ucd_category::GeneralCategory; -use crate::{ - card_rendering::strip_av_tags, - text::{normalize_to_nfc, strip_html}, -}; +use crate::card_rendering::strip_av_tags; +use crate::text::normalize_to_nfc; +use crate::text::strip_html; lazy_static! { static ref LINEBREAKS: Regex = Regex::new( diff --git a/rslib/src/undo/changes.rs b/rslib/src/undo/changes.rs index cd0ca6938..36c897fdd 100644 --- a/rslib/src/undo/changes.rs +++ b/rslib/src/undo/changes.rs @@ -1,13 +1,17 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -use crate::{ - card::undo::UndoableCardChange, collection::undo::UndoableCollectionChange, - config::undo::UndoableConfigChange, deckconfig::undo::UndoableDeckConfigChange, - decks::undo::UndoableDeckChange, notes::undo::UndoableNoteChange, - notetype::undo::UndoableNotetypeChange, prelude::*, revlog::undo::UndoableRevlogChange, - scheduler::queue::undo::UndoableQueueChange, tags::undo::UndoableTagChange, -}; +use crate::card::undo::UndoableCardChange; +use crate::collection::undo::UndoableCollectionChange; +use crate::config::undo::UndoableConfigChange; +use crate::deckconfig::undo::UndoableDeckConfigChange; +use crate::decks::undo::UndoableDeckChange; +use crate::notes::undo::UndoableNoteChange; +use crate::notetype::undo::UndoableNotetypeChange; +use crate::prelude::*; +use crate::revlog::undo::UndoableRevlogChange; +use crate::scheduler::queue::undo::UndoableQueueChange; +use crate::tags::undo::UndoableTagChange; #[derive(Debug)] pub(crate) enum UndoableChange { diff --git a/rslib/src/undo/mod.rs b/rslib/src/undo/mod.rs index 182d26102..a64b3017c 100644 --- a/rslib/src/undo/mod.rs +++ b/rslib/src/undo/mod.rs @@ -8,10 +8,9 @@ use std::collections::VecDeque; pub(crate) use changes::UndoableChange; pub use crate::ops::Op; -use crate::{ - ops::{OpChanges, StateChanges}, - prelude::*, -}; +use crate::ops::OpChanges; +use crate::ops::StateChanges; +use crate::prelude::*; const UNDO_LIMIT: usize = 30; @@ -212,7 +211,8 @@ impl Collection { self.state.undo.merge_undoable_ops(starting_from) } - /// Add an empty custom undo step, which subsequent changes can be merged into. + /// Add an empty custom undo step, which subsequent changes can be merged + /// into. pub fn add_custom_undo_step(&mut self, name: String) -> usize { self.state.undo.add_custom_step(name) } @@ -276,8 +276,8 @@ impl Collection { .pop() } - /// Return changes made by the current op. Must only be called in a transaction, - /// when an operation was passed to transact(). + /// Return changes made by the current op. Must only be called in a + /// transaction, when an operation was passed to transact(). pub(crate) fn op_changes(&self) -> OpChanges { self.state.undo.op_changes() } @@ -331,7 +331,9 @@ impl From<&[UndoableChange]> for StateChanges { #[cfg(test)] mod test { use super::UndoableChange; - use crate::{card::Card, collection::open_test_collection, prelude::*}; + use crate::card::Card; + use crate::collection::open_test_collection; + use crate::prelude::*; #[test] fn undo() -> Result<()> {