mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-11-14 00:17:07 +00:00
Rust v1.70: Replace once_cell with std::sync::OnceLock
This commit is contained in:
parent
80273a449c
commit
7ce77290e4
7 changed files with 70 additions and 53 deletions
|
@ -10,6 +10,7 @@ keywords = ["tags", "audio", "metadata", "id3", "vorbis"]
|
||||||
categories = ["multimedia", "multimedia::audio", "parser-implementations"]
|
categories = ["multimedia", "multimedia::audio", "parser-implementations"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
include = ["src", "Cargo.toml", "LICENSE-APACHE", "LICENSE-MIT", "SUPPORTED_FORMATS.md"]
|
include = ["src", "Cargo.toml", "LICENSE-APACHE", "LICENSE-MIT", "SUPPORTED_FORMATS.md"]
|
||||||
|
rust = "1.70.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Vorbis comments pictures
|
# Vorbis comments pictures
|
||||||
|
@ -24,7 +25,6 @@ log = "0.4.20"
|
||||||
# OGG Vorbis/Opus
|
# OGG Vorbis/Opus
|
||||||
ogg_pager = "0.5.0"
|
ogg_pager = "0.5.0"
|
||||||
# Key maps
|
# Key maps
|
||||||
once_cell = "1.18.0"
|
|
||||||
paste = "1.0.14"
|
paste = "1.0.14"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::probe::ParseOptions;
|
use crate::probe::ParseOptions;
|
||||||
use crate::properties::FileProperties;
|
use crate::properties::FileProperties;
|
||||||
use crate::resolve::CUSTOM_RESOLVERS;
|
use crate::resolve::custom_resolvers;
|
||||||
use crate::tag::{Tag, TagType};
|
use crate::tag::{Tag, TagType};
|
||||||
use crate::traits::TagExt;
|
use crate::traits::TagExt;
|
||||||
|
|
||||||
|
@ -831,7 +831,7 @@ impl FileType {
|
||||||
"mpc" | "mp+" | "mpp" => Some(Self::Mpc),
|
"mpc" | "mp+" | "mpp" => Some(Self::Mpc),
|
||||||
"spx" => Some(Self::Speex),
|
"spx" => Some(Self::Speex),
|
||||||
e => {
|
e => {
|
||||||
if let Some((ty, _)) = CUSTOM_RESOLVERS
|
if let Some((ty, _)) = custom_resolvers()
|
||||||
.lock()
|
.lock()
|
||||||
.ok()?
|
.ok()?
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::collections::HashMap;
|
||||||
/// assert_eq!(new_title, Some("TIT2"));
|
/// assert_eq!(new_title, Some("TIT2"));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn upgrade_v2(key: &str) -> Option<&'static str> {
|
pub fn upgrade_v2(key: &str) -> Option<&'static str> {
|
||||||
V2KEYS.get(key).copied()
|
v2keys().get(key).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Upgrade an ID3v2.3 key to an ID3v2.4 key
|
/// Upgrade an ID3v2.3 key to an ID3v2.4 key
|
||||||
|
@ -31,14 +31,17 @@ pub fn upgrade_v2(key: &str) -> Option<&'static str> {
|
||||||
/// assert_eq!(new_involved_people_list, Some("TIPL"));
|
/// assert_eq!(new_involved_people_list, Some("TIPL"));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn upgrade_v3(key: &str) -> Option<&'static str> {
|
pub fn upgrade_v3(key: &str) -> Option<&'static str> {
|
||||||
V3KEYS.get(key).copied()
|
v3keys().get(key).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! gen_upgrades {
|
macro_rules! gen_upgrades {
|
||||||
(V2 => [$($($v2_key:literal)|* => $id3v24_from_v2:literal),+]; V3 => [$($($v3_key:literal)|* => $id3v24_from_v3:literal),+]) => {
|
(V2 => [$($($v2_key:literal)|* => $id3v24_from_v2:literal),+]; V3 => [$($($v3_key:literal)|* => $id3v24_from_v3:literal),+]) => {
|
||||||
use once_cell::sync::Lazy;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
static V2KEYS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
static V2KEYS: OnceLock<HashMap<&'static str, &'static str>> = OnceLock::new();
|
||||||
|
|
||||||
|
fn v2keys() -> &'static HashMap<&'static str, &'static str> {
|
||||||
|
V2KEYS.get_or_init(|| {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
$(
|
$(
|
||||||
$(
|
$(
|
||||||
|
@ -46,9 +49,13 @@ macro_rules! gen_upgrades {
|
||||||
)+
|
)+
|
||||||
)+
|
)+
|
||||||
map
|
map
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
static V3KEYS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
static V3KEYS: OnceLock<HashMap<&'static str, &'static str>> = OnceLock::new();
|
||||||
|
|
||||||
|
fn v3keys() -> &'static HashMap<&'static str, &'static str> {
|
||||||
|
V3KEYS.get_or_init(|| {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
$(
|
$(
|
||||||
$(
|
$(
|
||||||
|
@ -56,8 +63,9 @@ macro_rules! gen_upgrades {
|
||||||
)+
|
)+
|
||||||
)+
|
)+
|
||||||
map
|
map
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_upgrades!(
|
gen_upgrades!(
|
||||||
|
|
|
@ -15,11 +15,15 @@ use crate::probe::Probe;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
|
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
|
||||||
use std::ops::Not;
|
use std::ops::Not;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use byteorder::{BigEndian, LittleEndian, WriteBytesExt};
|
use byteorder::{BigEndian, LittleEndian, WriteBytesExt};
|
||||||
|
|
||||||
|
static CRC_32_TABLE: OnceLock<[u32; 256]> = OnceLock::new();
|
||||||
|
|
||||||
// In the very rare chance someone wants to write a CRC in their extended header
|
// In the very rare chance someone wants to write a CRC in their extended header
|
||||||
static CRC_32_TABLE: once_cell::sync::Lazy<[u32; 256]> = once_cell::sync::Lazy::new(|| {
|
fn crc_32_table() -> &'static [u32; 256] {
|
||||||
|
CRC_32_TABLE.get_or_init(|| {
|
||||||
let mut crc32_table = [0; 256];
|
let mut crc32_table = [0; 256];
|
||||||
|
|
||||||
for n in 0..256 {
|
for n in 0..256 {
|
||||||
|
@ -30,7 +34,8 @@ static CRC_32_TABLE: once_cell::sync::Lazy<[u32; 256]> = once_cell::sync::Lazy::
|
||||||
}
|
}
|
||||||
|
|
||||||
crc32_table
|
crc32_table
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::shadow_unrelated)]
|
#[allow(clippy::shadow_unrelated)]
|
||||||
pub(crate) fn write_id3v2<'a, I: Iterator<Item = FrameRef<'a>> + Clone + 'a>(
|
pub(crate) fn write_id3v2<'a, I: Iterator<Item = FrameRef<'a>> + Clone + 'a>(
|
||||||
|
@ -232,7 +237,7 @@ fn calculate_crc(content: &[u8]) -> [u8; 5] {
|
||||||
let crc: u32 = content
|
let crc: u32 = content
|
||||||
.iter()
|
.iter()
|
||||||
.fold(!0, |crc, octet| {
|
.fold(!0, |crc, octet| {
|
||||||
(crc >> 8) ^ CRC_32_TABLE[(((crc & 0xFF) ^ u32::from(*octet)) & 0xFF) as usize]
|
(crc >> 8) ^ crc_32_table()[(((crc & 0xFF) ^ u32::from(*octet)) & 0xFF) as usize]
|
||||||
})
|
})
|
||||||
.not();
|
.not();
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::musepack::MpcFile;
|
||||||
use crate::ogg::opus::OpusFile;
|
use crate::ogg::opus::OpusFile;
|
||||||
use crate::ogg::speex::SpeexFile;
|
use crate::ogg::speex::SpeexFile;
|
||||||
use crate::ogg::vorbis::VorbisFile;
|
use crate::ogg::vorbis::VorbisFile;
|
||||||
use crate::resolve::CUSTOM_RESOLVERS;
|
use crate::resolve::custom_resolvers;
|
||||||
use crate::wavpack::WavPackFile;
|
use crate::wavpack::WavPackFile;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
@ -568,7 +568,7 @@ impl<R: Read + Seek> Probe<R> {
|
||||||
ret
|
ret
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
if let Ok(lock) = CUSTOM_RESOLVERS.lock() {
|
if let Ok(lock) = custom_resolvers().lock() {
|
||||||
#[allow(clippy::significant_drop_in_scrutinee)]
|
#[allow(clippy::significant_drop_in_scrutinee)]
|
||||||
for (_, resolve) in lock.iter() {
|
for (_, resolve) in lock.iter() {
|
||||||
if let ret @ Some(_) = resolve.guess(&buf[..buf_len]) {
|
if let ret @ Some(_) = resolve.guess(&buf[..buf_len]) {
|
||||||
|
|
|
@ -9,9 +9,7 @@ use crate::tag::TagType;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Read, Seek};
|
use std::io::{Read, Seek};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex, OnceLock};
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
|
|
||||||
/// A custom file resolver
|
/// A custom file resolver
|
||||||
///
|
///
|
||||||
|
@ -37,11 +35,14 @@ pub trait FileResolver: Send + Sync + AudioFile {
|
||||||
// Just broken out to its own type to make `CUSTOM_RESOLVER`'s type shorter :)
|
// Just broken out to its own type to make `CUSTOM_RESOLVER`'s type shorter :)
|
||||||
type ResolverMap = HashMap<&'static str, &'static dyn ObjectSafeFileResolver>;
|
type ResolverMap = HashMap<&'static str, &'static dyn ObjectSafeFileResolver>;
|
||||||
|
|
||||||
pub(crate) static CUSTOM_RESOLVERS: Lazy<Arc<Mutex<ResolverMap>>> =
|
static CUSTOM_RESOLVERS: OnceLock<Arc<Mutex<ResolverMap>>> = OnceLock::new();
|
||||||
Lazy::new(|| Arc::new(Mutex::new(HashMap::new())));
|
|
||||||
|
pub(crate) fn custom_resolvers() -> &'static Arc<Mutex<ResolverMap>> {
|
||||||
|
CUSTOM_RESOLVERS.get_or_init(Default::default)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn lookup_resolver(name: &'static str) -> &'static dyn ObjectSafeFileResolver {
|
pub(crate) fn lookup_resolver(name: &'static str) -> &'static dyn ObjectSafeFileResolver {
|
||||||
let res = CUSTOM_RESOLVERS.lock().unwrap();
|
let res = custom_resolvers().lock().unwrap();
|
||||||
|
|
||||||
if let Some(resolver) = res.get(name).copied() {
|
if let Some(resolver) = res.get(name).copied() {
|
||||||
return resolver;
|
return resolver;
|
||||||
|
@ -114,7 +115,10 @@ impl<T: FileResolver> ObjectSafeFileResolver for GhostlyResolver<T> {
|
||||||
/// * Attempting to register an existing name or type
|
/// * Attempting to register an existing name or type
|
||||||
/// * See [`Mutex::lock`]
|
/// * See [`Mutex::lock`]
|
||||||
pub fn register_custom_resolver<T: FileResolver + 'static>(name: &'static str) {
|
pub fn register_custom_resolver<T: FileResolver + 'static>(name: &'static str) {
|
||||||
let mut res = CUSTOM_RESOLVERS.lock().unwrap();
|
let mut res = CUSTOM_RESOLVERS
|
||||||
|
.get_or_init(Default::default)
|
||||||
|
.lock()
|
||||||
|
.unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
res.iter().all(|(n, _)| *n != name),
|
res.iter().all(|(n, _)| *n != name),
|
||||||
"Resolver `{}` already exists!",
|
"Resolver `{}` already exists!",
|
||||||
|
|
|
@ -29,15 +29,7 @@ macro_rules! gen_map {
|
||||||
($(#[$meta:meta])? $NAME:ident; $($($key:literal)|+ => $variant:ident),+) => {
|
($(#[$meta:meta])? $NAME:ident; $($($key:literal)|+ => $variant:ident),+) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
$(#[$meta])?
|
$(#[$meta])?
|
||||||
static [<$NAME _INNER>]: once_cell::sync::Lazy<HashMap<&'static str, ItemKey>> = once_cell::sync::Lazy::new(|| {
|
static [<$NAME _INNER>]: std::sync::OnceLock<HashMap<&'static str, ItemKey>> = std::sync::OnceLock::new();
|
||||||
let mut map = HashMap::new();
|
|
||||||
$(
|
|
||||||
$(
|
|
||||||
map.insert($key, ItemKey::$variant);
|
|
||||||
)+
|
|
||||||
)+
|
|
||||||
map
|
|
||||||
});
|
|
||||||
|
|
||||||
$(#[$meta])?
|
$(#[$meta])?
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -46,7 +38,15 @@ macro_rules! gen_map {
|
||||||
$(#[$meta])?
|
$(#[$meta])?
|
||||||
impl $NAME {
|
impl $NAME {
|
||||||
pub(crate) fn get_item_key(&self, key: &str) -> Option<ItemKey> {
|
pub(crate) fn get_item_key(&self, key: &str) -> Option<ItemKey> {
|
||||||
[<$NAME _INNER>].iter().find(|(k, _)| k.eq_ignore_ascii_case(key)).map(|(_, v)| v.clone())
|
[<$NAME _INNER>].get_or_init(|| {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
$(
|
||||||
|
$(
|
||||||
|
map.insert($key, ItemKey::$variant);
|
||||||
|
)+
|
||||||
|
)+
|
||||||
|
map
|
||||||
|
}).iter().find(|(k, _)| k.eq_ignore_ascii_case(key)).map(|(_, v)| v.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_key(&self, item_key: &ItemKey) -> Option<&str> {
|
pub(crate) fn get_key(&self, item_key: &ItemKey) -> Option<&str> {
|
||||||
|
|
Loading…
Reference in a new issue