[−][src]Module async_coap::arc_guard
Arc Guard
This crate1 provides the ArcGuard
class, which is a container for a single object
with lifetime that is bound to that of an Arc
. This is useful for passing around boxed
futures that have a lifetime that is limited to that of the object that created it.
For example, the following does not compile:
use futures::{future::ready,future::BoxFuture,prelude::*}; use std::sync::{Arc,Weak}; use arc_guard::{ArcGuard,ArcGuardExt}; trait PropertyFetcher { fn fetch( &self, key: &str, ) -> BoxFuture<Option<String>>; } struct WeakFetcher { sub_obj: Weak<Box<PropertyFetcher>>, } impl PropertyFetcher for WeakFetcher { fn fetch(&self, key: &str) -> BoxFuture<Option<String>> { if let Some(arc) = self.sub_obj.upgrade() { // error[E0515]: cannot return value referencing local variable `arc` arc.fetch(key).boxed() } else { ready(None).boxed() } } }
If you think about it, the fact that rustc
doesn't like this code makes perfect sense:
because sub_obj
is a weak reference, it could be dropped at any moment, violating the
lifetime guarantee for the return value of fetch()
. To fix this, we need to ensure that
the value we return internally keeps an Arc
reference to the object that created it. That's
where ArcGuard
comes in:
impl PropertyFetcher for WeakFetcher { fn fetch(&self, key: &str) -> BoxFuture<Option<String>> { if let Some(arc) = self.sub_obj.upgrade() { // Compiles and works! arc.guard(|x|x.fetch(key)).boxed() } else { ready(None).boxed() } } }
Additional Examples
let mut arc = Arc::new("foobar".to_string()); let guarded = arc.guard(|s| &s.as_str()[3..]); assert_eq!(guarded, "bar"); // We can't get a mutable instance to the // string while `guarded` is still around. assert_eq!(Arc::get_mut(&mut arc), None); core::mem::drop(guarded); assert!(Arc::get_mut(&mut arc).is_some());
I would have loved to call this crate
lifeguard
, because it is a "guard" on the lifetime of the contained "head" instance, but sadly that name was already taken. ↩
Structs
ArcGuard | A container for a single object with lifetime that is bound to that of an |
Traits
ArcGuardExt | A convenience trait for |