diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-12-05 16:32:20 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-12-05 16:32:20 -0300 |
commit | 72841de072c4a904983e9eb631b690a61d3e06ff (patch) | |
tree | 18b5677a9bcc61e77a140b9012c1d82333e2f4f1 /src/lib.rs | |
parent | 2b5d0cb87b13fd5354143bb0b802d06ca0715ca6 (diff) |
Use closures for new_with
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 101 |
1 files changed, 35 insertions, 66 deletions
diff --git a/src/lib.rs b/src/lib.rs index e87784d..fdefe7d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,7 +84,6 @@ //! # use std::cell::Cell; //! # //! use selfref::Holder; -//! use selfref::new_with_closure; //! # use selfref::opaque; //! # //! # struct MySelfRefStruct<'this> { @@ -102,7 +101,7 @@ //! fn main() { //! // first, construct the struct //! let holder = Box::pin(Holder::<'_, MySelfRefStructKey>::new_with( -//! new_with_closure::<MySelfRefStructKey, _>(|_| { +//! |foo| foo.build({ //! MySelfRefStruct { //! this: Cell::new(None) //! } @@ -131,7 +130,6 @@ //! use core::pin::pin; //! //! use selfref::Holder; -//! use selfref::NewWith; //! use selfref::opaque; //! //! struct Foo<'a, 'b: 'a> { @@ -147,23 +145,17 @@ //! } //! //! fn main() { -//! // can't use real closure, "hand-roll" a closure. -//! struct FooBuilder<'b>(&'b str); -//! impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> { -//! fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a { -//! Foo { -//! foo: Default::default(), -//! t: self.0, -//! } -//! } -//! } -//! //! // a non-'static &str //! let stack_array: [u8; 5] = *b"hello"; //! let stack_str = core::str::from_utf8(&stack_array).unwrap(); //! //! // construct the struct -//! let holder = pin!(Holder::new_with(FooBuilder(stack_str))); +//! let holder = pin!(Holder::<'_, FooKey<'_>>::new_with(|foo| { +//! foo.build(Foo { +//! foo: Default::default(), +//! t: stack_str, +//! }) +//! })); //! //! holder.as_ref().operate_in(|foo| { //! foo.foo.set(Some(foo.get_ref())); @@ -427,7 +419,6 @@ macro_rules! opaque { /// use core::cell::Cell; /// /// use selfref::Holder; -/// use selfref::new_with_closure; /// use selfref::opaque; /// /// #[derive(Default)] @@ -445,7 +436,7 @@ macro_rules! opaque { /// fn main() { /// // We can use a closure here, but we need to give the compiler a hint. /// let holder = Holder::<'_, FooKey>::new_with( -/// new_with_closure::<FooKey, _>(|foo| Foo::default()) +/// |foo| foo.build(Foo::default()) /// ); /// } /// ``` @@ -454,36 +445,23 @@ pub struct Holder<'k, T> where T: Opaque + 'k { inner: <T as Opaque>::Kind<'k>, } -/// Helper trait for creating a [`Holder`]. +/// Helper for creating a [`Holder`]. /// /// This is necessary because closures don't work properly here. /// /// See [`Holder::new_with`] for examples. -pub trait NewWith<'k, T: Opaque + 'k> { - /// Creates a new `T::Kind` with an unbound lifetime. - fn new_with<'a>(self) -> T::Kind<'a> where 'k: 'a, T::Kind<'a>: Sized; +pub struct Builder<'k, T: Opaque + 'k> where T::Kind<'k>: Sized { + inner: Option<T::Kind<'k>>, } -impl<'k, T: Opaque + 'k, F> NewWith<'k, T> for F -where - F: for<'a> FnOnce([&'a (); 0]) -> <T as Opaque>::Kind<'a>, -{ - fn new_with<'a>(self) -> T::Kind<'a> where 'k: 'a, T::Kind<'a>: Sized { - self([]) +impl<'k, T: Opaque + 'k> Builder<'k, T> where T::Kind<'k>: Sized { + /// Builds the [`Holder`]. + #[inline] + pub fn build(&mut self, t: T::Kind<'k>) { + self.inner = Some(t); } } -/// Helper for creating a [`Holder`] using a closure. -/// -/// This only works if `K` is `'static`. -pub fn new_with_closure<K: Opaque, F>(f: F) -> F -where - F: for<'a> FnOnce([&'a (); 0]) -> <K as Opaque>::Kind<'a>, - for<'a> K::Kind<'a>: Sized, -{ - f -} - impl<'k, T> Holder<'k, T> where T: Opaque { /// Creates a new holder. /// @@ -495,7 +473,6 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// use core::cell::Cell; /// /// use selfref::Holder; - /// use selfref::new_with_closure; /// use selfref::opaque; /// /// #[derive(Default)] @@ -513,7 +490,7 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// fn main() { /// // We can use a closure here, but we need to help the compiler. /// let holder = Holder::<'_, FooKey>::new_with( - /// new_with_closure::<FooKey, _>(|foo| Foo::default()) + /// |foo| foo.build(Foo::default()) /// ); /// } /// ``` @@ -525,7 +502,6 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// use core::marker::PhantomData; /// /// use selfref::Holder; - /// use selfref::NewWith; /// use selfref::opaque; /// /// struct Foo<'a, 'b: 'a> { @@ -541,28 +517,27 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// } /// /// fn main() { - /// struct FooBuilder<'b>(&'b str); - /// impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> { - /// fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a { - /// Foo { - /// foo: Default::default(), - /// t: self.0, - /// } - /// } - /// } /// let stack_array: [u8; 5] = *b"hello"; /// // a non-'static &str /// let stack_str = core::str::from_utf8(&stack_array).unwrap(); - /// let holder = Holder::new_with(FooBuilder(stack_str)); + /// let holder = Holder::<'_, FooKey<'_>>::new_with(|foo| { + /// foo.build(Foo { + /// foo: Default::default(), + /// t: stack_str, + /// }); + /// }); /// } /// ``` pub fn new_with<F>(f: F) -> Self where - F: NewWith<'k, T>, T::Kind<'k>: Sized + F: for<'a> FnOnce(&mut Builder<'a, T>), + T::Kind<'k>: Sized, { + let mut builder = Builder { inner: None }; + f(&mut builder); Self { // it is important that the constructor cannot observe 'k! - inner: f.new_with(), + inner: builder.inner.unwrap(), _pinned: PhantomPinned } } @@ -600,7 +575,6 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// use core::pin::pin; /// /// use selfref::Holder; - /// use selfref::new_with_closure; /// use selfref::opaque; /// /// #[derive(Default)] @@ -617,7 +591,7 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// /// fn main() { /// let holder = pin!(Holder::<'_, FooKey>::new_with( - /// new_with_closure::<FooKey, _>(|foo| Foo::default()) + /// |foo| foo.build(Foo::default()) /// )); /// // Actually making our Foo refer to itself. /// holder.as_ref().operate_in( @@ -639,7 +613,6 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// use core::pin::pin; /// /// use selfref::Holder; - /// use selfref::NewWith; /// use selfref::opaque; /// /// struct Foo<'a, 'b: 'a> { @@ -655,19 +628,15 @@ impl<'k, T> Holder<'k, T> where T: Opaque { /// } /// /// fn main() { - /// struct FooBuilder<'b>(&'b str); - /// impl<'k, 'b: 'k> NewWith<'k, FooKey<'b>> for FooBuilder<'b> { - /// fn new_with<'a>(self) -> Foo<'a, 'b> where 'k: 'a { - /// Foo { - /// foo: Default::default(), - /// t: self.0, - /// } - /// } - /// } /// let stack_array: [u8; 5] = *b"hello"; /// // a non-'static &str /// let stack_str = core::str::from_utf8(&stack_array).unwrap(); - /// let holder = pin!(Holder::new_with(FooBuilder(stack_str))); + /// let holder = pin!(Holder::<'_, FooKey<'_>>::new_with(|foo| { + /// foo.build(Foo { + /// foo: Default::default(), + /// t: stack_str, + /// }); + /// })); /// // Actually making our Foo refer to itself. /// holder.as_ref().operate_in(|foo| { /// foo.foo.set(Some(foo.get_ref())); |