From 40a7f36d14e6e89605d112b54af7190aaaaf31f3 Mon Sep 17 00:00:00 2001 From: Jacob Heider Date: Wed, 8 Jan 2025 11:45:29 -0500 Subject: [PATCH] add feature: "serde" --- .github/workflows/check-and-lint.yaml | 1 + .justfile | 2 +- Cargo.lock | 95 ++++++++++++++++++++++++++- cli/Cargo.toml | 4 +- lib/Cargo.toml | 10 ++- lib/src/range/mod.rs | 23 +++++++ lib/src/semver/mod.rs | 17 +++++ lib/src/tests/range.rs | 22 ++++++- lib/src/tests/semver.rs | 17 +++++ 9 files changed, 183 insertions(+), 8 deletions(-) diff --git a/.github/workflows/check-and-lint.yaml b/.github/workflows/check-and-lint.yaml index 7426cfe..f385a38 100644 --- a/.github/workflows/check-and-lint.yaml +++ b/.github/workflows/check-and-lint.yaml @@ -22,6 +22,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: check + args: --all-features env: RUSTFLAGS: "-D warnings" diff --git a/.justfile b/.justfile index 18370b8..9f5230e 100644 --- a/.justfile +++ b/.justfile @@ -4,7 +4,7 @@ default: # Generate coverage/lcov.info coverage: - cargo tarpaulin --engine ptrace -o lcov --output-dir coverage + cargo tarpaulin --engine ptrace -o lcov --output-dir coverage --all --all-targets --all-features # For getting ptrace as html on macos docker-coverage: diff --git a/Cargo.lock b/Cargo.lock index 0938078..bba2270 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,6 +105,12 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + [[package]] name = "lazy_static" version = "1.5.0" @@ -113,11 +119,14 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libsemverator" -version = "0.8.0" +version = "0.9.0" dependencies = [ "anyhow", "lazy_static", "regex", + "serde", + "serde_json", + "serde_test", ] [[package]] @@ -126,6 +135,24 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + [[package]] name = "regex" version = "1.10.6" @@ -155,21 +182,85 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + [[package]] name = "semverator" -version = "0.8.0" +version = "0.9.0" dependencies = [ "anyhow", "clap", "libsemverator", ] +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.135" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_test" +version = "1.0.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed" +dependencies = [ + "serde", +] + [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "syn" +version = "2.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 690a887..4042982 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "semverator" -version = "0.8.0" +version = "0.9.0" edition = "2021" license = "Apache-2.0" readme = "../README.md" @@ -13,7 +13,7 @@ categories = ["command-line-utilities"] [dependencies] anyhow = "1.0.75" clap = { version = '4.4.2', features = ['cargo'] } -libsemverator = { path = "../lib", version = "0.8.0" } +libsemverator = { path = "../lib", version = "0.9.0" } [lints.rust] unexpected_cfgs = { level = "allow", check-cfg = ['cfg(tarpaulin_include)'] } diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 9d3b113..ce7aaef 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libsemverator" -version = "0.8.0" +version = "0.9.0" edition = "2021" license = "Apache-2.0" readme = "../README.md" @@ -10,6 +10,9 @@ repository = "https://github.com/jhheider/semverator" keywords = ["semver", "semantic", "versioning", "pkgx"] categories = ["command-line-utilities"] +[features] +serde = ["dep:serde", "dep:serde_json"] + [lib] crate-type = ["cdylib", "rlib"] @@ -17,6 +20,11 @@ crate-type = ["cdylib", "rlib"] anyhow = "1.0.75" lazy_static = "1.5.0" regex = "1.9.5" +serde = { version = "1.0.217", optional = true } +serde_json = { version = "1.0.135", optional = true } [lints.rust] unexpected_cfgs = { level = "allow", check-cfg = ['cfg(tarpaulin_include)'] } + +[dev-dependencies] +serde_test = "1.0.177" diff --git a/lib/src/range/mod.rs b/lib/src/range/mod.rs index 467d41b..5bcf869 100644 --- a/lib/src/range/mod.rs +++ b/lib/src/range/mod.rs @@ -1,4 +1,6 @@ use crate::semver::Semver; +#[cfg(feature = "serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::{ fmt, hash::{Hash, Hasher}, @@ -118,3 +120,24 @@ fn at(left: &Semver, right: &Semver) -> bool { true } + +impl PartialEq for Range { + fn eq(&self, other: &Self) -> bool { + self.set == other.set + } +} + +#[cfg(feature = "serde")] +impl Serialize for Range { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(&format!("{self}")) + } +} + +#[cfg(feature = "serde")] +impl<'de> Deserialize<'de> for Range { + fn deserialize>(deserializer: D) -> Result { + let s = String::deserialize(deserializer)?; + Range::parse(&s).map_err(serde::de::Error::custom) + } +} diff --git a/lib/src/semver/mod.rs b/lib/src/semver/mod.rs index e1ea6d6..f976bfd 100644 --- a/lib/src/semver/mod.rs +++ b/lib/src/semver/mod.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt; pub mod bump; @@ -67,3 +69,18 @@ impl fmt::Display for Semver { Ok(()) } } + +#[cfg(feature = "serde")] +impl Serialize for Semver { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(&self.raw) + } +} + +#[cfg(feature = "serde")] +impl<'de> Deserialize<'de> for Semver { + fn deserialize>(deserializer: D) -> Result { + let s = String::deserialize(deserializer)?; + Semver::parse(&s).map_err(serde::de::Error::custom) + } +} diff --git a/lib/src/tests/range.rs b/lib/src/tests/range.rs index 7097d03..d10059e 100644 --- a/lib/src/tests/range.rs +++ b/lib/src/tests/range.rs @@ -1,6 +1,7 @@ -use anyhow::Result; - use crate::{range::Range, semver::Semver}; +use anyhow::Result; +#[cfg(feature = "serde")] +use serde_test::{assert_tokens, Token}; #[test] fn test_parse() -> Result<()> { @@ -279,3 +280,20 @@ fn test_display() -> Result<()> { Ok(()) } + +#[cfg(feature = "serde")] +#[test] +fn test_serde() -> Result<()> { + let ra = Range::parse("^3.7")?; + let rb = Range::parse("=3.11")?; + let rc = Range::parse("^3.9")?; + + assert_tokens(&ra, &[Token::Str("^3.7")]); + assert_tokens(&rb, &[Token::Str("=3.11")]); + assert_tokens(&rc, &[Token::Str("^3.9")]); + + let rd = serde_json::from_str::("\"your mom\""); + assert!(rd.is_err()); + + Ok(()) +} diff --git a/lib/src/tests/semver.rs b/lib/src/tests/semver.rs index 24fbbde..a9623d6 100644 --- a/lib/src/tests/semver.rs +++ b/lib/src/tests/semver.rs @@ -1,5 +1,7 @@ use crate::semver::{bump::SemverComponent, Semver}; use anyhow::Result; +#[cfg(feature = "serde")] +use serde_test::{assert_tokens, Token}; #[test] fn test_parse() -> Result<()> { @@ -181,3 +183,18 @@ fn test_display() -> Result<()> { Ok(()) } + +#[cfg(feature = "serde")] +#[test] +fn test_serde() -> Result<()> { + let a = Semver::parse("1.2.3")?; + let b = Semver::parse("1.2.4")?; + + assert_tokens(&a, &[Token::Str("1.2.3")]); + assert_tokens(&b, &[Token::Str("1.2.4")]); + + let c = serde_json::from_str::("\"your mom\""); + assert!(c.is_err()); + + Ok(()) +}