A better Rust ATProto crate
1use std::borrow::Cow; 2use std::collections::HashMap; 3use std::collections::HashSet; 4use std::collections::VecDeque; 5use std::hash::BuildHasher; 6use std::hash::Hash; 7use std::sync::Arc; 8 9/// Shamelessly copied from https://github.com/bearcove/merde 10/// Allow turning a value into an "owned" variant, which can then be 11/// returned, moved, etc. 12/// 13/// This usually involves allocating buffers for `Cow<'a, str>`, etc. 14pub trait IntoStatic: Sized { 15 /// The "owned" variant of the type. For `Cow<'a, str>`, this is `Cow<'static, str>`, for example. 16 type Output: 'static; 17 18 /// Turns the value into an "owned" variant, which can then be returned, moved, etc. 19 /// 20 /// This allocates, for all but the most trivial types. 21 fn into_static(self) -> Self::Output; 22} 23 24impl<T, E> IntoStatic for Result<T, E> 25where 26 T: IntoStatic, 27 E: IntoStatic, 28{ 29 type Output = Result<T::Output, E::Output>; 30 31 fn into_static(self) -> Self::Output { 32 match self { 33 Ok(v) => Ok(v.into_static()), 34 Err(e) => Err(e.into_static()), 35 } 36 } 37} 38 39impl<T> IntoStatic for Cow<'_, T> 40where 41 T: ToOwned + ?Sized + 'static, 42{ 43 type Output = Cow<'static, T>; 44 45 #[inline(always)] 46 fn into_static(self) -> Self::Output { 47 match self { 48 Cow::Borrowed(b) => Cow::Owned(b.to_owned()), 49 Cow::Owned(o) => Cow::Owned(o), 50 } 51 } 52} 53 54macro_rules! impl_into_static_passthru { 55 ($($ty:ty),+) => { 56 $( 57 impl IntoStatic for $ty { 58 type Output = $ty; 59 60 #[inline(always)] 61 fn into_static(self) -> Self::Output { 62 self 63 } 64 } 65 )+ 66 }; 67} 68 69impl_into_static_passthru!( 70 String, u128, u64, u32, u16, u8, i128, i64, i32, i16, i8, bool, char, usize, isize, f32, f64 71); 72 73impl<T: IntoStatic> IntoStatic for Box<T> { 74 type Output = Box<T::Output>; 75 76 fn into_static(self) -> Self::Output { 77 Box::new((*self).into_static()) 78 } 79} 80 81impl<T: IntoStatic> IntoStatic for Option<T> { 82 type Output = Option<T::Output>; 83 84 fn into_static(self) -> Self::Output { 85 self.map(|v| v.into_static()) 86 } 87} 88 89impl<T: IntoStatic> IntoStatic for Vec<T> { 90 type Output = Vec<T::Output>; 91 92 fn into_static(self) -> Self::Output { 93 self.into_iter().map(|v| v.into_static()).collect() 94 } 95} 96 97impl<T: IntoStatic + Clone> IntoStatic for Arc<T> { 98 type Output = Arc<T::Output>; 99 100 fn into_static(self) -> Self::Output { 101 let t: T = (*self).clone(); 102 Arc::new(t.into_static()) 103 } 104} 105 106impl<K, V, S> IntoStatic for HashMap<K, V, S> 107where 108 S: BuildHasher + Default + 'static, 109 K: IntoStatic + Eq + Hash, 110 V: IntoStatic, 111 K::Output: Eq + Hash, 112{ 113 type Output = HashMap<K::Output, V::Output, S>; 114 115 fn into_static(self) -> Self::Output { 116 self.into_iter() 117 .map(|(k, v)| (k.into_static(), v.into_static())) 118 .collect() 119 } 120} 121 122impl<T: IntoStatic> IntoStatic for HashSet<T> 123where 124 T::Output: Eq + Hash, 125{ 126 type Output = HashSet<T::Output>; 127 128 fn into_static(self) -> Self::Output { 129 self.into_iter().map(|v| v.into_static()).collect() 130 } 131} 132 133impl<T: IntoStatic> IntoStatic for VecDeque<T> { 134 type Output = VecDeque<T::Output>; 135 136 fn into_static(self) -> Self::Output { 137 self.into_iter().map(|v| v.into_static()).collect() 138 } 139} 140 141impl<T1: IntoStatic> IntoStatic for (T1,) { 142 type Output = (T1::Output,); 143 144 fn into_static(self) -> Self::Output { 145 (self.0.into_static(),) 146 } 147} 148 149impl<T1: IntoStatic, T2: IntoStatic> IntoStatic for (T1, T2) { 150 type Output = (T1::Output, T2::Output); 151 152 fn into_static(self) -> Self::Output { 153 (self.0.into_static(), self.1.into_static()) 154 } 155} 156 157impl<T1: IntoStatic, T2: IntoStatic, T3: IntoStatic> IntoStatic for (T1, T2, T3) { 158 type Output = (T1::Output, T2::Output, T3::Output); 159 160 fn into_static(self) -> Self::Output { 161 ( 162 self.0.into_static(), 163 self.1.into_static(), 164 self.2.into_static(), 165 ) 166 } 167} 168 169impl<T1: IntoStatic, T2: IntoStatic, T3: IntoStatic, T4: IntoStatic> IntoStatic 170 for (T1, T2, T3, T4) 171{ 172 type Output = (T1::Output, T2::Output, T3::Output, T4::Output); 173 174 fn into_static(self) -> Self::Output { 175 ( 176 self.0.into_static(), 177 self.1.into_static(), 178 self.2.into_static(), 179 self.3.into_static(), 180 ) 181 } 182} 183 184impl<T1: IntoStatic, T2: IntoStatic, T3: IntoStatic, T4: IntoStatic, T5: IntoStatic> IntoStatic 185 for (T1, T2, T3, T4, T5) 186{ 187 type Output = (T1::Output, T2::Output, T3::Output, T4::Output, T5::Output); 188 189 fn into_static(self) -> Self::Output { 190 ( 191 self.0.into_static(), 192 self.1.into_static(), 193 self.2.into_static(), 194 self.3.into_static(), 195 self.4.into_static(), 196 ) 197 } 198} 199 200impl<T1: IntoStatic, T2: IntoStatic, T3: IntoStatic, T4: IntoStatic, T5: IntoStatic, T6: IntoStatic> 201 IntoStatic for (T1, T2, T3, T4, T5, T6) 202{ 203 type Output = ( 204 T1::Output, 205 T2::Output, 206 T3::Output, 207 T4::Output, 208 T5::Output, 209 T6::Output, 210 ); 211 212 fn into_static(self) -> Self::Output { 213 ( 214 self.0.into_static(), 215 self.1.into_static(), 216 self.2.into_static(), 217 self.3.into_static(), 218 self.4.into_static(), 219 self.5.into_static(), 220 ) 221 } 222} 223 224impl< 225 T1: IntoStatic, 226 T2: IntoStatic, 227 T3: IntoStatic, 228 T4: IntoStatic, 229 T5: IntoStatic, 230 T6: IntoStatic, 231 T7: IntoStatic, 232> IntoStatic for (T1, T2, T3, T4, T5, T6, T7) 233{ 234 type Output = ( 235 T1::Output, 236 T2::Output, 237 T3::Output, 238 T4::Output, 239 T5::Output, 240 T6::Output, 241 T7::Output, 242 ); 243 244 fn into_static(self) -> Self::Output { 245 ( 246 self.0.into_static(), 247 self.1.into_static(), 248 self.2.into_static(), 249 self.3.into_static(), 250 self.4.into_static(), 251 self.5.into_static(), 252 self.6.into_static(), 253 ) 254 } 255} 256 257impl< 258 T1: IntoStatic, 259 T2: IntoStatic, 260 T3: IntoStatic, 261 T4: IntoStatic, 262 T5: IntoStatic, 263 T6: IntoStatic, 264 T7: IntoStatic, 265 T8: IntoStatic, 266> IntoStatic for (T1, T2, T3, T4, T5, T6, T7, T8) 267{ 268 type Output = ( 269 T1::Output, 270 T2::Output, 271 T3::Output, 272 T4::Output, 273 T5::Output, 274 T6::Output, 275 T7::Output, 276 T8::Output, 277 ); 278 279 fn into_static(self) -> Self::Output { 280 ( 281 self.0.into_static(), 282 self.1.into_static(), 283 self.2.into_static(), 284 self.3.into_static(), 285 self.4.into_static(), 286 self.5.into_static(), 287 self.6.into_static(), 288 self.7.into_static(), 289 ) 290 } 291}