1use serde::Deserialize;
5use serde::Serialize;
6
7use crate::Diff;
8use std::fmt::Debug;
9use std::fmt::Formatter;
10
11#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Default)]
13#[serde(transparent)]
14pub struct DiffString(#[serde(skip_serializing_if = "Option::is_none")] pub Option<String>);
15
16impl Diff for String {
18 type Type = DiffString;
20
21 fn diff(&self, other: &Self) -> crate::Result<Self::Type> {
23 if self == other {
24 Ok(DiffString(None))
25 } else {
26 other.clone().into_diff()
27 }
28 }
29
30 fn merge(&self, diff: Self::Type) -> crate::Result<Self> {
32 if diff.0.is_none() {
33 Ok(self.to_string())
34 } else {
35 Self::from_diff(diff)
36 }
37 }
38
39 fn from_diff(diff: Self::Type) -> crate::Result<Self> {
41 match diff.0 {
42 Some(s) => Ok(s),
43 None => Err(crate::Error::ConversionError(
44 "Problem converting from DiffString".into(),
45 )),
46 }
47 }
48
49 fn into_diff(self) -> crate::Result<Self::Type> {
51 Ok(DiffString(Some(self)))
52 }
53}
54
55impl Debug for DiffString {
57 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
58 match &self.0 {
59 Some(val) => write!(f, "DiffString({:#?})", val),
60 None => write!(f, "DiffString None"),
61 }
62 }
63}
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn test_string_diff() {
70 let sa = String::from("test");
71 let sb = String::from("another_string");
72
73 let diff = sa.diff(&sb).unwrap();
74
75 assert_eq!(diff, DiffString(Some("another_string".into())));
76
77 let sc = sa.merge(diff).unwrap();
78
79 assert_eq!(sb, sc);
80 }
81
82 #[test]
83 fn test_same_string() {
84 let sa = String::from("test");
85 let sb = String::from("test");
86
87 let diff = sa.diff(&sb).unwrap();
88
89 assert_eq!(diff, DiffString(None));
90
91 let sc = sa.merge(diff).unwrap();
92
93 assert_eq!(sb, sc);
94 assert_eq!(sa, sc);
95 }
96}