From f0e38d862bf003561c3fa998947de169f6655fe3 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sun, 3 Oct 2021 08:46:57 +0200 Subject: [PATCH] Added optional serde support --- CHANGELOG.md | 1 + Cargo.toml | 2 ++ src/lib.rs | 2 ++ src/text/inline.rs | 18 ++++++++++++++++++ src/text/mod.rs | 28 ++++++++++++++++++++++++++++ src/types.rs | 21 +++++++++++++++++++++ 6 files changed, 72 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed6f6c2..ba72a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to similar are documented here. ## 2.1.0 * Removed deprecated alternative slice diffing functions. +* Added `serde` feature to allow serialization with serde. ## 2.0.0 diff --git a/Cargo.toml b/Cargo.toml index 8c3ce13..4709142 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,10 +28,12 @@ bytes = ["bstr", "text"] [dev-dependencies] insta = "1.6.2" console = "0.14.0" +serde_json = "1.0.68" [dependencies] unicode-segmentation = { version = "1.7.1", optional = true } bstr = { version = "0.2.14", optional = true, default-features = false } +serde = { version = "1.0.130", optional = true, features = ["derive"] } [[example]] name = "patience" diff --git a/src/lib.rs b/src/lib.rs index 57b63c2..8741285 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,6 +142,8 @@ //! * `inline`: this feature gives access to additional functionality of the //! text diffing to provide inline information about which values changed //! in a line diff. This currently also enables the `unicode` feature. +//! * `serde`: this feature enables serialization to some types in this +//! crate. For enums without payload deserialization is then also supported. #![warn(missing_docs)] pub mod algorithms; pub mod iter; diff --git a/src/text/inline.rs b/src/text/inline.rs index 5b221ba..a6079c2 100644 --- a/src/text/inline.rs +++ b/src/text/inline.rs @@ -107,6 +107,7 @@ fn push_values<'s, T: DiffableStr + ?Sized>( /// /// This is like [`Change`] but with inline highlight info. #[derive(Debug, PartialEq, Eq, Hash, Clone, Ord, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] pub struct InlineChange<'s, T: DiffableStr + ?Sized> { tag: ChangeTag, old_index: Option, @@ -317,3 +318,20 @@ fn test_line_ops_inline() { .collect::>(); insta::assert_debug_snapshot!(&changes); } + +#[test] +#[cfg(feature = "serde")] +fn test_serde() { + let diff = TextDiff::from_lines( + "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff", + "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n", + ); + assert_eq!(diff.newline_terminated(), true); + let changes = diff + .ops() + .iter() + .flat_map(|op| diff.iter_inline_changes(op)) + .collect::>(); + let json = serde_json::to_string_pretty(&changes).unwrap(); + insta::assert_snapshot!(&json); +} diff --git a/src/text/mod.rs b/src/text/mod.rs index d9a11a2..b1a45f3 100644 --- a/src/text/mod.rs +++ b/src/text/mod.rs @@ -740,3 +740,31 @@ fn test_lifetimes_on_iter() { let changes = diff_lines(&a, &b); insta::assert_debug_snapshot!(&changes); } + +#[test] +#[cfg(feature = "serde")] +fn test_serde() { + let diff = TextDiff::from_lines( + "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff", + "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n", + ); + let changes = diff + .ops() + .iter() + .flat_map(|op| diff.iter_changes(op)) + .collect::>(); + let json = serde_json::to_string_pretty(&changes).unwrap(); + insta::assert_snapshot!(&json); +} + +#[test] +#[cfg(feature = "serde")] +fn test_serde_ops() { + let diff = TextDiff::from_lines( + "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff", + "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n", + ); + let changes = diff.ops(); + let json = serde_json::to_string_pretty(&changes).unwrap(); + insta::assert_snapshot!(&json); +} diff --git a/src/types.rs b/src/types.rs index c5ca854..8967676 100644 --- a/src/types.rs +++ b/src/types.rs @@ -7,6 +7,11 @@ use crate::iter::ChangesIter; /// An enum representing a diffing algorithm. #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] pub enum Algorithm { /// Picks the myers algorithm from [`crate::algorithms::myers`] Myers, @@ -25,6 +30,11 @@ impl Default for Algorithm { /// The tag of a change. #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Ord, PartialOrd)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] pub enum ChangeTag { /// The change indicates equality (not a change) Equal, @@ -59,6 +69,7 @@ impl fmt::Display for ChangeTag { /// This type has additional methods that are only available for types /// implementing [`DiffableStr`](crate::text::DiffableStr). #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Ord, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] pub struct Change { pub(crate) tag: ChangeTag, pub(crate) old_index: Option, @@ -98,6 +109,11 @@ impl Change { /// /// This is used by [`Capture`](crate::algorithms::Capture). #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case", tag = "op") +)] pub enum DiffOp { /// A segment is equal (see [`DiffHook::equal`]) Equal { @@ -141,6 +157,11 @@ pub enum DiffOp { /// The tag of a diff operation. #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Ord, PartialOrd)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "snake_case") +)] pub enum DiffTag { /// The diff op encodes an equal segment. Equal,