1
macro_rules! test_non_tag {
2
    ($test_name:ident => $deserialize_method:ident($($deserialize_param:expr),*)) => {
3
        #[test]
4
100
        fn $test_name() {
5
            use serde::{Deserialize, Deserializer, de::Visitor};
6

            
7
            struct TagVisitor;
8

            
9
            impl<'de> Visitor<'de> for TagVisitor {
10
                type Value = Tag;
11

            
12
                // GRCOV_EXCL_START
13
                fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
14
                    fmt.write_str("an error")
15
                }
16
                // GRCOV_EXCL_STOP
17
            }
18

            
19
            struct Tag;
20

            
21
            impl<'de> Deserialize<'de> for Tag {
22
100
                fn deserialize<D: Deserializer<'de>>(deserializer: D)
23
100
                    -> Result<Self, D::Error>
24
100
                {
25
100
                    deserializer.$deserialize_method($($deserialize_param,)* TagVisitor)
26
100
                }
27
            }
28

            
29
            #[derive(Debug)] // GRCOV_EXCL_LINE
30
            struct InternallyTagged;
31

            
32
            impl<'de> Deserialize<'de> for InternallyTagged {
33
100
                fn deserialize<D: Deserializer<'de>>(deserializer: D)
34
100
                    -> Result<Self, D::Error>
35
100
                {
36
100
                    deserializer.deserialize_any(serde::__private::de::TaggedContentVisitor::<
37
100
                        Tag,
38
100
                    >::new(
39
100
                        "tag",
40
100
                        "an internally tagged value",
41
100
                    )).map(|_| unreachable!())
42
100
                }
43
            }
44

            
45
100
            assert_eq!(
46
100
                ron::from_str::<InternallyTagged>("(tag: err)").unwrap_err().code,
47
100
                ron::Error::ExpectedString
48
100
            )
49
100
        }
50
    };
51
}
52

            
53
test_non_tag! { test_bool => deserialize_bool() }
54
test_non_tag! { test_i8 => deserialize_i8() }
55
test_non_tag! { test_i16 => deserialize_i16() }
56
test_non_tag! { test_i32 => deserialize_i32() }
57
test_non_tag! { test_i64 => deserialize_i64() }
58
#[cfg(feature = "integer128")]
59
test_non_tag! { test_i128 => deserialize_i128() }
60
test_non_tag! { test_u8 => deserialize_u8() }
61
test_non_tag! { test_u16 => deserialize_u16() }
62
test_non_tag! { test_u32 => deserialize_u32() }
63
test_non_tag! { test_u64 => deserialize_u64() }
64
#[cfg(feature = "integer128")]
65
test_non_tag! { test_u128 => deserialize_u128() }
66
test_non_tag! { test_f32 => deserialize_f32() }
67
test_non_tag! { test_f64 => deserialize_f64() }
68
test_non_tag! { test_char => deserialize_char() }
69
test_non_tag! { test_bytes => deserialize_bytes() }
70
test_non_tag! { test_byte_buf => deserialize_byte_buf() }
71
test_non_tag! { test_option => deserialize_option() }
72
test_non_tag! { test_unit => deserialize_unit() }
73
test_non_tag! { test_unit_struct => deserialize_unit_struct("") }
74
test_non_tag! { test_newtype_struct => deserialize_newtype_struct("") }
75
test_non_tag! { test_seq => deserialize_seq() }
76
test_non_tag! { test_tuple => deserialize_tuple(0) }
77
test_non_tag! { test_tuple_struct => deserialize_tuple_struct("", 0) }
78
test_non_tag! { test_map => deserialize_map() }
79
test_non_tag! { test_struct => deserialize_struct("", &[]) }
80
test_non_tag! { test_enum => deserialize_enum("", &[]) }
81

            
82
macro_rules! test_tag {
83
    ($test_name:ident => $deserialize_method:ident($($deserialize_param:expr),*)) => {
84
        #[test]
85
20
        fn $test_name() {
86
            use serde::{Deserialize, Deserializer, de::Visitor};
87

            
88
            struct TagVisitor;
89

            
90
            impl<'de> Visitor<'de> for TagVisitor {
91
                type Value = Tag;
92

            
93
                // GRCOV_EXCL_START
94
                fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
95
                    fmt.write_str("a tag")
96
                }
97
                // GRCOV_EXCL_STOP
98

            
99
20
                fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
100
20
                    assert_eq!(v, "tag");
101
20
                    Ok(Tag)
102
20
                }
103
            }
104

            
105
            struct Tag;
106

            
107
            impl<'de> Deserialize<'de> for Tag {
108
20
                fn deserialize<D: Deserializer<'de>>(deserializer: D)
109
20
                    -> Result<Self, D::Error>
110
20
                {
111
20
                    deserializer.$deserialize_method($($deserialize_param,)* TagVisitor)
112
20
                }
113
            }
114

            
115
            #[derive(Debug)] // GRCOV_EXCL_LINE
116
            struct InternallyTagged;
117

            
118
            impl<'de> Deserialize<'de> for InternallyTagged {
119
20
                fn deserialize<D: Deserializer<'de>>(deserializer: D)
120
20
                    -> Result<Self, D::Error>
121
20
                {
122
20
                    deserializer.deserialize_any(serde::__private::de::TaggedContentVisitor::<
123
20
                        Tag,
124
20
                    >::new(
125
20
                        "tag",
126
20
                        "an internally tagged value",
127
20
                    )).map(|_| InternallyTagged)
128
20
                }
129
            }
130

            
131
20
            assert!(
132
20
                ron::from_str::<InternallyTagged>("(tag: \"tag\")").is_ok(),
133
20
            )
134
20
        }
135
    };
136
}
137

            
138
test_tag! { test_str => deserialize_string() }
139
test_tag! { test_string => deserialize_string() }
140
test_tag! { test_identifier => deserialize_identifier() }
141

            
142
test_tag! { test_any => deserialize_any() }
143
test_tag! { test_ignored_any => deserialize_ignored_any() }