Skip to content

Commit

Permalink
Merge pull request #155 from Baptistemontan/fix_serde_cfg
Browse files Browse the repository at this point in the history
Simplify internal cfgs
  • Loading branch information
Baptistemontan authored Nov 3, 2024
2 parents ea8e755 + d7aad16 commit b3d2ae3
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 93 deletions.
8 changes: 4 additions & 4 deletions leptos_i18n_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ readme = "../README.md"
icu = "1.5"
serde = { version = "1", features = ["rc"] }
serde_json = { version = "1" }
serde_yaml = { version = "0.9", optional = true }
serde_yaml = { version = "0.9" }
toml = "0.8"
fixed_decimal = { version = "0.5", features = ["ryu"] }
json5 = { version = "0.4", optional = true }
json5 = { version = "0.4" }
quote = { version = "1", optional = true }
syn = { version = "2.0", optional = true }
proc-macro2 = { version = "1", optional = true }
Expand All @@ -24,8 +24,8 @@ proc-macro2 = { version = "1", optional = true }
default = ["json_files"]
quote = ["dep:quote", "dep:syn", "dep:proc-macro2"]
json_files = []
yaml_files = ["dep:serde_yaml"]
json5_files = ["dep:json5"]
yaml_files = []
json5_files = []
plurals = []
format_datetime = []
format_list = []
Expand Down
4 changes: 4 additions & 0 deletions leptos_i18n_parser/src/parse_locales/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ pub enum Error {
locale: Key,
key_path: KeyPath,
},
NoFileFormats,
MultipleFilesFormats,
}

impl Display for Error {
Expand Down Expand Up @@ -204,6 +206,8 @@ impl Display for Error {
Error::PluralsAtNormalKey { key_path, locale } => write!(f, "In locale {:?} at key \"{}\", Found plurals but a key of that name is already present.", locale, key_path),
Error::DisabledFormatter { locale, key_path, formatter } => write!(f, "{}, at key \"{}\" in locale {:?}", formatter.err_message(), key_path, locale),
Error::DisabledPlurals { locale, key_path } => write!(f, "Plurals are not enabled, enable the \"plurals\" feature to use them, at key \"{}\" in locale {:?}", key_path, locale),
Error::NoFileFormats => write!(f, "No file formats has been provided for leptos_i18n. Supported formats are: json, json5 and yaml."),
Error::MultipleFilesFormats => write!(f, "Multiple file formats have been provided for leptos_i18n, choose only one. Supported formats are: json, json5 and yaml."),
}
}
}
Expand Down
154 changes: 65 additions & 89 deletions leptos_i18n_parser/src/parse_locales/locale.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,106 +15,71 @@ use super::ranges::RangeType;
use super::warning::{Warning, Warnings};
use super::{ForeignKeysPaths, StringIndexer, VAR_COUNT_KEY};

macro_rules! define_by_format {
(json => $($tt:tt)*) => {
#[cfg(all(feature = "json_files", not(any(feature = "yaml_files", feature = "json5_files"))))]
$($tt)*
};
(yaml => $($tt:tt)*) => {
#[cfg(all(feature = "yaml_files", not(any(feature = "json_files", feature = "json5_files"))))]
$($tt)*
};
(json5 => $($tt:tt)*) => {
#[cfg(all(feature = "json5_files", not(any(feature = "json_files", feature = "yaml_files"))))]
$($tt)*
};
(none => $($tt:tt)*) => {
#[cfg(not(any(feature = "json_files", feature = "yaml_files", feature = "json5_files")))]
$($tt)*
};
// This is attrocious, found a better way fgs
(multiple => $($tt:tt)*) => {
#[cfg(any(all(feature = "json_files", feature = "yaml_files"), all(feature = "json_files", feature = "json5_files"), all(feature = "yaml_files", feature = "json5_files")))]
$($tt)*
}
}

macro_rules! define_error {
($ident:ident => $t:ty) => {
define_by_format!($ident => pub type SerdeError = $t;);
};
}

macro_rules! define_files_exts {
($ident:ident => $($lit:literal),*) => {
define_by_format!($ident => const FILE_EXTS: &[&str] = &[$($lit,)*];);
};
($ident:ident) => {
define_by_format!($ident => const FILE_EXTS: &[&str] = &[];);
};
}

