Repository: maciejhirsz/json-rust (rust)

Issue:
Equality on tree should work despite the fact that there are two constructors `Short` and `String`
... otherwise, we can end up with two values that should be equal but are not.

Pull request:
Resolves #126 - Equality on JsonValue should not differentiate betwee…
…n Short and String

Patch:
diff --git a/src/value/mod.rs b/src/value/mod.rs
index 2d1f58b..5671e1c 100644
--- a/src/value/mod.rs
+++ b/src/value/mod.rs
@@ -34,7 +34,7 @@ macro_rules! number_to_signed {
     }
 }
 
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, Clone)]
 pub enum JsonValue {
     Null,
     Short(Short),
@@ -45,6 +45,25 @@ pub enum JsonValue {
     Array(Vec<JsonValue>),
 }
 
+impl PartialEq for JsonValue {
+    fn eq(&self, other: &Self) -> bool {
+        use self::JsonValue::*;
+        match (self, other) {
+            (&Null, &Null) => true,
+            (&Short(ref a), &Short(ref b)) => a == b,
+            (&String(ref a), &String(ref b)) => a == b,
+            (&Short(ref a), &String(ref b))
+            | (&String(ref b), &Short(ref a)) => a.as_str() == b.as_str(),
+            (&Number(ref a), &Number(ref b)) => a == b,
+            (&Boolean(ref a), &Boolean(ref b)) => a == b,
+            (&Object(ref a), &Object(ref b)) => a == b,
+            (&Array(ref a), &Array(ref b)) => a == b,
+            _ => false,
+        }
+    }
+}
+
+impl Eq for JsonValue {}
 
 /// Implements formatting
 ///


Test patch:
diff --git a/tests/value.rs b/tests/value.rs
index e508e8d..7a7618b 100644
--- a/tests/value.rs
+++ b/tests/value.rs
@@ -621,3 +621,41 @@ fn pretty_writer_generator() {
 
     assert_eq!(String::from_utf8(buf).unwrap(), "{\n    \"foo\": [\n        \"bar\",\n        100,\n        true\n    ]\n}");
 }
+
+#[test]
+fn equality() {
+    let left = object!{
+        "foo" => array!["bar", 100, true]
+    };
+
+    let left_copy = object!{
+        "foo" => array!["bar", 100, true]
+    };
+
+    let left_string = object!{
+        "foo" => array![JsonValue::String("bar".to_string()), 100, true]
+    };
+
+    let left_short = object!{
+        "foo" => array![JsonValue::Short(unsafe { json::short::Short::from_slice("bar") }), 100, true]
+    };
+
+    let change_bool = object!{
+        "foo" => array!["bar", 100, false]
+    };
+
+    let change_string = object!{
+        "foo" => array![JsonValue::String("sna".to_string()), 100, true]
+    };
+
+    let change_short = object!{
+        "foo" => array![JsonValue::Short(unsafe { json::short::Short::from_slice("sna") }), 100, true]
+    };
+
+    assert_eq!(left, left_copy);
+    assert_eq!(left, left_string);
+    assert_eq!(left, left_short);
+    assert_ne!(left, change_bool);
+    assert_ne!(left, change_string);
+    assert_ne!(left, change_short);
+}