twitch_irc/message/commands/
globaluserstate.rs1use crate::message::commands::IRCMessageParseExt;
2use crate::message::twitch::{Badge, RGBColor};
3use crate::message::{IRCMessage, ServerMessageParseError};
4use std::collections::HashSet;
5use std::convert::TryFrom;
6
7#[cfg(feature = "with-serde")]
8use {serde::Deserialize, serde::Serialize};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
14#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
15pub struct GlobalUserStateMessage {
16 pub user_id: String,
18 pub user_name: String,
20 pub badge_info: Vec<Badge>,
30 pub badges: Vec<Badge>,
32 pub emote_sets: HashSet<String>,
34 pub name_color: Option<RGBColor>,
36
37 pub source: IRCMessage,
39}
40
41impl TryFrom<IRCMessage> for GlobalUserStateMessage {
42 type Error = ServerMessageParseError;
43
44 fn try_from(source: IRCMessage) -> Result<GlobalUserStateMessage, ServerMessageParseError> {
45 if source.command != "GLOBALUSERSTATE" {
46 return Err(ServerMessageParseError::MismatchedCommand(Box::new(source)));
47 }
48
49 Ok(GlobalUserStateMessage {
53 user_id: source.try_get_nonempty_tag_value("user-id")?.to_owned(),
54 user_name: source
55 .try_get_nonempty_tag_value("display-name")?
56 .to_owned(),
57 badge_info: source.try_get_badges("badge-info")?,
58 badges: source.try_get_badges("badges")?,
59 emote_sets: source.try_get_emote_sets("emote-sets")?,
60 name_color: source.try_get_color("color")?,
61 source,
62 })
63 }
64}
65
66impl From<GlobalUserStateMessage> for IRCMessage {
67 fn from(msg: GlobalUserStateMessage) -> IRCMessage {
68 msg.source
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::message::twitch::{Badge, RGBColor};
75 use crate::message::{GlobalUserStateMessage, IRCMessage};
76 use std::collections::HashSet;
77 use std::convert::TryFrom;
78 use std::iter::FromIterator;
79
80 #[test]
81 pub fn test_basic() {
82 let src = "@badge-info=;badges=;color=#19E6E6;display-name=randers;emote-sets=0,42,237;user-id=40286300;user-type= :tmi.twitch.tv GLOBALUSERSTATE";
83 let irc_message = IRCMessage::parse(src).unwrap();
84 let msg = GlobalUserStateMessage::try_from(irc_message.clone()).unwrap();
85
86 assert_eq!(
87 msg,
88 GlobalUserStateMessage {
89 user_id: "40286300".to_owned(),
90 user_name: "randers".to_owned(),
91 badge_info: vec![],
92 badges: vec![],
93 emote_sets: vec!["0", "42", "237"]
94 .into_iter()
95 .map(|s| s.to_owned())
96 .collect(),
97 name_color: Some(RGBColor {
98 r: 0x19,
99 g: 0xE6,
100 b: 0xE6
101 }),
102 source: irc_message
103 }
104 );
105 }
106
107 #[test]
108 pub fn test_badges_no_color() {
109 let src = "@badge-info=;badges=premium/1;color=;display-name=randers;emote-sets=;user-id=40286300;user-type= :tmi.twitch.tv GLOBALUSERSTATE";
112 let irc_message = IRCMessage::parse(src).unwrap();
113 let msg = GlobalUserStateMessage::try_from(irc_message.clone()).unwrap();
114
115 assert_eq!(
116 msg,
117 GlobalUserStateMessage {
118 user_id: "40286300".to_owned(),
119 user_name: "randers".to_owned(),
120 badge_info: vec![],
121 badges: vec![Badge {
122 name: "premium".to_owned(),
123 version: "1".to_owned()
124 }],
125 emote_sets: HashSet::new(),
126 name_color: None,
127 source: irc_message
128 }
129 );
130 }
131
132 #[test]
133 pub fn test_plain_new_user() {
134 let src = "@badge-info=;badges=;color=;display-name=randers811;emote-sets=0;user-id=553170741;user-type= :tmi.twitch.tv GLOBALUSERSTATE";
136 let irc_message = IRCMessage::parse(src).unwrap();
137 let msg = GlobalUserStateMessage::try_from(irc_message.clone()).unwrap();
138
139 assert_eq!(
140 msg,
141 GlobalUserStateMessage {
142 user_id: "553170741".to_owned(),
143 user_name: "randers811".to_owned(),
144 badge_info: vec![],
145 badges: vec![],
146 emote_sets: HashSet::from_iter(vec!["0".to_owned()]),
147 name_color: None,
148 source: irc_message
149 }
150 );
151 }
152}