#[cfg(feature = "json5_files")]
#[derive(Debug)]
pub enum Json5Error {
Serde(json5::Error),
pub enum SerdeError {
Json(serde_json::Error),
Yaml(serde_yaml::Error),
Json5(json5::Error),
Io(std::io::Error),
None,
Multiple,
}

#[cfg(feature = "json5_files")]
impl std::fmt::Display for Json5Error {
impl std::fmt::Display for SerdeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Json5Error::Serde(error) => std::fmt::Display::fmt(error, f),
Json5Error::Io(error) => std::fmt::Display::fmt(error, f),
SerdeError::Json(error) => std::fmt::Display::fmt(error, f),
SerdeError::Yaml(error) => std::fmt::Display::fmt(error, f),
SerdeError::Json5(error) => std::fmt::Display::fmt(error, f),
SerdeError::Io(error) => std::fmt::Display::fmt(error, f),
SerdeError::None => write!(f, "No file formats has been provided for leptos_i18n. Supported formats are: json, json5 and yaml."),
SerdeError::Multiple => write!(f, "Multiple file formats have been provided for leptos_i18n, choose only one. Supported formats are: json, json5 and yaml."),
}
}
}

define_error!(json => serde_json::Error);
define_error!(json5 => Json5Error);
define_error!(yaml => serde_yaml::Error);
define_error!(none => &'static str); // whatever impl Display
define_error!(multiple => &'static str); // whatever impl Display

define_files_exts!(json => "json");
define_files_exts!(json5 => "json5");
define_files_exts!(yaml => "yaml", "yml");
define_files_exts!(none);
define_files_exts!(multiple);

define_by_format!(json =>
fn de_inner<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let mut deserializer = serde_json::Deserializer::from_reader(locale_file);
serde::de::DeserializeSeed::deserialize(seed, &mut deserializer)
}
);
define_by_format!(json5 =>
fn de_inner<R: Read>(mut locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let mut buff = String::new();
Read::read_to_string(&mut locale_file, &mut buff).map_err(Json5Error::Io)?;
let mut deserializer = json5::Deserializer::from_str(&buff).map_err(Json5Error::Serde)?;
serde::de::DeserializeSeed::deserialize(seed, &mut deserializer).map_err(Json5Error::Serde)
}
);
define_by_format!(yaml =>
fn de_inner<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let deserializer = serde_yaml::Deserializer::from_reader(locale_file);
serde::de::DeserializeSeed::deserialize(seed, deserializer)
}
);
define_by_format!(none =>
fn de_inner<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let _ = (locale_file, seed);
compile_error!("No file format has been provided for leptos_i18n, supported formats are: json and yaml")
const fn get_files_exts() -> &'static [&'static str] {
if cfg!(feature = "json_files") {
&["json"]
} else if cfg!(feature = "yaml_files") {
&["yaml", "yml"]
} else if cfg!(feature = "json5_files") {
&["json5"]
} else {
&[]
}
);
define_by_format!(multiple =>
fn de_inner<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let _ = (locale_file, seed);
compile_error!("Multiple file format have been provided for leptos_i18n, choose only one, supported formats are: json and yaml")
}

const FILE_EXTS: &[&str] = get_files_exts();

fn de_inner_json<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let mut deserializer = serde_json::Deserializer::from_reader(locale_file);
serde::de::DeserializeSeed::deserialize(seed, &mut deserializer).map_err(SerdeError::Json)
}

fn de_inner_json5<R: Read>(mut locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let mut buff = String::new();
Read::read_to_string(&mut locale_file, &mut buff).map_err(SerdeError::Io)?;
let mut deserializer = json5::Deserializer::from_str(&buff).map_err(SerdeError::Json5)?;
serde::de::DeserializeSeed::deserialize(seed, &mut deserializer).map_err(SerdeError::Json5)
}

fn de_inner_yaml<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
let deserializer = serde_yaml::Deserializer::from_reader(locale_file);
serde::de::DeserializeSeed::deserialize(seed, deserializer).map_err(SerdeError::Yaml)
}

fn de_inner<R: Read>(locale_file: R, seed: LocaleSeed) -> Result<Locale, SerdeError> {
if cfg!(feature = "json_files") {
de_inner_json(locale_file, seed)
} else if cfg!(feature = "yaml_files") {
de_inner_yaml(locale_file, seed)
} else if cfg!(feature = "json5_files") {
de_inner_json5(locale_file, seed)
} else {
unreachable!()
}
);
}

#[derive(Debug, Clone, PartialEq)]
pub struct Locale {
Expand Down Expand Up @@ -216,7 +181,18 @@ fn find_file(path: &mut PathBuf) -> Result<File> {
};
}

Err(Error::LocaleFileNotFound(errs))
#[allow(clippy::const_is_empty)]
if !FILE_EXTS.is_empty() {
Err(Error::LocaleFileNotFound(errs))
} else if cfg!(any(
feature = "json_files",
feature = "yaml_files",
feature = "json5_files"
)) {
Err(Error::MultipleFilesFormats)
} else {
Err(Error::NoFileFormats)
}
}

impl InterpolOrLit {
Expand Down

0 comments on commit b3d2ae3

Please sign in to comment.