From 4633d0994757ed2a85a5bab64280b61f137991cf Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Mon, 18 Mar 2024 19:11:49 +0300 Subject: [PATCH 1/2] remove snafu --- CHANGELOG.md | 2 ++ Cargo.toml | 6 +++--- macros/src/lib.rs | 6 +++++- src/error.rs | 11 +++++------ src/fs.rs | 11 +++++++---- src/lib.rs | 3 --- src/loader/tera.rs | 19 +++++++++---------- 7 files changed, 31 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3c88bd..fe3a143 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Remove unused `lazy_static`, replace `snafu` with `thiserror`, bump `flume` to `0.11` + ## [0.9.1](https://github.com/XAMPPRocky/fluent-templates/compare/fluent-templates-v0.9.0...fluent-templates-v0.9.1) - 2024-03-10 ### Other diff --git a/Cargo.toml b/Cargo.toml index c1aa145..41dc86c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ license.workspace = true repository.workspace = true version.workspace = true resolver = "2" +rust-version = "1.70.0" [workspace.package] edition = "2021" @@ -37,18 +38,17 @@ use-ignore = ["ignore", "fluent-template-macros/ignore"] [dependencies] handlebars = { version = "5", optional = true } -lazy_static = "1.2.0" fluent = "0.16" fluent-bundle = "0.15.2" fluent-syntax = "0.11" fluent-langneg = "0.13" serde_json = "1.0.79" unic-langid = { version = "0.9.0", features = ["macros"] } -snafu = "0.7.0" +thiserror = "1.0.58" tera = { version = "1.15.0", optional = true, default-features = false } heck = "0.4.0" ignore = { version = "0.4.18", optional = true } -flume = { version = "0.10.12", default-features = false } +flume = { version = "0.11.0", default-features = false } log = "0.4.14" fluent-template-macros = { path = "./macros", optional = true, version = "0.9.1" } once_cell = "1.10.0" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index c59ba04..7844a18 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -213,7 +213,11 @@ pub fn static_loader(input: proc_macro::TokenStream) -> proc_macro::TokenStream let mut insert_resources: Vec<_> = build_resources(locales_directory).into_iter().collect(); - if insert_resources.iter().find(|(lang, _)| *lang == fallback_language.value()).is_none() { + if insert_resources + .iter() + .find(|(lang, _)| *lang == fallback_language.value()) + .is_none() + { return syn::Error::new( fallback_language.span(), "Fallback language not found in locales directory", diff --git a/src/error.rs b/src/error.rs index 30e668f..a1126aa 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,11 +1,10 @@ use std::fmt; /// Errors that can occur when loading or parsing fluent resources. -#[derive(Debug, snafu::Snafu)] -#[snafu(visibility(pub(crate)))] +#[derive(Debug, thiserror::Error)] pub enum LoaderError { /// An `io::Error` occurred while interacting with `path`. - #[snafu(display("Error with {}\n: {}", path.display(), source))] + #[error("Error with {}\n: {}", path.display(), source)] Fs { /// The path to file with the error. path: std::path::PathBuf, @@ -13,14 +12,14 @@ pub enum LoaderError { source: std::io::Error, }, /// An error was found in the fluent syntax. - #[snafu(display("Error parsing Fluent\n: {}", source))] + #[error("Error parsing Fluent\n: {}", source)] Fluent { /// The original parse errors - #[snafu(source(from(Vec, FluentError::from)))] + #[from] source: FluentError, }, /// An error was found whilst loading a bundle at runtime. - #[snafu(display("Failed to add FTL resources to the bundle"))] + #[error("Failed to add FTL resources to the bundle")] FluentBundle { /// The original bundle errors errors: Vec, diff --git a/src/fs.rs b/src/fs.rs index 4d15cd1..b0a18d0 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -2,20 +2,23 @@ use std::fs; use std::path::Path; use fluent_bundle::FluentResource; -use snafu::*; pub use unic_langid::{langid, langids, LanguageIdentifier}; use crate::error; pub fn read_from_file>(path: P) -> crate::Result { let path = path.as_ref(); - resource_from_str(&fs::read_to_string(path).context(error::FsSnafu { path })?) + resource_from_str( + &fs::read_to_string(path).map_err(|source| error::LoaderError::Fs { + path: path.into(), + source, + })?, + ) } pub fn resource_from_str(src: &str) -> crate::Result { FluentResource::try_new(src.to_owned()) - .map_err(|(_, errs)| errs) - .context(error::FluentSnafu) + .map_err(|(_, errs)| error::FluentError::from(errs).into()) } pub fn resources_from_vec(srcs: &[String]) -> crate::Result> { diff --git a/src/lib.rs b/src/lib.rs index afc4452..ccd29e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -314,9 +314,6 @@ //! [`handlebars::Context`]: https://docs.rs/handlebars/3.1.0/handlebars/struct.Context.html #![warn(missing_docs)] -#[doc(hidden)] -pub extern crate lazy_static; - #[doc(hidden)] pub extern crate fluent_bundle; diff --git a/src/loader/tera.rs b/src/loader/tera.rs index 0e52412..444407e 100644 --- a/src/loader/tera.rs +++ b/src/loader/tera.rs @@ -1,6 +1,5 @@ use fluent_bundle::FluentValue; use serde_json::Value as Json; -use snafu::OptionExt; use std::collections::HashMap; use unic_langid::LanguageIdentifier; @@ -9,15 +8,15 @@ use crate::Loader; const LANG_KEY: &str = "lang"; const FLUENT_KEY: &str = "key"; -#[derive(Debug, snafu::Snafu)] +#[derive(Debug, thiserror::Error)] enum Error { - #[snafu(display("No `lang` argument provided."))] + #[error("No `lang` argument provided.")] NoLangArgument, - #[snafu(display("`lang` must be a valid unicode language identifier."))] + #[error("`lang` must be a valid unicode language identifier.")] LangArgumentInvalid, - #[snafu(display("No `id` argument provided."))] + #[error("No `id` argument provided.")] NoFluentArgument, - #[snafu(display("Couldn't convert JSON to Fluent value."))] + #[error("Couldn't convert JSON to Fluent value.")] JsonToFluentFail, } @@ -38,10 +37,10 @@ fn json_to_fluent(json: Json) -> crate::Result, Error> { fn parse_language(arg: &Json) -> crate::Result { arg.as_str() - .context(self::LangArgumentInvalidSnafu)? + .ok_or(Error::LangArgumentInvalid)? .parse::() .ok() - .context(self::LangArgumentInvalidSnafu) + .ok_or(Error::LangArgumentInvalid) } impl tera::Function for crate::FluentLoader { @@ -50,12 +49,12 @@ impl tera::Function for crate::FluentLoader { let lang = lang_arg .as_ref() .or(self.default_lang.as_ref()) - .context(self::NoLangArgumentSnafu)?; + .ok_or(Error::NoLangArgument)?; let id = args .get(FLUENT_KEY) .and_then(Json::as_str) - .context(self::NoFluentArgumentSnafu)?; + .ok_or(Error::NoFluentArgument)?; /// Filters kwargs to exclude ones used by this function and tera. fn is_not_tera_key((k, _): &(&String, &Json)) -> bool { From 8175d6ed8fb475bcf4895efb08693a8e38d15f80 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Tue, 19 Mar 2024 07:13:35 +0300 Subject: [PATCH 2/2] split_once --- macros/src/lib.rs | 5 ++--- src/loader.rs | 16 ++++------------ src/loader/arc_loader.rs | 2 +- src/loader/shared.rs | 15 +++++---------- src/loader/static_loader.rs | 2 +- 5 files changed, 13 insertions(+), 27 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 7844a18..6aa598d 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -213,10 +213,9 @@ pub fn static_loader(input: proc_macro::TokenStream) -> proc_macro::TokenStream let mut insert_resources: Vec<_> = build_resources(locales_directory).into_iter().collect(); - if insert_resources + if !insert_resources .iter() - .find(|(lang, _)| *lang == fallback_language.value()) - .is_none() + .any(|(lang, _)| *lang == fallback_language.value()) { return syn::Error::new( fallback_language.span(), diff --git a/src/loader.rs b/src/loader.rs index f9ec1a3..b9c20f5 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -225,16 +225,8 @@ pub fn build_bundles( bundles } -fn map_to_fluent_args<'map, T: AsRef>( - map: Option<&'map HashMap>, -) -> Option> { - let mut new = FluentArgs::new(); - - if let Some(map) = map { - for (key, value) in map { - new.set(key.as_ref(), value.clone()); - } - } - - Some(new) +fn map_to_fluent_args<'map, T: AsRef>(map: &'map HashMap) -> FluentArgs<'map> { + map.iter() + .map(|(key, value)| (key.as_ref(), value.clone())) + .collect() } diff --git a/src/loader/arc_loader.rs b/src/loader/arc_loader.rs index 5811b6b..b9811e1 100644 --- a/src/loader/arc_loader.rs +++ b/src/loader/arc_loader.rs @@ -123,7 +123,7 @@ impl super::Loader for ArcLoader { return val; } } - format!("Unknown localization {}", text_id) + format!("Unknown localization {text_id}") } // Traverse the fallback chain, diff --git a/src/loader/shared.rs b/src/loader/shared.rs index 44671a8..6e69b4d 100644 --- a/src/loader/shared.rs +++ b/src/loader/shared.rs @@ -14,28 +14,23 @@ pub fn lookup_single_language, R: Borrow>( ) -> Option { let bundle = bundles.get(lang)?; let mut errors = Vec::new(); - let pattern = if text_id.contains('.') { - // TODO: #![feature(str_split_once)] - let ids: Vec<_> = text_id.splitn(2, '.').collect(); + let pattern = if let Some((msg, attr)) = text_id.split_once('.') { bundle - .get_message(ids[0])? + .get_message(msg)? .attributes() - .find(|attribute| attribute.id() == ids[1])? + .find(|attribute| attribute.id() == attr)? .value() } else { bundle.get_message(text_id)?.value()? }; - let args = super::map_to_fluent_args(args); + let args = args.map(super::map_to_fluent_args); let value = bundle.format_pattern(pattern, args.as_ref(), &mut errors); if errors.is_empty() { Some(value.into()) } else { - panic!( - "Failed to format a message for locale {} and id {}.\nErrors\n{:?}", - lang, text_id, errors - ) + panic!("Failed to format a message for locale {lang} and id {text_id}.\nErrors\n{errors:?}") } } diff --git a/src/loader/static_loader.rs b/src/loader/static_loader.rs index 9eb4162..fec3547 100644 --- a/src/loader/static_loader.rs +++ b/src/loader/static_loader.rs @@ -74,7 +74,7 @@ impl super::Loader for StaticLoader { return val; } } - format!("Unknown localization {}", text_id) + format!("Unknown localization {text_id}") } // Traverse the fallback chain,