1#![forbid(unsafe_code)]
6#![deny(missing_docs)]
7#![cfg_attr(not(feature = "std"), no_std)]
8#![cfg_attr(docsrs, feature(doc_auto_cfg))]
9
10use cfg_if::cfg_if;
11
12cfg_if! {
13 if #[cfg(feature = "std")] {
14 use std::borrow::Cow;
15 } else if #[cfg(feature = "alloc")] {
16 extern crate alloc;
17
18 use alloc::{borrow::Cow, vec::Vec};
19 }
20}
21
22pub trait IntoStatic {
24 type Static: IntoStatic<Static = Self::Static> + 'static;
26
27 fn into_static(self) -> Self::Static;
29}
30
31cfg_if! {
32 if #[cfg(any(feature = "std", feature = "alloc"))] {
33 impl IntoStatic for Cow<'_, str> {
34 type Static = Cow<'static, str>;
35
36 fn into_static(self) -> Self::Static {
37 Self::Static::Owned(self.into_owned())
38 }
39 }
40
41 impl IntoStatic for Cow<'_, [u8]> {
42 type Static = Cow<'static, [u8]>;
43
44 fn into_static(self) -> Self::Static {
45 Self::Static::Owned(self.into_owned())
46 }
47 }
48
49 impl<T: Clone + IntoStatic<Static: Clone>> IntoStatic for Cow<'_, [T]> {
50 type Static = Cow<'static, [T::Static]>;
51
52 fn into_static(self) -> Self::Static {
53 Self::Static::Owned(self.into_owned().into_static())
54 }
55 }
56
57 impl<T: IntoStatic> IntoStatic for Vec<T> {
58 type Static = Vec<T::Static>;
59
60 fn into_static(self) -> Self::Static {
61 self.into_iter().map(IntoStatic::into_static).collect()
62 }
63 }
64 }
65}
66
67impl<T: IntoStatic> IntoStatic for Option<T> {
68 type Static = Option<T::Static>;
69
70 fn into_static(self) -> Self::Static {
71 self.map(IntoStatic::into_static)
72 }
73}
74
75impl<T: IntoStatic, E: IntoStatic> IntoStatic for Result<T, E> {
76 type Static = Result<T::Static, E::Static>;
77
78 fn into_static(self) -> Self::Static {
79 self.map(IntoStatic::into_static)
80 .map_err(IntoStatic::into_static)
81 }
82}
83
84impl<T: IntoStatic, const N: usize> IntoStatic for [T; N] {
85 type Static = [T::Static; N];
86
87 fn into_static(self) -> Self::Static {
88 self.map(IntoStatic::into_static)
89 }
90}
91
92macro_rules! impl_tuple {
93 ($($name: ident: $type: ident),+) => {
94 impl<$($type: $crate::IntoStatic),+> $crate::IntoStatic for ($($type,)+) {
95 type Static = ($($type::Static,)+);
96
97 fn into_static(self) -> Self::Static {
98 let ($($name,)+) = self;
99
100 ($($name.into_static(),)+)
101 }
102 }
103 }
104}
105
106impl_tuple!(a: A);
107impl_tuple!(a: A, b: B);
108impl_tuple!(a: A, b: B, c: C);
109impl_tuple!(a: A, b: B, c: C, d: D);
110impl_tuple!(a: A, b: B, c: C, d: D, e: E);
111impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F);
112impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
113impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
114impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
115impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
116impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
117impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);