into_static/
lib.rs

1//! Upgrading to static lifetimes.
2//!
3//! This crate provides the [`IntoStatic`] trait, which allows upgrading all lifetimes to `'static`.
4//!
5//! [`IntoStatic`] is implemented for [`Option<T>`] and [`Result<T, E>`], provided
6//! `T` and `E` are also [`IntoStatic`].
7//!
8//! The trait is also implemented for arrays [`[T; N]`](array) and tuples containing to 12 items,
9//! provided each type is [`IntoStatic`].
10//!
11//! When the `std` or `alloc` feature is enabled, [`IntoStatic`] is also
12//! implemented for `Cow<'_, T>`, yielding `Cow<'static, T>` (provided `T: 'static` is satisfied).
13
14#![forbid(unsafe_code)]
15#![deny(missing_docs)]
16#![cfg_attr(not(feature = "std"), no_std)]
17#![cfg_attr(docsrs, feature(doc_auto_cfg))]
18
19#[cfg(feature = "std")]
20use std::borrow::{Cow, ToOwned};
21
22#[cfg(feature = "alloc")]
23extern crate alloc;
24
25#[cfg(all(not(feature = "std"), feature = "alloc"))]
26use alloc::borrow::{Cow, ToOwned};
27
28/// Upgrading to `'static` lifetimes.
29pub trait IntoStatic {
30    /// The type with `'static` lifetimes.
31    type Static: 'static;
32
33    /// Upgrades [`Self`] to [`Self::Static`].
34    fn into_static(self) -> Self::Static;
35}
36
37#[cfg(any(feature = "std", feature = "alloc"))]
38impl<T: ToOwned + ?Sized + 'static> IntoStatic for Cow<'_, T> {
39    type Static = Cow<'static, T>;
40
41    fn into_static(self) -> Self::Static {
42        Self::Static::Owned(self.into_owned())
43    }
44}
45
46impl<T: IntoStatic> IntoStatic for Option<T> {
47    type Static = Option<T::Static>;
48
49    fn into_static(self) -> Self::Static {
50        self.map(IntoStatic::into_static)
51    }
52}
53
54impl<T: IntoStatic, E: IntoStatic> IntoStatic for Result<T, E> {
55    type Static = Result<T::Static, E::Static>;
56
57    fn into_static(self) -> Self::Static {
58        self.map(IntoStatic::into_static)
59            .map_err(IntoStatic::into_static)
60    }
61}
62
63impl<T: IntoStatic, const N: usize> IntoStatic for [T; N] {
64    type Static = [T::Static; N];
65
66    fn into_static(self) -> Self::Static {
67        self.map(IntoStatic::into_static)
68    }
69}
70
71macro_rules! impl_tuple {
72    ($($name: ident: $type: ident),+) => {
73        impl<$($type: $crate::IntoStatic),+> $crate::IntoStatic for ($($type,)+) {
74            type Static = ($($type::Static,)+);
75
76            fn into_static(self) -> Self::Static {
77                let ($($name,)+) = self;
78                ($($name.into_static(),)+)
79            }
80        }
81    }
82}
83
84impl_tuple!(a: A);
85impl_tuple!(a: A, b: B);
86impl_tuple!(a: A, b: B, c: C);
87impl_tuple!(a: A, b: B, c: C, d: D);
88impl_tuple!(a: A, b: B, c: C, d: D, e: E);
89impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F);
90impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
91impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
92impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
93impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
94impl_tuple!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
95impl_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);