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