twitch_message/
into_static.rs

1use std::borrow::Cow;
2
3use crate::{messages::*, HashMap, Prefix, Tags};
4
5/// A trait for converting a T: 'a to a T: 'static
6///
7/// This is used for going from a [`Message<'a>`](crate::messages::Message) to a `Message<'static>` or any of the sub types (see [`messages`](crate::messages))
8pub trait IntoStatic {
9    /// Output of [`IntoStatic::into_static`].
10    ///
11    /// This is an alternative to `ToOwned::Owned`
12    type Output: 'static;
13
14    /// This method casts `self` between `Self<'a>` and `Self<'static>`.
15    fn into_static(self) -> Self::Output;
16}
17
18mod private {
19    pub trait Sealed {}
20    impl<T> Sealed for T where T: super::IntoStatic {}
21}
22
23impl<'a> IntoStatic for Cow<'a, str> {
24    type Output = Cow<'static, str>;
25
26    fn into_static(self) -> Self::Output {
27        match self {
28            Cow::Borrowed(s) => Cow::Owned(s.to_string()),
29            Cow::Owned(s) => Cow::Owned(s),
30        }
31    }
32}
33
34impl<'a, T> IntoStatic for &'a T
35where
36    T: IntoStatic,
37    T: Clone,
38{
39    type Output = T::Output;
40
41    fn into_static(self) -> Self::Output {
42        self.clone().into_static()
43    }
44}
45
46impl IntoStatic for &str {
47    type Output = Cow<'static, str>;
48
49    fn into_static(self) -> Self::Output {
50        self.to_string().into()
51    }
52}
53
54impl<T> IntoStatic for Vec<T>
55where
56    T: IntoStatic,
57{
58    type Output = Vec<T::Output>;
59
60    fn into_static(self) -> Self::Output {
61        self.into_iter().map(IntoStatic::into_static).collect()
62    }
63}
64
65impl<K, V> IntoStatic for crate::HashMap<K, V>
66where
67    K: IntoStatic,
68    V: IntoStatic,
69    K::Output: Eq + std::hash::Hash,
70{
71    type Output = HashMap<K::Output, V::Output>;
72
73    fn into_static(self) -> Self::Output {
74        self.into_iter()
75            .map(|(k, v)| (k.into_static(), v.into_static()))
76            .collect()
77    }
78}
79
80impl<T> IntoStatic for Option<T>
81where
82    T: IntoStatic,
83{
84    type Output = Option<T::Output>;
85
86    fn into_static(self) -> Self::Output {
87        self.map(IntoStatic::into_static)
88    }
89}
90
91impl<'a> IntoStatic for TwitchMessage<'a>
92where
93    'static: 'a,
94{
95    type Output = TwitchMessage<'static>;
96
97    #[allow(deprecated)]
98    fn into_static(self) -> Self::Output {
99        match self {
100            Self::UserState(msg) => TwitchMessage::UserState(msg.into_static()),
101            Self::UserNotice(msg) => TwitchMessage::UserNotice(msg.into_static()),
102            Self::Reconnect(msg) => TwitchMessage::Reconnect(msg.into_static()),
103            Self::HostTarget(msg) => TwitchMessage::HostTarget(msg.into_static()),
104            Self::RoomState(msg) => TwitchMessage::RoomState(msg.into_static()),
105            Self::IrcReady(msg) => TwitchMessage::IrcReady(msg.into_static()),
106            Self::Privmsg(msg) => TwitchMessage::Privmsg(msg.into_static()),
107            Self::Whisper(msg) => TwitchMessage::Whisper(msg.into_static()),
108            Self::Notice(msg) => TwitchMessage::Notice(msg.into_static()),
109            Self::Ping(msg) => TwitchMessage::Ping(msg.into_static()),
110            Self::Pong(msg) => TwitchMessage::Pong(msg.into_static()),
111            Self::Ready(msg) => TwitchMessage::Ready(msg.into_static()),
112            Self::GlobalUserState(msg) => TwitchMessage::GlobalUserState(msg.into_static()),
113            Self::ClearMsg(msg) => TwitchMessage::ClearMsg(msg.into_static()),
114            Self::Capability(msg) => TwitchMessage::Capability(msg.into_static()),
115            Self::ClearChat(msg) => TwitchMessage::ClearChat(msg.into_static()),
116            Self::Message(msg) => TwitchMessage::Message(msg.into_static()),
117        }
118    }
119}
120
121impl<'a> IntoStatic for Message<'a>
122where
123    'static: 'a,
124{
125    type Output = Message<'static>;
126
127    fn into_static(self) -> Self::Output {
128        Message {
129            raw: self.raw.into_static(),
130            tags: self.tags.into_static(),
131            prefix: self.prefix.into_static(),
132            kind: self.kind.into_static(),
133            args: self.args.into_static(),
134            data: self.data.into_static(),
135        }
136    }
137}
138
139impl<'a> IntoStatic for Tags<'a>
140where
141    'static: 'a,
142{
143    type Output = Tags<'static>;
144
145    fn into_static(self) -> Self::Output {
146        Tags {
147            inner: self.inner.into_static(),
148        }
149    }
150}
151
152impl<'a> IntoStatic for Prefix<'a>
153where
154    'static: 'a,
155{
156    type Output = Prefix<'static>;
157
158    fn into_static(self) -> Self::Output {
159        match self {
160            Self::User { name, user, host } => Prefix::User {
161                name: name.into_static(),
162                user: user.into_static(),
163                host: host.into_static(),
164            },
165            Self::Server { host } => Prefix::Server {
166                host: host.into_static(),
167            },
168            Self::None => Prefix::None,
169        }
170    }
171}
172
173impl<'a> IntoStatic for MessageKind<'a>
174where
175    'static: 'a,
176{
177    type Output = MessageKind<'static>;
178
179    fn into_static(self) -> Self::Output {
180        match self {
181            Self::Capability => MessageKind::Capability,
182            Self::Ping => MessageKind::Ping,
183            Self::Pong => MessageKind::Pong,
184            Self::IrcReady => MessageKind::IrcReady,
185            Self::Ready => MessageKind::Ready,
186            Self::GlobalUserState => MessageKind::GlobalUserState,
187            Self::UserState => MessageKind::UserState,
188            Self::RoomState => MessageKind::RoomState,
189            Self::Privmsg => MessageKind::Privmsg,
190            Self::ClearChat => MessageKind::ClearChat,
191            Self::ClearMsg => MessageKind::ClearMsg,
192            Self::Notice => MessageKind::Notice,
193            Self::HostTarget => MessageKind::HostTarget,
194            Self::UserNotice => MessageKind::UserNotice,
195            Self::Whisper => MessageKind::Whisper,
196            Self::Reconnect => MessageKind::Reconnect,
197            Self::Numeric(n) => MessageKind::Numeric(n),
198            Self::Unknown(s) => MessageKind::Unknown(IntoStatic::into_static(s)),
199        }
200    }
201}
202
203impl<'a> IntoStatic for Capability<'a>
204where
205    'static: 'a,
206{
207    type Output = Capability<'static>;
208    fn into_static(self) -> Self::Output {
209        Self::Output {
210            acknowledged: self.acknowledged,
211            kind: self.kind.into_static(),
212            raw: self.raw.into_static(),
213        }
214    }
215}
216
217impl<'a> IntoStatic for ClearChat<'a>
218where
219    'static: 'a,
220{
221    type Output = ClearChat<'static>;
222    fn into_static(self) -> Self::Output {
223        Self::Output {
224            raw: self.raw.into_static(),
225            channel: self.channel.into_static(),
226            target: self.target.into_static(),
227            tags: self.tags.into_static(),
228        }
229    }
230}
231
232impl<'a> IntoStatic for ClearChatTarget<'a>
233where
234    'static: 'a,
235{
236    type Output = ClearChatTarget<'static>;
237    fn into_static(self) -> Self::Output {
238        match self {
239            ClearChatTarget::All => Self::Output::All,
240            ClearChatTarget::User(user) => Self::Output::User(user.into_static()),
241        }
242    }
243}
244
245impl<'a> IntoStatic for ClearMsg<'a>
246where
247    'static: 'a,
248{
249    type Output = ClearMsg<'static>;
250    fn into_static(self) -> Self::Output {
251        Self::Output {
252            raw: self.raw.into_static(),
253            channel: self.channel.into_static(),
254            message: self.message.into_static(),
255            tags: self.tags.into_static(),
256        }
257    }
258}
259
260impl<'a> IntoStatic for GlobalUserState<'a>
261where
262    'static: 'a,
263{
264    type Output = GlobalUserState<'static>;
265    fn into_static(self) -> Self::Output {
266        Self::Output {
267            tags: self.tags.into_static(),
268            raw: self.raw.into_static(),
269        }
270    }
271}
272
273#[allow(deprecated)]
274impl<'a> IntoStatic for HostTarget<'a>
275where
276    'static: 'a,
277{
278    type Output = HostTarget<'static>;
279    fn into_static(self) -> Self::Output {
280        Self::Output {
281            raw: self.raw.into_static(),
282            hosting_channel: self.hosting_channel.into_static(),
283            host_mode: self.host_mode.into_static(),
284        }
285    }
286}
287
288#[allow(deprecated)]
289impl IntoStatic for HostMode {
290    type Output = Self;
291    fn into_static(self) -> Self::Output {
292        self
293    }
294}
295
296impl<'a> IntoStatic for IrcReady<'a>
297where
298    'static: 'a,
299{
300    type Output = IrcReady<'static>;
301    fn into_static(self) -> Self::Output {
302        Self::Output {
303            name: self.name.into_static(),
304            raw: self.raw.into_static(),
305        }
306    }
307}
308
309#[allow(deprecated)]
310impl<'a> IntoStatic for Notice<'a>
311where
312    'static: 'a,
313{
314    type Output = Notice<'static>;
315    fn into_static(self) -> Self::Output {
316        Self::Output {
317            raw: self.raw.into_static(),
318            channel: self.channel.into_static(),
319            message: self.message.into_static(),
320            tags: self.tags.into_static(),
321        }
322    }
323}
324
325impl<'a> IntoStatic for Ping<'a>
326where
327    'static: 'a,
328{
329    type Output = Ping<'static>;
330    fn into_static(self) -> Self::Output {
331        Self::Output {
332            token: self.token.into_static(),
333            raw: self.raw.into_static(),
334        }
335    }
336}
337
338impl<'a> IntoStatic for Pong<'a>
339where
340    'static: 'a,
341{
342    type Output = Pong<'static>;
343    fn into_static(self) -> Self::Output {
344        Self::Output {
345            token: self.token.into_static(),
346            raw: self.raw.into_static(),
347        }
348    }
349}
350
351impl<'a> IntoStatic for Privmsg<'a>
352where
353    'static: 'a,
354{
355    type Output = Privmsg<'static>;
356    fn into_static(self) -> Self::Output {
357        Self::Output {
358            channel: self.channel.into_static(),
359            sender: self.sender.into_static(),
360            tags: self.tags.into_static(),
361            data: self.data.into_static(),
362            raw: self.raw.into_static(),
363        }
364    }
365}
366
367impl<'a> IntoStatic for Ready<'a>
368where
369    'static: 'a,
370{
371    type Output = Ready<'static>;
372    fn into_static(self) -> Self::Output {
373        Self::Output {
374            name: self.name.into_static(),
375            raw: self.raw.into_static(),
376        }
377    }
378}
379
380impl<'a> IntoStatic for Reconnect<'a>
381where
382    'static: 'a,
383{
384    type Output = Reconnect<'static>;
385    fn into_static(self) -> Self::Output {
386        Self::Output {
387            raw: self.raw.into_static(),
388        }
389    }
390}
391
392impl<'a> IntoStatic for RoomState<'a>
393where
394    'static: 'a,
395{
396    type Output = RoomState<'static>;
397    fn into_static(self) -> Self::Output {
398        Self::Output {
399            tags: self.tags.into_static(),
400            raw: self.raw.into_static(),
401        }
402    }
403}
404
405impl<'a> IntoStatic for UserState<'a>
406where
407    'static: 'a,
408{
409    type Output = UserState<'static>;
410    fn into_static(self) -> Self::Output {
411        Self::Output {
412            tags: self.tags.into_static(),
413            raw: self.raw.into_static(),
414        }
415    }
416}
417
418impl<'a> IntoStatic for UserNotice<'a>
419where
420    'static: 'a,
421{
422    type Output = UserNotice<'static>;
423    fn into_static(self) -> Self::Output {
424        Self::Output {
425            raw: self.raw.into_static(),
426            tags: self.tags.into_static(),
427            channel: self.channel.into_static(),
428            data: self.data.into_static(),
429        }
430    }
431}
432
433impl<'a> IntoStatic for Whisper<'a>
434where
435    'static: 'a,
436{
437    type Output = Whisper<'static>;
438    fn into_static(self) -> Self::Output {
439        Self::Output {
440            raw: self.raw.into_static(),
441            from_user: self.from_user.into_static(),
442            to_user: self.to_user.into_static(),
443            data: self.data.into_static(),
444            tags: self.tags.into_static(),
445        }
446    }
447}