diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0619ea..c5e9717 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,12 @@ jobs: command: test args: --features arbitrary + - name: cargo test --all-features + uses: actions-rs/cargo@v1 + with: + command: test + args: --all-features + rustfmt: name: Rustfmt runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a7782d..9ed8a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### Next +* Add `serde` feature (`Serialize` and `Deserialize` for `Lang` and `Script`). + ### v0.16.2 - 2022-10-23 * Support [Arbitrary](https://crates.io/crates/arbitrary) diff --git a/Cargo.toml b/Cargo.toml index d63b3d1..ce1d60f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ include = [ hashbrown = "0.12.0" once_cell = "1.10.0" enum-map = { version = "2", optional = true } +serde = { version = "1", optional = true, features = ["derive"] } arbitrary = { version = "1", optional = true, features = ["derive"] } [dev-dependencies] diff --git a/README.md b/README.md index 40f7fc1..5a2c3b3 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,8 @@ You're gonna be in a great company using Whatlang: | Feature | Description | |-------------|---------------------------------------------------------------------------------------| | `enum-map` | `Lang` and `Script` implement `Enum` trait from [enum-map](https://docs.rs/enum-map/) | -| `arbitrary` | Support [Arbitrary](https://crates.io/crates/arbitrary) | +| `arbitrary` | Support [Arbitrary](https://crates.io/crates/arbitrary) | +| `serde` | Implements `Serialize` and `Deserialize` for `Lang` and `Script` | | `dev` | Enables `whatlang::dev` module which provides some internal API.
It exists for profiling purposes and normal users are discouraged to to rely on this API. | ## How does it work? diff --git a/src/core/filter_list.rs b/src/core/filter_list.rs index 3e12341..eed86d4 100644 --- a/src/core/filter_list.rs +++ b/src/core/filter_list.rs @@ -1,8 +1,9 @@ use crate::Lang; #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub enum FilterList { + #[default] All, Allow(Vec), Deny(Vec), @@ -18,25 +19,19 @@ impl FilterList { Self::Allow(allowlist) } - pub fn deny(blacklist: Vec) -> Self { - Self::Deny(blacklist) + pub fn deny(denylist: Vec) -> Self { + Self::Deny(denylist) } pub fn is_allowed(&self, lang: Lang) -> bool { match self { Self::All => true, Self::Allow(ref allowlist) => allowlist.contains(&lang), - Self::Deny(ref blacklist) => !blacklist.contains(&lang), + Self::Deny(ref denylist) => !denylist.contains(&lang), } } } -impl Default for FilterList { - fn default() -> Self { - FilterList::All - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/core/method.rs b/src/core/method.rs index 76ec97c..8c40266 100644 --- a/src/core/method.rs +++ b/src/core/method.rs @@ -3,10 +3,11 @@ use std::fmt; use std::str::FromStr; #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub enum Method { Trigram, Alphabet, + #[default] Combined, } @@ -34,12 +35,6 @@ impl fmt::Display for Method { } } -impl Default for Method { - fn default() -> Self { - Method::Combined - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/lang.rs b/src/lang.rs index b0e034b..ba84ff3 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -10,6 +10,11 @@ use crate::error::ParseError; /// Represents a language following [ISO 639-3](https://en.wikipedia.org/wiki/ISO_639-3) standard. #[cfg_attr(feature = "enum-map", derive(::enum_map::Enum))] #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr( + feature = "serde", + derive(::serde::Serialize, ::serde::Deserialize), + serde(rename_all = "lowercase") +)] #[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)] pub enum Lang { /// Esperanto (Esperanto) @@ -721,4 +726,14 @@ mod tests { assert_eq!(Lang::Deu.to_string(), "Deutsch"); assert_eq!(Lang::Eng.to_string(), "English"); } + + #[cfg(feature = "serde")] + #[test] + fn test_serialize_and_deserialize() { + let langs = vec![Lang::Epo, Lang::Ukr, Lang::Spa]; + let json_langs = serde_json::to_string(&langs).unwrap(); + assert_eq!(json_langs, r#"["epo","ukr","spa"]"#); + let parsed_langs: Vec = serde_json::from_str(&json_langs).unwrap(); + assert_eq!(parsed_langs, langs); + } } diff --git a/src/lib.rs b/src/lib.rs index f95c27d..e48f39a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,10 +34,12 @@ //! //! # Features //! -//! | Feature | Description | -//! |------------|---------------------------------------------------------------------------------------| -//! | `enum-map` | `Lang` and `Script` implement `Enum` trait from [enum-map](https://docs.rs/enum-map/) | -//! +//! | Feature | Description | +//! |-------------|---------------------------------------------------------------------------------------| +//! | `enum-map` | `Lang` and `Script` implement `Enum` trait from [enum-map](https://docs.rs/enum-map/) | +//! | `arbitrary` | Support [Arbitrary](https://crates.io/crates/arbitrary) | +//! | `serde` | Implements `Serialize` and `Deserialize` for `Lang` and `Script` | +//! | `dev` | Enables `whatlang::dev` module which provides some internal API.
It exists for profiling purposes and normal users are discouraged to to rely on this API. | //! mod alphabets; mod combined; diff --git a/src/scripts/script.rs b/src/scripts/script.rs index be839cd..cd0e8ef 100644 --- a/src/scripts/script.rs +++ b/src/scripts/script.rs @@ -8,6 +8,7 @@ use crate::Lang; /// Represents a writing system (Latin, Cyrillic, Arabic, etc). #[cfg_attr(feature = "enum-map", derive(::enum_map::Enum))] #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))] +#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))] #[derive(PartialEq, Eq, Debug, Clone, Copy, Hash)] pub enum Script { // Keep this in alphabetic order (for C bindings) @@ -205,4 +206,14 @@ mod tests { assert_eq!(Script::Cyrillic.to_string(), "Cyrillic"); assert_eq!(Script::Arabic.to_string(), "Arabic"); } + + #[cfg(feature = "serde")] + #[test] + fn test_serialize_and_deserialize() { + let scripts = vec![Script::Georgian, Script::Cyrillic]; + let json_scripts = serde_json::to_string(&scripts).unwrap(); + assert_eq!(json_scripts, r#"["Georgian","Cyrillic"]"#); + let parsed_scripts: Vec