1use std::borrow::Cow;
2
3use crate::{messages::*, HashMap, Prefix, Tags};
4
5pub trait IntoStatic {
9 type Output: 'static;
13
14 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}