Skip to content

Commit d9969a9

Browse files
authored
lazy_static → once_cell → stabilized versions (#3447)
* Anki: Replace lazy_static with once_cell Unify to once_cell, lazy_static's replacement. The latter in unmaintained. * Anki: Replace once_cell with stabilized LazyCell / LazyLock as far as possible Since 1.80: rust-lang/rust#109736 and rust-lang/rust#98165 Non-Thread-Safe Lazy → std::cell::LazyCell https://doc.rust-lang.org/nightly/std/cell/struct.LazyCell.html Thread-safe SyncLazy → std::sync::LazyLock https://doc.rust-lang.org/nightly/std/sync/struct.LazyLock.html The compiler accepted LazyCell only in minilints. The final use in rslib/src/log.rs couldn't be replaced since get_or_try_init has not yet been standardized: rust-lang/rust#109737 * Declare correct MSRV (dae) Some of our deps require newer Rust versions, so this was misleading. Updating the MSRV also allows us to use .inspect() on Option now
1 parent e2124cd commit d9969a9

File tree

39 files changed

+202
-222
lines changed

39 files changed

+202
-222
lines changed

Cargo.lock

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version = "0.0.0"
33
authors = ["Ankitects Pty Ltd and contributors <https://help.ankiweb.net>"]
44
edition = "2021"
55
license = "AGPL-3.0-or-later"
6-
rust-version = "1.65"
6+
rust-version = "1.80"
77

88
[workspace]
99
members = [

build/ninja_gen/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ camino.workspace = true
1414
dunce.workspace = true
1515
globset.workspace = true
1616
itertools.workspace = true
17-
lazy_static.workspace = true
1817
maplit.workspace = true
1918
num_cpus.workspace = true
2019
walkdir.workspace = true

build/ninja_gen/src/input.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use std::collections::HashMap;
55
use std::fmt::Display;
6+
use std::sync::LazyLock;
67

78
use camino::Utf8PathBuf;
89

@@ -118,9 +119,7 @@ pub struct Glob {
118119
pub exclude: Option<String>,
119120
}
120121

121-
lazy_static::lazy_static! {
122-
static ref CACHED_FILES: Vec<Utf8PathBuf> = cache_files();
123-
}
122+
static CACHED_FILES: LazyLock<Vec<Utf8PathBuf>> = LazyLock::new(cache_files);
124123

125124
/// Walking the source tree once instead of for each glob yields ~4x speed
126125
/// improvements.

ftl/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ camino.workspace = true
1616
clap.workspace = true
1717
fluent-syntax.workspace = true
1818
itertools.workspace = true
19-
lazy_static.workspace = true
2019
regex.workspace = true
2120
serde_json.workspace = true
2221
snafu.workspace = true

ftl/src/garbage_collection.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::fs;
66
use std::io::BufReader;
77
use std::iter::FromIterator;
88
use std::path::PathBuf;
9+
use std::sync::LazyLock;
910

1011
use anki_io::create_file;
1112
use anyhow::Context;
@@ -14,7 +15,6 @@ use clap::Args;
1415
use fluent_syntax::ast;
1516
use fluent_syntax::ast::Resource;
1617
use fluent_syntax::parser;
17-
use lazy_static::lazy_static;
1818
use regex::Regex;
1919
use walkdir::DirEntry;
2020
use walkdir::WalkDir;
@@ -144,9 +144,8 @@ fn extract_nested_messages_and_terms(
144144
ftl_roots: &[impl AsRef<str>],
145145
used_ftls: &mut HashSet<String>,
146146
) {
147-
lazy_static! {
148-
static ref REFERENCE: Regex = Regex::new(r"\{\s*-?([-0-9a-z]+)\s*\}").unwrap();
149-
}
147+
static REFERENCE: LazyLock<Regex> =
148+
LazyLock::new(|| Regex::new(r"\{\s*-?([-0-9a-z]+)\s*\}").unwrap());
150149
for_files_with_ending(ftl_roots, ".ftl", |entry| {
151150
let source = fs::read_to_string(entry.path()).expect("file not readable");
152151
for caps in REFERENCE.captures_iter(&source) {
@@ -198,11 +197,12 @@ fn entry_use_check(used_ftls: &HashSet<String>) -> impl Fn(&ast::Entry<&str>) ->
198197
}
199198

200199
fn extract_references_from_file(refs: &mut HashSet<String>, entry: &DirEntry) {
201-
lazy_static! {
202-
static ref SNAKECASE_TR: Regex = Regex::new(r"\Wtr\s*\.([0-9a-z_]+)\W").unwrap();
203-
static ref CAMELCASE_TR: Regex = Regex::new(r"\Wtr2?\.([0-9A-Za-z_]+)\W").unwrap();
204-
static ref DESIGNER_STYLE_TR: Regex = Regex::new(r"<string>([0-9a-z_]+)</string>").unwrap();
205-
}
200+
static SNAKECASE_TR: LazyLock<Regex> =
201+
LazyLock::new(|| Regex::new(r"\Wtr\s*\.([0-9a-z_]+)\W").unwrap());
202+
static CAMELCASE_TR: LazyLock<Regex> =
203+
LazyLock::new(|| Regex::new(r"\Wtr2?\.([0-9A-Za-z_]+)\W").unwrap());
204+
static DESIGNER_STYLE_TR: LazyLock<Regex> =
205+
LazyLock::new(|| Regex::new(r"<string>([0-9a-z_]+)</string>").unwrap());
206206

207207
let file_name = entry.file_name().to_str().expect("non-unicode filename");
208208

rslib/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ htmlescape.workspace = true
6969
hyper.workspace = true
7070
id_tree.workspace = true
7171
itertools.workspace = true
72-
lazy_static.workspace = true
7372
nom.workspace = true
7473
num_cpus.workspace = true
7574
num_enum.workspace = true

rslib/linkchecker/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ rust-version.workspace = true
1111
anki.workspace = true
1212
futures.workspace = true
1313
itertools.workspace = true
14-
lazy_static.workspace = true
1514
linkcheck.workspace = true
1615
regex.workspace = true
1716
reqwest.workspace = true

rslib/linkchecker/tests/links.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
use std::borrow::Cow;
77
use std::env;
88
use std::iter;
9+
use std::sync::LazyLock;
910
use std::time::Duration;
1011

1112
use anki::links::help_page_link_suffix;
1213
use anki::links::help_page_to_link;
1314
use anki::links::HelpPage;
1415
use futures::StreamExt;
1516
use itertools::Itertools;
16-
use lazy_static::lazy_static;
1717
use linkcheck::validation::check_web;
1818
use linkcheck::validation::Context;
1919
use linkcheck::validation::Reason;
@@ -70,9 +70,8 @@ impl From<&'static str> for CheckableUrl {
7070
}
7171

7272
fn ts_help_pages() -> impl Iterator<Item = &'static str> {
73-
lazy_static! {
74-
static ref QUOTED_URL: Regex = Regex::new("\"(http.+)\"").unwrap();
75-
}
73+
static QUOTED_URL: LazyLock<Regex> = LazyLock::new(|| Regex::new("\"(http.+)\"").unwrap());
74+
7675
QUOTED_URL
7776
.captures_iter(include_str!("../../../ts/lib/tslib/help-page.ts"))
7877
.map(|caps| caps.get(1).unwrap().as_str())

rslib/proto_gen/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ anyhow.workspace = true
1515
camino.workspace = true
1616
inflections.workspace = true
1717
itertools.workspace = true
18-
once_cell.workspace = true
1918
prost-reflect.workspace = true
2019
prost-types.workspace = true
2120
regex.workspace = true

rslib/proto_gen/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use std::collections::HashMap;
88
use std::env;
99
use std::path::PathBuf;
10+
use std::sync::LazyLock;
1011

1112
use anki_io::read_to_string;
1213
use anki_io::write_file_if_changed;
@@ -16,7 +17,6 @@ use camino::Utf8Path;
1617
use inflections::Inflect;
1718
use itertools::Either;
1819
use itertools::Itertools;
19-
use once_cell::sync::Lazy;
2020
use prost_reflect::DescriptorPool;
2121
use prost_reflect::MessageDescriptor;
2222
use prost_reflect::MethodDescriptor;
@@ -238,8 +238,8 @@ pub fn add_must_use_annotations_to_file<E>(path: &Utf8Path, is_empty: E) -> Resu
238238
where
239239
E: Fn(&Utf8Path, &str) -> bool,
240240
{
241-
static MESSAGE_OR_ENUM_RE: Lazy<Regex> =
242-
Lazy::new(|| Regex::new(r"pub (struct|enum) ([[:alnum:]]+?)\s").unwrap());
241+
static MESSAGE_OR_ENUM_RE: LazyLock<Regex> =
242+
LazyLock::new(|| Regex::new(r"pub (struct|enum) ([[:alnum:]]+?)\s").unwrap());
243243
let contents = read_to_string(path)?;
244244
let contents = MESSAGE_OR_ENUM_RE.replace_all(&contents, |caps: &Captures| {
245245
let is_enum = caps.get(1).unwrap().as_str() == "enum";

rslib/src/ankidroid/db.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::collections::HashMap;
55
use std::mem::size_of;
66
use std::sync::atomic::AtomicI32;
77
use std::sync::atomic::Ordering;
8+
use std::sync::LazyLock;
89
use std::sync::Mutex;
910

1011
use anki_proto::ankidroid::sql_value::Data;
@@ -16,7 +17,6 @@ use itertools::FoldWhile;
1617
use itertools::FoldWhile::Continue;
1718
use itertools::FoldWhile::Done;
1819
use itertools::Itertools;
19-
use lazy_static::lazy_static;
2020
use rusqlite::ToSql;
2121
use serde::Deserialize;
2222

@@ -110,10 +110,8 @@ fn select_slice_of_size<'a>(
110110

111111
type SequenceNumber = i32;
112112

113-
lazy_static! {
114-
static ref HASHMAP: Mutex<HashMap<CollectionId, HashMap<SequenceNumber, DbResponse>>> =
115-
Mutex::new(HashMap::new());
116-
}
113+
static HASHMAP: LazyLock<Mutex<HashMap<CollectionId, HashMap<SequenceNumber, DbResponse>>>> =
114+
LazyLock::new(|| Mutex::new(HashMap::new()));
117115

118116
pub(crate) fn flush_single_result(col: &Collection, sequence_number: i32) {
119117
HASHMAP
@@ -244,10 +242,9 @@ pub(crate) fn next_sequence_number() -> i32 {
244242
SEQUENCE_NUMBER.fetch_add(1, Ordering::SeqCst)
245243
}
246244

247-
lazy_static! {
248-
// same as we get from io.requery.android.database.CursorWindow.sCursorWindowSize
249-
static ref DB_COMMAND_PAGE_SIZE: Mutex<usize> = Mutex::new(1024 * 1024 * 2);
250-
}
245+
// same as we get from
246+
// io.requery.android.database.CursorWindow.sCursorWindowSize
247+
static DB_COMMAND_PAGE_SIZE: LazyLock<Mutex<usize>> = LazyLock::new(|| Mutex::new(1024 * 1024 * 2));
251248

252249
pub(crate) fn set_max_page_size(size: usize) {
253250
let mut state = DB_COMMAND_PAGE_SIZE.lock().expect("Could not lock mutex");

rslib/src/ankihub/login.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// Copyright: Ankitects Pty Ltd and contributors
22
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
33

4-
use lazy_static::lazy_static;
4+
use std::sync::LazyLock;
5+
56
use regex::Regex;
67
use reqwest::Client;
78
use serde;
@@ -31,11 +32,9 @@ pub async fn ankihub_login<S: Into<String>>(
3132
client: Client,
3233
) -> Result<LoginResponse> {
3334
let client = HttpAnkiHubClient::new("", client);
34-
lazy_static! {
35-
static ref EMAIL_RE: Regex =
36-
Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
37-
.unwrap();
38-
}
35+
static EMAIL_RE: LazyLock<Regex> = LazyLock::new(|| {
36+
Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap()
37+
});
3938
let mut request = LoginRequest {
4039
username: None,
4140
email: None,

rslib/src/backend/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ use std::ops::Deref;
1919
use std::result;
2020
use std::sync::Arc;
2121
use std::sync::Mutex;
22+
use std::sync::OnceLock;
2223
use std::thread::JoinHandle;
2324

2425
use futures::future::AbortHandle;
25-
use once_cell::sync::OnceCell;
2626
use prost::Message;
2727
use reqwest::Client;
2828
use tokio::runtime;
@@ -53,7 +53,7 @@ pub struct BackendInner {
5353
server: bool,
5454
sync_abort: Mutex<Option<AbortHandle>>,
5555
progress_state: Arc<Mutex<ProgressState>>,
56-
runtime: OnceCell<Runtime>,
56+
runtime: OnceLock<Runtime>,
5757
state: Mutex<BackendState>,
5858
backup_task: Mutex<Option<JoinHandle<Result<()>>>>,
5959
media_sync_task: Mutex<Option<JoinHandle<Result<()>>>>,
@@ -88,7 +88,7 @@ impl Backend {
8888
want_abort: false,
8989
last_progress: None,
9090
})),
91-
runtime: OnceCell::new(),
91+
runtime: OnceLock::new(),
9292
state: Mutex::new(BackendState::default()),
9393
backup_task: Mutex::new(None),
9494
media_sync_task: Mutex::new(None),

rslib/src/cloze.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ use std::borrow::Cow;
55
use std::collections::HashMap;
66
use std::collections::HashSet;
77
use std::fmt::Write;
8+
use std::sync::LazyLock;
89

910
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusion;
1011
use anki_proto::image_occlusion::get_image_occlusion_note_response::ImageOcclusionShape;
1112
use htmlescape::encode_attribute;
12-
use lazy_static::lazy_static;
1313
use nom::branch::alt;
1414
use nom::bytes::complete::tag;
1515
use nom::bytes::complete::take_while;
@@ -24,16 +24,16 @@ use crate::latex::contains_latex;
2424
use crate::template::RenderContext;
2525
use crate::text::strip_html_preserving_entities;
2626

27-
lazy_static! {
28-
static ref MATHJAX: Regex = Regex::new(
27+
static MATHJAX: LazyLock<Regex> = LazyLock::new(|| {
28+
Regex::new(
2929
r"(?xsi)
3030
(\\[(\[]) # 1 = mathjax opening tag
3131
(.*?) # 2 = inner content
3232
(\\[])]) # 3 = mathjax closing tag
33-
"
33+
",
3434
)
35-
.unwrap();
36-
}
35+
.unwrap()
36+
});
3737

3838
mod mathjax_caps {
3939
pub const OPENING_TAG: usize = 1;

rslib/src/import_export/text/csv/export.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use std::collections::HashMap;
66
use std::fs::File;
77
use std::io::Write;
88
use std::sync::Arc;
9+
use std::sync::LazyLock;
910

1011
use anki_proto::import_export::ExportNoteCsvRequest;
1112
use itertools::Itertools;
12-
use lazy_static::lazy_static;
1313
use regex::Regex;
1414

1515
use super::metadata::Delimiter;
@@ -156,23 +156,22 @@ fn field_to_record_field(field: &str, with_html: bool) -> Cow<str> {
156156
}
157157

158158
fn strip_redundant_sections(text: &str) -> Cow<str> {
159-
lazy_static! {
160-
static ref RE: Regex = Regex::new(
159+
static RE: LazyLock<Regex> = LazyLock::new(|| {
160+
Regex::new(
161161
r"(?isx)
162162
<style>.*?</style> # style elements
163163
|
164164
\[\[type:[^]]+\]\] # type replacements
165-
"
165+
",
166166
)
167-
.unwrap();
168-
}
167+
.unwrap()
168+
});
169169
RE.replace_all(text.as_ref(), "")
170170
}
171171

172172
fn strip_answer_side_question(text: &str) -> Cow<str> {
173-
lazy_static! {
174-
static ref RE: Regex = Regex::new(r"(?is)^.*<hr id=answer>\n*").unwrap();
175-
}
173+
static RE: LazyLock<Regex> =
174+
LazyLock::new(|| Regex::new(r"(?is)^.*<hr id=answer>\n*").unwrap());
176175
RE.replace_all(text.as_ref(), "")
177176
}
178177

0 commit comments

Comments
 (0)