Split io.rs into separate crate, and use it in proto build
Will be handy to use it in our other scripts in the future too - thanks Rumo! Results of benchmarking ./run before and after these crate splits: - Touching a proto file leads to a slight increase: about +90ms - Touching an rslib file leads to a bigger decrease, as there's less to recompile: about -700ms And ./ninja test is even better: about +200ms and -3800ms.
This commit is contained in:
parent
a83c4a7da7
commit
d380f3034c
|
@ -83,6 +83,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"ammonia",
|
||||
"anki_i18n",
|
||||
"anki_io",
|
||||
"anki_proto",
|
||||
"anyhow",
|
||||
"async-compression",
|
||||
|
@ -184,10 +185,19 @@ dependencies = [
|
|||
"workspace-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anki_io"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"snafu",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anki_proto"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anki_io",
|
||||
"anyhow",
|
||||
"inflections",
|
||||
"num_enum",
|
||||
|
@ -1148,13 +1158,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
||||
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"windows-sys 0.45.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1935,13 +1945,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.9"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc",
|
||||
"windows-sys 0.45.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2033,9 +2043,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
version = "0.2.146"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
|
@ -2117,9 +2127,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.1"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -3415,16 +3425,16 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.5"
|
||||
version = "0.37.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e78cc525325c06b4a7ff02db283472f3c042b7ff0c391f96c6d5ac6f4f91b75"
|
||||
checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3906,15 +3916,16 @@ checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5"
|
|||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.5.0"
|
||||
version = "3.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
|
||||
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix",
|
||||
"windows-sys 0.45.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -12,6 +12,7 @@ members = [
|
|||
"rslib/i18n_helpers",
|
||||
"rslib/linkchecker",
|
||||
"rslib/proto",
|
||||
"rslib/io",
|
||||
"pylib/rsbridge",
|
||||
"build/configure",
|
||||
"build/ninja_gen",
|
||||
|
|
|
@ -43,6 +43,7 @@ features = ["json", "socks", "stream", "multipart"]
|
|||
|
||||
[dependencies]
|
||||
anki_i18n = { path = "i18n" }
|
||||
anki_io = { path = "io" }
|
||||
anki_proto = { path = "proto" }
|
||||
|
||||
csv = { git = "https://github.com/ankitects/rust-csv.git", rev = "1c9d3aab6f79a7d815c69f925a46a4590c115f90" }
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "anki_io"
|
||||
publish = false
|
||||
description = "Utils for better I/O error reporting"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
snafu = "0.7.4"
|
||||
tempfile = "3.6.0"
|
|
@ -65,7 +65,7 @@ impl FileIoError {
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) fn is_not_found(&self) -> bool {
|
||||
pub fn is_not_found(&self) -> bool {
|
||||
self.source.kind() == std::io::ErrorKind::NotFound
|
||||
}
|
||||
}
|
|
@ -1,23 +1,33 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
mod error;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::Seek;
|
||||
use std::path::Component;
|
||||
use std::path::Path;
|
||||
|
||||
use snafu::ResultExt;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
use crate::error::FileIoError;
|
||||
use crate::error::FileIoSnafu;
|
||||
use crate::error::FileOp;
|
||||
use crate::prelude::*;
|
||||
pub use crate::error::FileIoError;
|
||||
pub use crate::error::FileIoSnafu;
|
||||
pub use crate::error::FileOp;
|
||||
|
||||
pub(crate) type Result<T, E = FileIoError> = std::result::Result<T, E>;
|
||||
pub type Result<T, E = FileIoError> = std::result::Result<T, E>;
|
||||
|
||||
/// See [File::create].
|
||||
pub fn create_file(path: impl AsRef<Path>) -> Result<File> {
|
||||
File::create(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Create,
|
||||
})
|
||||
}
|
||||
|
||||
/// See [File::open].
|
||||
pub(crate) fn open_file(path: impl AsRef<Path>) -> Result<File> {
|
||||
pub fn open_file(path: impl AsRef<Path>) -> Result<File> {
|
||||
File::open(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Open,
|
||||
|
@ -25,7 +35,7 @@ pub(crate) fn open_file(path: impl AsRef<Path>) -> Result<File> {
|
|||
}
|
||||
|
||||
/// See [std::fs::write].
|
||||
pub(crate) fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
|
||||
pub fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
|
||||
std::fs::write(&path, contents).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Write,
|
||||
|
@ -34,7 +44,7 @@ pub(crate) fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) ->
|
|||
|
||||
/// See [std::fs::remove_file].
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn remove_file(path: impl AsRef<Path>) -> Result<()> {
|
||||
pub fn remove_file(path: impl AsRef<Path>) -> Result<()> {
|
||||
std::fs::remove_file(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Remove,
|
||||
|
@ -42,7 +52,7 @@ pub(crate) fn remove_file(path: impl AsRef<Path>) -> Result<()> {
|
|||
}
|
||||
|
||||
/// See [std::fs::create_dir].
|
||||
pub(crate) fn create_dir(path: impl AsRef<Path>) -> Result<()> {
|
||||
pub fn create_dir(path: impl AsRef<Path>) -> Result<()> {
|
||||
std::fs::create_dir(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Create,
|
||||
|
@ -50,7 +60,7 @@ pub(crate) fn create_dir(path: impl AsRef<Path>) -> Result<()> {
|
|||
}
|
||||
|
||||
/// See [std::fs::create_dir_all].
|
||||
pub(crate) fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
|
||||
pub fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
|
||||
std::fs::create_dir_all(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Create,
|
||||
|
@ -58,7 +68,7 @@ pub(crate) fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
|
|||
}
|
||||
|
||||
/// See [std::fs::read].
|
||||
pub(crate) fn read_file(path: impl AsRef<Path>) -> Result<Vec<u8>> {
|
||||
pub fn read_file(path: impl AsRef<Path>) -> Result<Vec<u8>> {
|
||||
std::fs::read(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Read,
|
||||
|
@ -67,7 +77,7 @@ pub(crate) fn read_file(path: impl AsRef<Path>) -> Result<Vec<u8>> {
|
|||
|
||||
/// Like [read_file], but skips the section that is potentially locked by
|
||||
/// SQLite.
|
||||
pub(crate) fn read_locked_db_file(path: impl AsRef<Path>) -> Result<Vec<u8>> {
|
||||
pub fn read_locked_db_file(path: impl AsRef<Path>) -> Result<Vec<u8>> {
|
||||
read_locked_db_file_inner(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Read,
|
||||
|
@ -94,28 +104,28 @@ fn read_locked_db_file_inner(path: impl AsRef<Path>) -> std::io::Result<Vec<u8>>
|
|||
}
|
||||
|
||||
/// See [std::fs::metadata].
|
||||
pub(crate) fn metadata(path: impl AsRef<Path>) -> Result<std::fs::Metadata> {
|
||||
pub fn metadata(path: impl AsRef<Path>) -> Result<std::fs::Metadata> {
|
||||
std::fs::metadata(&path).context(FileIoSnafu {
|
||||
path: path.as_ref(),
|
||||
op: FileOp::Metadata,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn new_tempfile() -> Result<NamedTempFile> {
|
||||
pub fn new_tempfile() -> Result<NamedTempFile> {
|
||||
NamedTempFile::new().context(FileIoSnafu {
|
||||
path: std::env::temp_dir(),
|
||||
op: FileOp::Create,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn new_tempfile_in(dir: impl AsRef<Path>) -> Result<NamedTempFile> {
|
||||
pub fn new_tempfile_in(dir: impl AsRef<Path>) -> Result<NamedTempFile> {
|
||||
NamedTempFile::new_in(&dir).context(FileIoSnafu {
|
||||
path: dir.as_ref(),
|
||||
op: FileOp::Create,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn new_tempfile_in_parent_of(file: &Path) -> Result<NamedTempFile> {
|
||||
pub fn new_tempfile_in_parent_of(file: &Path) -> Result<NamedTempFile> {
|
||||
let dir = file.parent().unwrap_or(file);
|
||||
NamedTempFile::new_in(dir).context(FileIoSnafu {
|
||||
path: dir,
|
||||
|
@ -129,7 +139,7 @@ pub(crate) fn new_tempfile_in_parent_of(file: &Path) -> Result<NamedTempFile> {
|
|||
/// folder is synced on UNIX platforms after renaming. This minimizes the
|
||||
/// chances of corruption if there is a crash or power loss directly after the
|
||||
/// op, but it can be considerably slower.
|
||||
pub(crate) fn atomic_rename(file: NamedTempFile, target: &Path, fsync: bool) -> Result<()> {
|
||||
pub fn atomic_rename(file: NamedTempFile, target: &Path, fsync: bool) -> Result<()> {
|
||||
if fsync {
|
||||
file.as_file().sync_all().context(FileIoSnafu {
|
||||
path: file.path(),
|
||||
|
@ -150,7 +160,7 @@ pub(crate) fn atomic_rename(file: NamedTempFile, target: &Path, fsync: bool) ->
|
|||
}
|
||||
|
||||
/// Like [std::fs::read_dir], but only yielding files. [Err]s are not filtered.
|
||||
pub(crate) fn read_dir_files(path: impl AsRef<Path>) -> Result<ReadDirFiles> {
|
||||
pub fn read_dir_files(path: impl AsRef<Path>) -> Result<ReadDirFiles> {
|
||||
std::fs::read_dir(&path)
|
||||
.map(ReadDirFiles)
|
||||
.context(FileIoSnafu {
|
||||
|
@ -160,7 +170,7 @@ pub(crate) fn read_dir_files(path: impl AsRef<Path>) -> Result<ReadDirFiles> {
|
|||
}
|
||||
|
||||
/// True if name does not contain any path separators.
|
||||
pub(crate) fn filename_is_safe(name: &str) -> bool {
|
||||
pub fn filename_is_safe(name: &str) -> bool {
|
||||
let mut components = Path::new(name).components();
|
||||
let first_element_normal = components
|
||||
.next()
|
||||
|
@ -170,7 +180,7 @@ pub(crate) fn filename_is_safe(name: &str) -> bool {
|
|||
first_element_normal && components.next().is_none()
|
||||
}
|
||||
|
||||
pub(crate) struct ReadDirFiles(std::fs::ReadDir);
|
||||
pub struct ReadDirFiles(std::fs::ReadDir);
|
||||
|
||||
impl Iterator for ReadDirFiles {
|
||||
type Item = std::io::Result<std::fs::DirEntry>;
|
|
@ -10,6 +10,7 @@ license.workspace = true
|
|||
rust-version.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
anki_io = { version = "0.0.0", path = "../io" }
|
||||
anyhow = "1.0.71"
|
||||
inflections = "1.1.1"
|
||||
prost-build = "0.11.9"
|
||||
|
|
|
@ -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 std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Context;
|
||||
use anki_io::create_file;
|
||||
use anyhow::Result;
|
||||
use inflections::Inflect;
|
||||
use prost_reflect::DescriptorPool;
|
||||
|
@ -18,9 +17,7 @@ use prost_reflect::ServiceDescriptor;
|
|||
|
||||
pub(crate) fn write_python_interface(pool: &DescriptorPool) -> Result<()> {
|
||||
let output_path = Path::new("../../out/pylib/anki/_backend_generated.py");
|
||||
let mut out = BufWriter::new(
|
||||
File::create(output_path).with_context(|| format!("opening {output_path:?}"))?,
|
||||
);
|
||||
let mut out = BufWriter::new(create_file(output_path)?);
|
||||
write_header(&mut out)?;
|
||||
|
||||
for service in pool.services() {
|
||||
|
|
|
@ -7,6 +7,8 @@ use std::fs;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::create_dir_all;
|
||||
use anki_io::read_file;
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use prost_build::ServiceGenerator;
|
||||
|
@ -17,13 +19,11 @@ pub fn write_backend_proto_rs(descriptors_path: &Path) -> Result<DescriptorPool>
|
|||
let proto_dir = PathBuf::from("../../proto");
|
||||
let paths = gather_proto_paths(&proto_dir)?;
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
fs::create_dir_all(
|
||||
create_dir_all(
|
||||
descriptors_path
|
||||
.parent()
|
||||
.context("no parent found for descriptors path")?,
|
||||
)
|
||||
.with_context(|| format!("creating {descriptors_path:?}"))?;
|
||||
|
||||
.context("missing parent of descriptor")?,
|
||||
)?;
|
||||
prost_build::Config::new()
|
||||
.out_dir(&out_dir)
|
||||
.file_descriptor_set_path(descriptors_path)
|
||||
|
@ -57,8 +57,7 @@ pub fn write_backend_proto_rs(descriptors_path: &Path) -> Result<DescriptorPool>
|
|||
}
|
||||
|
||||
fn write_service_index(out_dir: &Path, descriptors_path: &Path) -> Result<DescriptorPool> {
|
||||
let descriptors = fs::read(descriptors_path)
|
||||
.with_context(|| format!("failed to read {descriptors_path:?}"))?;
|
||||
let descriptors = read_file(descriptors_path)?;
|
||||
let pool =
|
||||
DescriptorPool::decode(descriptors.as_ref()).context("unable to decode descriptors")?;
|
||||
let mut buf = String::new();
|
||||
|
|
|
@ -11,13 +11,13 @@ use std::thread;
|
|||
use std::thread::JoinHandle;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use anki_io::read_locked_db_file;
|
||||
use anki_proto::config::preferences::BackupLimits;
|
||||
use chrono::prelude::*;
|
||||
use itertools::Itertools;
|
||||
use tracing::error;
|
||||
|
||||
use crate::import_export::package::export_colpkg_from_data;
|
||||
use crate::io::read_locked_db_file;
|
||||
use crate::prelude::*;
|
||||
|
||||
const BACKUP_FORMAT_STRING: &str = "backup-%Y-%m-%d-%H.%M.%S.colpkg";
|
||||
|
|
|
@ -13,12 +13,12 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use anki_i18n::I18n;
|
||||
use anki_io::create_dir_all;
|
||||
|
||||
use crate::browser_table;
|
||||
use crate::decks::Deck;
|
||||
use crate::decks::DeckId;
|
||||
use crate::error::Result;
|
||||
use crate::io::create_dir_all;
|
||||
use crate::notetype::Notetype;
|
||||
use crate::notetype::NotetypeId;
|
||||
use crate::scheduler::queue::CardQueues;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
mod db;
|
||||
mod file_io;
|
||||
mod filtered;
|
||||
mod invalid_input;
|
||||
pub(crate) mod network;
|
||||
|
@ -12,6 +11,8 @@ mod search;
|
|||
pub mod windows;
|
||||
|
||||
use anki_i18n::I18n;
|
||||
use anki_io::FileIoError;
|
||||
use anki_io::FileOp;
|
||||
use anki_proto::ProtoError;
|
||||
pub use db::DbError;
|
||||
pub use db::DbErrorKind;
|
||||
|
@ -25,9 +26,6 @@ pub use search::ParseError;
|
|||
pub use search::SearchErrorKind;
|
||||
use snafu::Snafu;
|
||||
|
||||
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;
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::metadata;
|
||||
use anki_io::read_file;
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageClozeNote;
|
||||
use anki_proto::image_occlusion::get_image_occlusion_note_response::Value;
|
||||
use anki_proto::image_occlusion::GetImageForOcclusionResponse;
|
||||
use anki_proto::image_occlusion::GetImageOcclusionNoteResponse;
|
||||
use regex::Regex;
|
||||
|
||||
use crate::io::metadata;
|
||||
use crate::io::read_file;
|
||||
use crate::media::MediaManager;
|
||||
use crate::notetype::CardGenContext;
|
||||
use crate::prelude::*;
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use anki_io::filename_is_safe;
|
||||
use itertools::Itertools;
|
||||
|
||||
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;
|
||||
|
|
|
@ -5,6 +5,10 @@ use std::collections::HashSet;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::atomic_rename;
|
||||
use anki_io::new_tempfile;
|
||||
use anki_io::new_tempfile_in_parent_of;
|
||||
|
||||
use super::super::meta::MetaExt;
|
||||
use crate::collection::CollectionBuilder;
|
||||
use crate::import_export::gather::ExchangeData;
|
||||
|
@ -13,9 +17,6 @@ use crate::import_export::package::media::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 {
|
||||
|
|
|
@ -5,12 +5,12 @@ use std::collections::HashMap;
|
|||
use std::fs::File;
|
||||
use std::mem;
|
||||
|
||||
use anki_io::FileIoSnafu;
|
||||
use anki_io::FileOp;
|
||||
use zip::ZipArchive;
|
||||
|
||||
use super::super::super::meta::MetaExt;
|
||||
use super::Context;
|
||||
use crate::error::FileIoSnafu;
|
||||
use crate::error::FileOp;
|
||||
use crate::import_export::package::media::extract_media_entries;
|
||||
use crate::import_export::package::media::MediaCopier;
|
||||
use crate::import_export::package::media::SafeMediaEntry;
|
||||
|
|
|
@ -10,6 +10,10 @@ use std::collections::HashSet;
|
|||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
use anki_io::new_tempfile;
|
||||
use anki_io::open_file;
|
||||
use anki_io::FileIoSnafu;
|
||||
use anki_io::FileOp;
|
||||
pub(crate) use notes::NoteMeta;
|
||||
use rusqlite::OptionalExtension;
|
||||
use tempfile::NamedTempFile;
|
||||
|
@ -17,15 +21,11 @@ use zip::ZipArchive;
|
|||
|
||||
use super::super::meta::MetaExt;
|
||||
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;
|
||||
|
|
|
@ -7,7 +7,8 @@ use std::collections::HashSet;
|
|||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::io::read_file;
|
||||
use anki_io::read_file;
|
||||
|
||||
use crate::media::files::sha1_of_data;
|
||||
use crate::media::MediaManager;
|
||||
use crate::prelude::*;
|
||||
|
|
|
@ -9,6 +9,10 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::atomic_rename;
|
||||
use anki_io::new_tempfile;
|
||||
use anki_io::new_tempfile_in_parent_of;
|
||||
use anki_io::open_file;
|
||||
use prost::Message;
|
||||
use tempfile::NamedTempFile;
|
||||
use zip::write::FileOptions;
|
||||
|
@ -30,10 +34,6 @@ use crate::import_export::package::media::MediaCopier;
|
|||
use crate::import_export::package::media::MediaIter;
|
||||
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::prelude::*;
|
||||
use crate::storage::SchemaVersion;
|
||||
|
||||
|
|
|
@ -7,24 +7,24 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::atomic_rename;
|
||||
use anki_io::create_dir_all;
|
||||
use anki_io::new_tempfile_in_parent_of;
|
||||
use anki_io::open_file;
|
||||
use anki_io::FileIoSnafu;
|
||||
use anki_io::FileOp;
|
||||
use zip::read::ZipFile;
|
||||
use zip::ZipArchive;
|
||||
use zstd::stream::copy_decode;
|
||||
|
||||
use super::super::meta::MetaExt;
|
||||
use crate::collection::CollectionBuilder;
|
||||
use crate::error::FileIoSnafu;
|
||||
use crate::error::FileOp;
|
||||
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::ImportError;
|
||||
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::*;
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
use std::path::Path;
|
||||
|
||||
use anki_io::create_dir_all;
|
||||
use anki_io::read_file;
|
||||
use tempfile::tempdir;
|
||||
|
||||
use crate::collection::CollectionBuilder;
|
||||
use crate::import_export::package::import_colpkg;
|
||||
use crate::io::create_dir_all;
|
||||
use crate::io::read_file;
|
||||
use crate::media::MediaManager;
|
||||
use crate::prelude::*;
|
||||
|
||||
|
@ -79,7 +79,7 @@ fn roundtrip() -> Result<()> {
|
|||
#[test]
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
fn normalization_check_on_export() -> Result<()> {
|
||||
use crate::io::write_file;
|
||||
use anki_io::write_file;
|
||||
|
||||
let _dir = tempdir()?;
|
||||
let dir = _dir.path();
|
||||
|
|
|
@ -12,6 +12,12 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anki_io::atomic_rename;
|
||||
use anki_io::filename_is_safe;
|
||||
use anki_io::new_tempfile_in;
|
||||
use anki_io::read_dir_files;
|
||||
use anki_io::FileIoError;
|
||||
use anki_io::FileOp;
|
||||
use prost::Message;
|
||||
use sha1::Digest;
|
||||
use sha1::Sha1;
|
||||
|
@ -24,15 +30,9 @@ use super::meta::MetaExt;
|
|||
use super::MediaEntries;
|
||||
use super::MediaEntry;
|
||||
use super::Meta;
|
||||
use crate::error::FileIoError;
|
||||
use crate::error::FileOp;
|
||||
use crate::error::InvalidInputError;
|
||||
use crate::import_export::package::colpkg::export::MaybeEncodedWriter;
|
||||
use crate::import_export::ImportError;
|
||||
use crate::io::atomic_rename;
|
||||
use crate::io::filename_is_safe;
|
||||
use crate::io::new_tempfile_in;
|
||||
use crate::io::read_dir_files;
|
||||
use crate::media::files::filename_if_normalized;
|
||||
use crate::media::files::normalize_filename;
|
||||
use crate::prelude::*;
|
||||
|
|
|
@ -7,6 +7,8 @@ use std::io::Read;
|
|||
use std::io::Seek;
|
||||
use std::io::SeekFrom;
|
||||
|
||||
use anki_io::open_file;
|
||||
|
||||
use crate::import_export::text::csv::metadata::CsvDeck;
|
||||
use crate::import_export::text::csv::metadata::CsvMetadata;
|
||||
use crate::import_export::text::csv::metadata::CsvMetadataHelpers;
|
||||
|
@ -18,7 +20,6 @@ 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::*;
|
||||
use crate::text::strip_utf8_bom;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use std::io::Read;
|
|||
use std::io::Seek;
|
||||
use std::io::SeekFrom;
|
||||
|
||||
use anki_io::open_file;
|
||||
pub use anki_proto::import_export::csv_metadata::Deck as CsvDeck;
|
||||
pub use anki_proto::import_export::csv_metadata::Delimiter;
|
||||
pub use anki_proto::import_export::csv_metadata::DupeResolution;
|
||||
|
@ -24,7 +25,6 @@ use crate::config::I32ConfigKey;
|
|||
use crate::import_export::text::csv::import::FieldSourceColumns;
|
||||
use crate::import_export::text::NameOrId;
|
||||
use crate::import_export::ImportError;
|
||||
use crate::io::open_file;
|
||||
use crate::notetype::NoteField;
|
||||
use crate::prelude::*;
|
||||
use crate::text::html_to_text_line;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use anki_io::read_file;
|
||||
|
||||
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 {
|
||||
|
|
|
@ -18,7 +18,6 @@ pub mod error;
|
|||
pub mod findreplace;
|
||||
pub mod image_occlusion;
|
||||
pub mod import_export;
|
||||
mod io;
|
||||
pub mod latex;
|
||||
pub mod links;
|
||||
pub mod log;
|
||||
|
|
|
@ -521,13 +521,13 @@ pub(crate) mod test {
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anki_io::create_dir;
|
||||
use anki_io::write_file;
|
||||
use tempfile::tempdir;
|
||||
use tempfile::TempDir;
|
||||
|
||||
use super::*;
|
||||
use crate::collection::CollectionBuilder;
|
||||
use crate::io::create_dir;
|
||||
use crate::io::write_file;
|
||||
|
||||
fn common_setup() -> Result<(TempDir, MediaManager, Collection)> {
|
||||
let dir = tempdir()?;
|
||||
|
|
|
@ -9,6 +9,12 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::time;
|
||||
|
||||
use anki_io::create_dir;
|
||||
use anki_io::open_file;
|
||||
use anki_io::write_file;
|
||||
use anki_io::FileIoError;
|
||||
use anki_io::FileIoSnafu;
|
||||
use anki_io::FileOp;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use sha1::Digest;
|
||||
|
@ -18,12 +24,6 @@ use unic_ucd_category::GeneralCategory;
|
|||
use unicode_normalization::is_nfc;
|
||||
use unicode_normalization::UnicodeNormalization;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ use std::collections::HashMap;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::io::create_dir_all;
|
||||
use anki_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;
|
||||
|
|
|
@ -949,13 +949,13 @@ impl SearchNode {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use anki_io::write_file;
|
||||
use tempfile::tempdir;
|
||||
|
||||
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<String>) {
|
||||
|
|
|
@ -77,9 +77,10 @@ impl SqliteStorage {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use anki_io::new_tempfile;
|
||||
|
||||
use super::*;
|
||||
use crate::collection::CollectionBuilder;
|
||||
use crate::io::new_tempfile;
|
||||
use crate::prelude::*;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -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 anki_io::atomic_rename;
|
||||
use anki_io::new_tempfile_in_parent_of;
|
||||
use anki_io::read_file;
|
||||
use anki_io::write_file;
|
||||
|
||||
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;
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
use std::fs;
|
||||
use std::io::Write;
|
||||
|
||||
use anki_io::atomic_rename;
|
||||
use anki_io::new_tempfile_in_parent_of;
|
||||
use anki_io::write_file;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::response::Response;
|
||||
use flate2::write::GzEncoder;
|
||||
|
@ -13,9 +16,6 @@ use tokio_util::io::ReaderStream;
|
|||
|
||||
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;
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
use std::fs;
|
||||
use std::io::ErrorKind;
|
||||
|
||||
use anki_io::FileIoSnafu;
|
||||
use anki_io::FileOp;
|
||||
use snafu::ResultExt;
|
||||
|
||||
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;
|
||||
|
|
|
@ -7,7 +7,8 @@ pub mod upload;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::io::create_dir_all;
|
||||
use anki_io::create_dir_all;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::sync::error::HttpResult;
|
||||
use crate::sync::error::OrHttpErr;
|
||||
|
|
|
@ -5,14 +5,14 @@ use std::fs;
|
|||
use std::io::ErrorKind;
|
||||
use std::path::Path;
|
||||
|
||||
use anki_io::write_file;
|
||||
use anki_io::FileIoError;
|
||||
use anki_io::FileIoSnafu;
|
||||
use anki_io::FileOp;
|
||||
use snafu::ResultExt;
|
||||
use tracing::info;
|
||||
|
||||
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;
|
||||
|
|
|
@ -18,6 +18,7 @@ use std::pin::Pin;
|
|||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use anki_io::create_dir_all;
|
||||
use axum::extract::DefaultBodyLimit;
|
||||
use axum::Router;
|
||||
use snafu::whatever;
|
||||
|
@ -27,7 +28,6 @@ use snafu::Whatever;
|
|||
use tracing::Span;
|
||||
|
||||
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;
|
||||
|
|
|
@ -5,9 +5,9 @@ use std::collections::HashMap;
|
|||
use std::path::Path;
|
||||
use std::time;
|
||||
|
||||
use anki_io::read_dir_files;
|
||||
use tracing::debug;
|
||||
|
||||
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;
|
||||
|
@ -243,12 +243,12 @@ mod test {
|
|||
use std::time;
|
||||
use std::time::Duration;
|
||||
|
||||
use anki_io::create_dir;
|
||||
use anki_io::write_file;
|
||||
use tempfile::tempdir;
|
||||
|
||||
use super::*;
|
||||
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;
|
||||
|
|
|
@ -321,10 +321,10 @@ fn initial_db_setup(db: &mut Connection) -> error::Result<()> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use anki_io::new_tempfile;
|
||||
use tempfile::TempDir;
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue