diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 88 |
1 files changed, 31 insertions, 57 deletions
diff --git a/src/lib.rs b/src/lib.rs index b8a4f86..e87784d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,6 @@ //! use selfref::Holder; //! use selfref::new_with_closure; //! # use selfref::opaque; -//! use selfref::operate_in_closure; //! # //! # struct MySelfRefStruct<'this> { //! # this: Cell<Option<&'this MySelfRefStruct<'this>>>, @@ -112,9 +111,9 @@ //! //! // then, build the self-reference //! holder.as_ref().operate_in( -//! operate_in_closure::<MySelfRefStructKey, _, _>(|this| { +//! |this| { //! this.this.set(Some(this.get_ref())); -//! }) +//! } //! ); //! } //! ``` @@ -133,7 +132,6 @@ //! //! use selfref::Holder; //! use selfref::NewWith; -//! use selfref::OperateIn; //! use selfref::opaque; //! //! struct Foo<'a, 'b: 'a> { @@ -167,16 +165,9 @@ //! // construct the struct //! let holder = pin!(Holder::new_with(FooBuilder(stack_str))); //! -//! // setup the self-reference -//! struct SetFooRef; -//! impl<'k, 'b: 'k> OperateIn<'k, FooKey<'b>> for SetFooRef { -//! type Out = (); -//! fn operate_in<'a>(self, foo: Pin<&'a Foo<'a, 'b>>) -//! where 'k: 'a { -//! foo.foo.set(Some(foo.get_ref())); -//! } -//! } -//! holder.as_ref().operate_in(SetFooRef); +//! holder.as_ref().operate_in(|foo| { +//! foo.foo.set(Some(foo.get_ref())); +//! }); //! } //! ``` //! @@ -577,32 +568,19 @@ impl<'k, T> Holder<'k, T> where T: Opaque { } } -/// Helper trait for working with a [`Holder`]. +/// Wrapper around a `Pin<&'k T::Kind<'k>>` for implied bounds. /// -/// This is necessary because closures don't work properly here. -/// -/// See [`Holder::operate_in`] for examples. -pub trait OperateIn<'k, T: Opaque + 'k> { - /// The value returned by this operation. - type Out; - /// Do this operation. - fn operate_in<'a>(self, x: Pin<&'a T::Kind<'a>>) -> Self::Out where 'k: 'a; +/// Derefs to `Pin<&'k T::Kind<'k>>`. +pub struct OperateIn<'k, T> where T: Opaque + 'k { + inner: Pin<&'k T::Kind<'k>>, } -impl<'k, T: Opaque + 'k, F, R> OperateIn<'k, T> for F -where F: for<'a> FnOnce(Pin<&'a T::Kind<'a>>) -> R { - type Out = R; - fn operate_in<'a>(self, x: Pin<&'a T::Kind<'a>>) -> R where 'k: 'a { - self(x) - } -} +impl<'k, T> core::ops::Deref for OperateIn<'k, T> where T: Opaque { + type Target = Pin<&'k T::Kind<'k>>; -/// Helper for working with a [`Holder`] using a closure. -/// -/// This only works if `K` is `'static`. -pub fn operate_in_closure<K: Opaque, F, R>(f: F) -> F -where F: for<'a> FnOnce(Pin<&'a <K as Opaque>::Kind<'a>>) -> R { - f + fn deref(&self) -> &Pin<&'k T::Kind<'k>> { + &self.inner + } } impl<'k, T> Holder<'k, T> where T: Opaque { @@ -624,7 +602,6 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// use selfref::Holder; /// use selfref::new_with_closure; /// use selfref::opaque; - /// use selfref::operate_in_closure; /// /// #[derive(Default)] /// struct Foo<'a> { @@ -644,9 +621,9 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// )); /// // Actually making our Foo refer to itself. /// holder.as_ref().operate_in( - /// operate_in_closure::<FooKey, _, _>(|foo| { + /// |foo| { /// foo.foo.set(Some(foo.get_ref())); - /// }) + /// } /// ); /// } /// ``` @@ -663,7 +640,6 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// /// use selfref::Holder; /// use selfref::NewWith; - /// use selfref::OperateIn; /// use selfref::opaque; /// /// struct Foo<'a, 'b: 'a> { @@ -693,34 +669,32 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// let stack_str = core::str::from_utf8(&stack_array).unwrap(); /// let holder = pin!(Holder::new_with(FooBuilder(stack_str))); /// // Actually making our Foo refer to itself. - /// struct SetFooRef; - /// impl<'k, 'b: 'k> OperateIn<'k, FooKey<'b>> for SetFooRef { - /// type Out = (); - /// fn operate_in<'a>(self, foo: Pin<&'a Foo<'a, 'b>>) - /// where 'k: 'a { - /// foo.foo.set(Some(foo.get_ref())); - /// } - /// } - /// holder.as_ref().operate_in(SetFooRef); + /// holder.as_ref().operate_in(|foo| { + /// foo.foo.set(Some(foo.get_ref())); + /// }); /// } /// ``` pub fn operate_in<'i, F, R>(self: Pin<&'i Self>, f: F) -> R where - F: OperateIn<'k, T, Out=R> + F: for<'x> FnOnce(OperateIn<'x, T>) -> R { - /// Converts Pin<&'a T::Kind<'k>> to Pin<&'b T::Kind<'b>> + /// Converts `Pin<&'a T::Kind<'k>>` to `Pin<&'b T::Kind<'b>>`. + /// + /// Not sure why this is called "upcast_dangling" since none of these + /// are actually dangling. But anyway. unsafe fn upcast_dangling<'a, 'b, 'c, T: Opaque + 'c>( x: Pin<&'a T::Kind<'c>>, ) -> Pin<&'b T::Kind<'b>> where T::Kind<'c>: 'a { mem::transmute(x) } - - f.operate_in(unsafe { - upcast_dangling::<'i, 'k, '_, T> - (self.map_unchecked(|self_ref| { - &self_ref.inner - })) + f(OperateIn { + inner: unsafe { + upcast_dangling::<'i, 'k, '_, T> + (self.map_unchecked(|self_ref| { + &self_ref.inner + })) + } }) } } |