9 releases (breaking)
0.8.0 | Jun 23, 2024 |
---|---|
0.7.0 | Oct 25, 2023 |
0.6.0 | Oct 20, 2023 |
0.5.0 | Apr 29, 2023 |
0.1.0 | Feb 18, 2022 |
#138 in Rust patterns
10,182 downloads per month
Used in 22 crates
(7 directly)
62KB
1.5K
SLoC
Bounded Static
This crate defines the ToBoundedStatic
and IntoBoundedStatic
traits,
the ToStatic
macro and provides impls
for common types. This crate has zero-dependencies, is no_std
friendly and
forbids unsafe
code.
As described in the Common Rust Lifetime Misconceptions:
T: 'static
should be read as "T
is bounded by a'static
lifetime" not "T
has a'static
lifetime".
The traits ToBoundedStatic
and IntoBoundedStatic
can be used to convert any suitable T
and &T
to an
owned T
such that T: 'static
. Both traits define an associated type which is bounded by 'static
and provide a
method to convert to that bounded type.
The macros ToStatic
can be used to automatically derive ToBoundedStatic
and IntoBoundedStatic
for any struct
or enum
that can be converted to a form that is bounded by 'static
.
Refer to the crate documentation
for details and examples.
FAQ
When is this useful?
This is useful for data structures which directly or indirectly contain Cow<T>
types that must be supplied to
a function which requires the 'static
bound (i.e. std::thread::spawn
):
#[derive(Debug, PartialEq, ToStatic)]
struct Foo<'a> {
foo: Cow<'a, str>,
bar: Vec<Bar<'a>>
}
#[derive(Debug, PartialEq, ToStatic)]
enum Bar<'a> {
First,
Second(Cow<'a, str>),
}
fn main() {
let value = String::from("data");
let foo = Foo {
foo: Cow::from(&value),
bar: vec![Bar::First, Bar::Second(Cow::from(&value))]
};
let foo_static = foo.into_static();
std::thread::spawn(move || {
assert_eq!(foo_static.foo, "data");
assert_eq!(foo_static.bar, vec![Bar::First, Bar::Second("data".into())])
}).join().unwrap();
}
How does this differ from the ToOwned
trait?
The ToOwned
trait defines an associated type Owned
which
is not bound by 'static
and therefore the follow will not compile:
use std::borrow::Cow;
fn main() {
#[derive(Clone)]
struct Foo<'a> {
foo: Cow<'a, str>,
}
fn ensure_static<T: 'static>(_: T) {}
let s = String::from("data");
let foo = Foo { foo: Cow::from(&s) };
ensure_static(foo.to_owned())
}
Results in the following error:
error[E0597]: `s` does not live long enough
--> src/lib.rs:12:36
|
12 | let foo = Foo { foo: Cow::from(&s) };
| ----------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `s` is borrowed for `'static`
13 | ensure_static(foo.to_owned())
14 | }
| - `s` dropped here while still borrowed
Replacing Clone
with ToStatic
and using into_static()
(or to_static()
as needed) allows the example to compile:
use std::borrow::Cow;
fn main() {
#[derive(ToStatic)]
struct Foo<'a> {
foo: Cow<'a, str>,
}
fn ensure_static<T: 'static>(_: T) {}
let s = String::from("data");
let foo = Foo { foo: Cow::from(&s) };
ensure_static(foo.into_static())
}
License
bounded-static
is distributed under the terms of the Apache License (Version 2.0).
See LICENSE for details.
Copyright 2022
Dependencies
~0–5MB
~13K SLoC