From 38de102cffb7692738ec7940794e59452372d395 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Wed, 20 Jul 2022 21:43:37 -0400 Subject: [PATCH] Support eager and lazy methods for providing references and values There are times where computing a value may be cheap, or where computing a reference may be expensive, so this fills out the possibilities. --- library/core/src/any.rs | 74 +++++++++++++++++++++++++++++++++++---- library/core/tests/any.rs | 2 +- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index e54f6c912d594..3bfb675531e64 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -796,7 +796,7 @@ pub trait Provider { /// impl Provider for SomeConcreteType { /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { /// demand.provide_ref::(&self.field) - /// .provide_value::(|| self.num_field); + /// .provide_value::(self.num_field); /// } /// } /// ``` @@ -881,28 +881,55 @@ impl<'a> Demand<'a> { /// /// # Examples /// + /// Provides an `u8`. + /// + /// ```rust + /// #![feature(provide_any)] + /// + /// use std::any::{Provider, Demand}; + /// # struct SomeConcreteType { field: u8 } + /// + /// impl Provider for SomeConcreteType { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// demand.provide_value::(self.field); + /// } + /// } + /// ``` + #[unstable(feature = "provide_any", issue = "96024")] + pub fn provide_value(&mut self, value: T) -> &mut Self + where + T: 'static, + { + self.provide::>(value) + } + + /// Provide a value or other type with only static lifetimes computed using a closure. + /// + /// # Examples + /// /// Provides a `String` by cloning. /// /// ```rust - /// # #![feature(provide_any)] + /// #![feature(provide_any)] + /// /// use std::any::{Provider, Demand}; /// # struct SomeConcreteType { field: String } /// /// impl Provider for SomeConcreteType { /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - /// demand.provide_value::(|| self.field.clone()); + /// demand.provide_value_with::(|| self.field.clone()); /// } /// } /// ``` #[unstable(feature = "provide_any", issue = "96024")] - pub fn provide_value(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self + pub fn provide_value_with(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self where T: 'static, { self.provide_with::>(fulfil) } - /// Provide a reference, note that the referee type must be bounded by `'static`, + /// Provide a reference. The referee type must be bounded by `'static`, /// but may be unsized. /// /// # Examples @@ -910,7 +937,8 @@ impl<'a> Demand<'a> { /// Provides a reference to a field as a `&str`. /// /// ```rust - /// # #![feature(provide_any)] + /// #![feature(provide_any)] + /// /// use std::any::{Provider, Demand}; /// # struct SomeConcreteType { field: String } /// @@ -925,6 +953,40 @@ impl<'a> Demand<'a> { self.provide::>>(value) } + /// Provide a reference computed using a closure. The referee type + /// must be bounded by `'static`, but may be unsized. + /// + /// # Examples + /// + /// Provides a reference to a field as a `&str`. + /// + /// ```rust + /// #![feature(provide_any)] + /// + /// use std::any::{Provider, Demand}; + /// # struct SomeConcreteType { business: String, party: String } + /// # fn today_is_a_weekday() -> bool { true } + /// + /// impl Provider for SomeConcreteType { + /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) { + /// demand.provide_ref_with::(|| { + /// if today_is_a_weekday() { + /// &self.business + /// } else { + /// &self.party + /// } + /// }); + /// } + /// } + /// ``` + #[unstable(feature = "provide_any", issue = "96024")] + pub fn provide_ref_with( + &mut self, + fulfil: impl FnOnce() -> &'a T, + ) -> &mut Self { + self.provide_with::>>(fulfil) + } + /// Provide a value with the given `Type` tag. fn provide(&mut self, value: I::Reified) -> &mut Self where diff --git a/library/core/tests/any.rs b/library/core/tests/any.rs index 8ed0c88808fe2..9538b81394957 100644 --- a/library/core/tests/any.rs +++ b/library/core/tests/any.rs @@ -142,7 +142,7 @@ impl Provider for SomeConcreteType { demand .provide_ref::(&self.some_string) .provide_ref::(&self.some_string) - .provide_value::(|| "bye".to_owned()); + .provide_value_with::(|| "bye".to_owned()); } }