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