Skip to content

Commit 10af2fd

Browse files
committed
Do not use serde private types
1 parent 91602f8 commit 10af2fd

File tree

2 files changed

+23
-87
lines changed

2 files changed

+23
-87
lines changed

src/slack/mod.rs

+9-87
Original file line numberDiff line numberDiff line change
@@ -198,97 +198,19 @@ pub struct LinkSharedMessage {
198198
pub event_ts: String,
199199
}
200200

201-
#[derive(Debug)]
202-
// tag: subtype
203-
pub enum Message {
201+
#[derive(Debug, Deserialize)]
202+
#[serde(tag = "subtype")]
203+
#[serde(rename_all = "snake_case")]
204+
pub enum TaggedMessage {
204205
BotMessage(BotMessage),
205206
ChannelJoin(ChannelJoinMessage),
206-
BasicMessage(BasicMessage),
207207
}
208208

209-
impl<'de> serde::Deserialize<'de> for Message {
210-
fn deserialize<D>(deserializer: D) -> Result<Message, D::Error>
211-
where
212-
D: serde::Deserializer<'de>,
213-
{
214-
use serde::private::de::Content;
215-
use std::fmt;
216-
struct FieldVisitor;
217-
struct TaggedContent<'de> {
218-
pub tag: String,
219-
pub content: Content<'de>,
220-
}
221-
impl<'de> ::serde::de::Visitor<'de> for FieldVisitor {
222-
type Value = TaggedContent<'de>;
223-
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
224-
fmt.write_str("subtyped or non-subtyped message")
225-
}
226-
227-
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
228-
where
229-
M: serde::de::MapAccess<'de>,
230-
{
231-
let mut tag = None;
232-
let mut vec = Vec::with_capacity(30);
233-
while let Some(kv) = map.next_entry::<&'de str, Content<'de>>()? {
234-
match kv {
235-
("subtype", v) => {
236-
if tag.is_some() {
237-
return Err(serde::de::Error::duplicate_field("subtype"));
238-
}
239-
tag = Some(match v.as_str() {
240-
Some(subtype) => subtype.to_string(),
241-
None => return Err(serde::de::Error::missing_field("subtype")),
242-
});
243-
}
244-
(k, v) => {
245-
vec.push((Content::Str(k), v));
246-
}
247-
}
248-
}
249-
Ok(TaggedContent {
250-
tag: tag.unwrap_or_else(|| "".to_string()),
251-
content: Content::Map(vec),
252-
})
253-
}
254-
}
255-
impl<'de> ::serde::Deserialize<'de> for TaggedContent<'de> {
256-
#[inline]
257-
fn deserialize<__D>(d: __D) -> ::serde::export::Result<Self, __D::Error>
258-
where
259-
__D: ::serde::Deserializer<'de>,
260-
{
261-
::serde::Deserializer::deserialize_identifier(d, FieldVisitor)
262-
}
263-
}
264-
let tagged = match ::serde::Deserializer::deserialize_any(deserializer, FieldVisitor) {
265-
::serde::export::Ok(val) => val,
266-
::serde::export::Err(e) => {
267-
return ::serde::export::Err(e);
268-
}
269-
};
270-
271-
macro_rules! deserialize_subtype {
272-
($($field:expr => $e_type:ty as $v_type:path,)*) => {
273-
match tagged.tag.as_str() {
274-
$($field => ::serde::export::Result::map(
275-
<$e_type as ::serde::Deserialize>::deserialize(
276-
::serde::private::de::ContentDeserializer::<D::Error>::new(
277-
tagged.content,
278-
),
279-
),
280-
$v_type,
281-
),)*
282-
_ => Err(serde::de::Error::unknown_variant(&tagged.tag, &[$($field),*]))
283-
}
284-
}
285-
}
286-
deserialize_subtype! {
287-
"bot_message" => BotMessage as Message::BotMessage,
288-
"channel_join" => ChannelJoinMessage as Message::ChannelJoin,
289-
"" => BasicMessage as Message::BasicMessage,
290-
}
291-
}
209+
#[derive(Debug, Deserialize)]
210+
#[serde(untagged)]
211+
pub enum Message {
212+
TaggedMessage(TaggedMessage),
213+
BasicMessage(BasicMessage),
292214
}
293215

294216
#[derive(Debug, Deserialize)]

src/slack/test.rs

+14
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,17 @@ pub fn test_deserialize_bot_message() {
6969
)
7070
.unwrap();
7171
}
72+
73+
#[test]
74+
pub fn test_deserialize_normal_message() {
75+
serde_json::from_str::<Message>(
76+
r#"{
77+
"type": "message",
78+
"ts": "1358877455.000010",
79+
"channel": "aaaa",
80+
"text": "Pushing is the answer",
81+
"user": "github"
82+
}"#,
83+
)
84+
.unwrap();
85+
}

0 commit comments

Comments
 (0)