summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_with/tests/indexmap.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/serde_with/tests/indexmap.rs')
-rw-r--r--third_party/rust/serde_with/tests/indexmap.rs285
1 files changed, 285 insertions, 0 deletions
diff --git a/third_party/rust/serde_with/tests/indexmap.rs b/third_party/rust/serde_with/tests/indexmap.rs
new file mode 100644
index 0000000000..7e46b9c5c5
--- /dev/null
+++ b/third_party/rust/serde_with/tests/indexmap.rs
@@ -0,0 +1,285 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+mod utils;
+
+use crate::utils::{check_deserialization, check_error_deserialization, is_equal};
+use core::iter::FromIterator;
+use expect_test::expect;
+use indexmap_crate::{IndexMap, IndexSet};
+use serde::{Deserialize, Serialize};
+use serde_with::{serde_as, DisplayFromStr, Same};
+use std::net::IpAddr;
+
+#[test]
+fn test_indexmap() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "IndexMap<DisplayFromStr, DisplayFromStr>")] IndexMap<u8, u32>);
+
+ // Normal
+ is_equal(
+ S([(1, 1), (3, 3), (111, 111)].iter().cloned().collect()),
+ expect![[r#"
+ {
+ "1": "1",
+ "3": "3",
+ "111": "111"
+ }"#]],
+ );
+ is_equal(S(IndexMap::default()), expect![[r#"{}"#]]);
+}
+
+#[test]
+fn test_indexset() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "IndexSet<DisplayFromStr>")] IndexSet<u32>);
+
+ // Normal
+ is_equal(
+ S([1, 2, 3, 4, 5].iter().cloned().collect()),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5"
+ ]"#]],
+ );
+ is_equal(S(IndexSet::default()), expect![[r#"[]"#]]);
+}
+
+#[test]
+fn test_map_as_tuple_list() {
+ let ip = "1.2.3.4".parse().unwrap();
+ let ip2 = "255.255.255.255".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SI(#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr)>")] IndexMap<u32, IpAddr>);
+
+ let map: IndexMap<_, _> = vec![(1, ip), (10, ip), (200, ip2)].into_iter().collect();
+ is_equal(
+ SI(map.clone()),
+ expect![[r#"
+ [
+ [
+ "1",
+ "1.2.3.4"
+ ],
+ [
+ "10",
+ "1.2.3.4"
+ ],
+ [
+ "200",
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SI2(#[serde_as(as = "Vec<(Same, DisplayFromStr)>")] IndexMap<u32, IpAddr>);
+
+ is_equal(
+ SI2(map),
+ expect![[r#"
+ [
+ [
+ 1,
+ "1.2.3.4"
+ ],
+ [
+ 10,
+ "1.2.3.4"
+ ],
+ [
+ 200,
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+}
+
+#[test]
+fn test_tuple_list_as_map() {
+ let ip = "1.2.3.4".parse().unwrap();
+ let ip2 = "255.255.255.255".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SI(
+ #[serde_as(as = "std::collections::HashMap<DisplayFromStr, DisplayFromStr>")]
+ IndexSet<(u32, IpAddr)>,
+ );
+
+ is_equal(
+ SI(IndexSet::from_iter(vec![(1, ip), (10, ip), (200, ip2)])),
+ expect![[r#"
+ {
+ "1": "1.2.3.4",
+ "10": "1.2.3.4",
+ "200": "255.255.255.255"
+ }"#]],
+ );
+}
+
+#[test]
+fn duplicate_key_first_wins_indexmap() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::maps_first_key_wins")] IndexMap<usize, usize>);
+
+ // Different value and key always works
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 2,
+ "3": 3
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 1,
+ "3": 1
+ }"#]],
+ );
+
+ // Duplicate keys, the first one is used
+ check_deserialization(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 2)])),
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ );
+}
+
+#[test]
+fn prohibit_duplicate_key_indexmap() {
+ #[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] IndexMap<usize, usize>,
+ );
+
+ // Different value and key always works
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 2,
+ "3": 3
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 1,
+ "3": 1
+ }"#]],
+ );
+
+ // Duplicate keys are an error
+ check_error_deserialization::<S>(
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ expect![[r#"invalid entry: found duplicate key at line 1 column 24"#]],
+ );
+}
+
+#[test]
+fn duplicate_value_last_wins_indexset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_last_value_wins")] IndexSet<W>);
+
+ #[derive(Debug, Eq, Deserialize, Serialize)]
+ struct W(i32, bool);
+ impl PartialEq for W {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+ impl std::hash::Hash for W {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: std::hash::Hasher,
+ {
+ self.0.hash(state)
+ }
+ }
+
+ // Different values always work
+ is_equal(
+ S(IndexSet::from_iter(vec![
+ W(1, true),
+ W(2, false),
+ W(3, true),
+ ])),
+ expect![[r#"
+ [
+ [
+ 1,
+ true
+ ],
+ [
+ 2,
+ false
+ ],
+ [
+ 3,
+ true
+ ]
+ ]"#]],
+ );
+
+ let value: S = serde_json::from_str(
+ r#"[
+ [1, false],
+ [1, true],
+ [2, true],
+ [2, false]
+ ]"#,
+ )
+ .unwrap();
+ let entries: Vec<_> = value.0.into_iter().collect();
+ assert_eq!(1, entries[0].0);
+ assert!(entries[0].1);
+ assert_eq!(2, entries[1].0);
+ assert!(!entries[1].1);
+}
+
+#[test]
+fn prohibit_duplicate_value_indexset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] IndexSet<usize>);
+
+ is_equal(
+ S(IndexSet::from_iter(vec![1, 2, 3, 4])),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 4
+ ]"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"[1, 2, 3, 4, 1]"#,
+ expect![[r#"invalid entry: found duplicate value at line 1 column 15"#]],
+ );
+}