@@ -796,7 +796,7 @@ pub trait Provider {
796
796
/// impl Provider for SomeConcreteType {
797
797
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
798
798
/// demand.provide_ref::<str>(&self.field)
799
- /// .provide_value::<i32>(|| self.num_field);
799
+ /// .provide_value::<i32>(self.num_field);
800
800
/// }
801
801
/// }
802
802
/// ```
@@ -881,36 +881,64 @@ impl<'a> Demand<'a> {
881
881
///
882
882
/// # Examples
883
883
///
884
+ /// Provides an `u8`.
885
+ ///
886
+ /// ```rust
887
+ /// #![feature(provide_any)]
888
+ ///
889
+ /// use std::any::{Provider, Demand};
890
+ /// # struct SomeConcreteType { field: u8 }
891
+ ///
892
+ /// impl Provider for SomeConcreteType {
893
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
894
+ /// demand.provide_value::<u8>(self.field);
895
+ /// }
896
+ /// }
897
+ /// ```
898
+ #[ unstable( feature = "provide_any" , issue = "96024" ) ]
899
+ pub fn provide_value < T > ( & mut self , value : T ) -> & mut Self
900
+ where
901
+ T : ' static ,
902
+ {
903
+ self . provide :: < tags:: Value < T > > ( value)
904
+ }
905
+
906
+ /// Provide a value or other type with only static lifetimes computed using a closure.
907
+ ///
908
+ /// # Examples
909
+ ///
884
910
/// Provides a `String` by cloning.
885
911
///
886
912
/// ```rust
887
- /// # #![feature(provide_any)]
913
+ /// #![feature(provide_any)]
914
+ ///
888
915
/// use std::any::{Provider, Demand};
889
916
/// # struct SomeConcreteType { field: String }
890
917
///
891
918
/// impl Provider for SomeConcreteType {
892
919
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
893
- /// demand.provide_value ::<String>(|| self.field.clone());
920
+ /// demand.provide_value_with ::<String>(|| self.field.clone());
894
921
/// }
895
922
/// }
896
923
/// ```
897
924
#[ unstable( feature = "provide_any" , issue = "96024" ) ]
898
- pub fn provide_value < T > ( & mut self , fulfil : impl FnOnce ( ) -> T ) -> & mut Self
925
+ pub fn provide_value_with < T > ( & mut self , fulfil : impl FnOnce ( ) -> T ) -> & mut Self
899
926
where
900
927
T : ' static ,
901
928
{
902
929
self . provide_with :: < tags:: Value < T > > ( fulfil)
903
930
}
904
931
905
- /// Provide a reference, note that the referee type must be bounded by `'static`,
932
+ /// Provide a reference. The referee type must be bounded by `'static`,
906
933
/// but may be unsized.
907
934
///
908
935
/// # Examples
909
936
///
910
937
/// Provides a reference to a field as a `&str`.
911
938
///
912
939
/// ```rust
913
- /// # #![feature(provide_any)]
940
+ /// #![feature(provide_any)]
941
+ ///
914
942
/// use std::any::{Provider, Demand};
915
943
/// # struct SomeConcreteType { field: String }
916
944
///
@@ -925,6 +953,40 @@ impl<'a> Demand<'a> {
925
953
self . provide :: < tags:: Ref < tags:: MaybeSizedValue < T > > > ( value)
926
954
}
927
955
956
+ /// Provide a reference computed using a closure. The referee type
957
+ /// must be bounded by `'static`, but may be unsized.
958
+ ///
959
+ /// # Examples
960
+ ///
961
+ /// Provides a reference to a field as a `&str`.
962
+ ///
963
+ /// ```rust
964
+ /// #![feature(provide_any)]
965
+ ///
966
+ /// use std::any::{Provider, Demand};
967
+ /// # struct SomeConcreteType { business: String, party: String }
968
+ /// # fn today_is_a_weekday() -> bool { true }
969
+ ///
970
+ /// impl Provider for SomeConcreteType {
971
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
972
+ /// demand.provide_ref_with::<str>(|| {
973
+ /// if today_is_a_weekday() {
974
+ /// &self.business
975
+ /// } else {
976
+ /// &self.party
977
+ /// }
978
+ /// });
979
+ /// }
980
+ /// }
981
+ /// ```
982
+ #[ unstable( feature = "provide_any" , issue = "96024" ) ]
983
+ pub fn provide_ref_with < T : ?Sized + ' static > (
984
+ & mut self ,
985
+ fulfil : impl FnOnce ( ) -> & ' a T ,
986
+ ) -> & mut Self {
987
+ self . provide_with :: < tags:: Ref < tags:: MaybeSizedValue < T > > > ( fulfil)
988
+ }
989
+
928
990
/// Provide a value with the given `Type` tag.
929
991
fn provide < I > ( & mut self , value : I :: Reified ) -> & mut Self
930
992
where
@@ -946,6 +1008,156 @@ impl<'a> Demand<'a> {
946
1008
}
947
1009
self
948
1010
}
1011
+
1012
+ /// Check if the `Demand` would be satisfied if provided with a
1013
+ /// value of the specified type. If the type does not match or has
1014
+ /// already been provided, returns false.
1015
+ ///
1016
+ /// # Examples
1017
+ ///
1018
+ /// Check if an `u8` still needs to be provided and then provides
1019
+ /// it.
1020
+ ///
1021
+ /// ```rust
1022
+ /// #![feature(provide_any)]
1023
+ ///
1024
+ /// use std::any::{Provider, Demand};
1025
+ ///
1026
+ /// struct Parent(Option<u8>);
1027
+ ///
1028
+ /// impl Provider for Parent {
1029
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1030
+ /// if let Some(v) = self.0 {
1031
+ /// demand.provide_value::<u8>(v);
1032
+ /// }
1033
+ /// }
1034
+ /// }
1035
+ ///
1036
+ /// struct Child {
1037
+ /// parent: Parent,
1038
+ /// }
1039
+ ///
1040
+ /// impl Child {
1041
+ /// // Pretend that this takes a lot of resources to evaluate.
1042
+ /// fn an_expensive_computation(&self) -> Option<u8> {
1043
+ /// Some(99)
1044
+ /// }
1045
+ /// }
1046
+ ///
1047
+ /// impl Provider for Child {
1048
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1049
+ /// // In general, we don't know if this call will provide
1050
+ /// // an `u8` value or not...
1051
+ /// self.parent.provide(demand);
1052
+ ///
1053
+ /// // ...so we check to see if the `u8` is needed before
1054
+ /// // we run our expensive computation.
1055
+ /// if demand.would_be_satisfied_by_value_of::<u8>() {
1056
+ /// if let Some(v) = self.an_expensive_computation() {
1057
+ /// demand.provide_value::<u8>(v);
1058
+ /// }
1059
+ /// }
1060
+ ///
1061
+ /// // The demand will be satisfied now, regardless of if
1062
+ /// // the parent provided the value or we did.
1063
+ /// assert!(!demand.would_be_satisfied_by_value_of::<u8>());
1064
+ /// }
1065
+ /// }
1066
+ ///
1067
+ /// let parent = Parent(Some(42));
1068
+ /// let child = Child { parent };
1069
+ /// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
1070
+ ///
1071
+ /// let parent = Parent(None);
1072
+ /// let child = Child { parent };
1073
+ /// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
1074
+ /// ```
1075
+ #[ unstable( feature = "provide_any" , issue = "96024" ) ]
1076
+ pub fn would_be_satisfied_by_value_of < T > ( & self ) -> bool
1077
+ where
1078
+ T : ' static ,
1079
+ {
1080
+ self . would_be_satisfied_by :: < tags:: Value < T > > ( )
1081
+ }
1082
+
1083
+ /// Check if the `Demand` would be satisfied if provided with a
1084
+ /// reference to a value of the specified type. If the type does
1085
+ /// not match or has already been provided, returns false.
1086
+ ///
1087
+ /// # Examples
1088
+ ///
1089
+ /// Check if a `&str` still needs to be provided and then provides
1090
+ /// it.
1091
+ ///
1092
+ /// ```rust
1093
+ /// #![feature(provide_any)]
1094
+ ///
1095
+ /// use std::any::{Provider, Demand};
1096
+ ///
1097
+ /// struct Parent(Option<String>);
1098
+ ///
1099
+ /// impl Provider for Parent {
1100
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1101
+ /// if let Some(v) = &self.0 {
1102
+ /// demand.provide_ref::<str>(v);
1103
+ /// }
1104
+ /// }
1105
+ /// }
1106
+ ///
1107
+ /// struct Child {
1108
+ /// parent: Parent,
1109
+ /// name: String,
1110
+ /// }
1111
+ ///
1112
+ /// impl Child {
1113
+ /// // Pretend that this takes a lot of resources to evaluate.
1114
+ /// fn an_expensive_computation(&self) -> Option<&str> {
1115
+ /// Some(&self.name)
1116
+ /// }
1117
+ /// }
1118
+ ///
1119
+ /// impl Provider for Child {
1120
+ /// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
1121
+ /// // In general, we don't know if this call will provide
1122
+ /// // a `str` reference or not...
1123
+ /// self.parent.provide(demand);
1124
+ ///
1125
+ /// // ...so we check to see if the `&str` is needed before
1126
+ /// // we run our expensive computation.
1127
+ /// if demand.would_be_satisfied_by_ref_of::<str>() {
1128
+ /// if let Some(v) = self.an_expensive_computation() {
1129
+ /// demand.provide_ref::<str>(v);
1130
+ /// }
1131
+ /// }
1132
+ ///
1133
+ /// // The demand will be satisfied now, regardless of if
1134
+ /// // the parent provided the reference or we did.
1135
+ /// assert!(!demand.would_be_satisfied_by_ref_of::<str>());
1136
+ /// }
1137
+ /// }
1138
+ ///
1139
+ /// let parent = Parent(Some("parent".into()));
1140
+ /// let child = Child { parent, name: "child".into() };
1141
+ /// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
1142
+ ///
1143
+ /// let parent = Parent(None);
1144
+ /// let child = Child { parent, name: "child".into() };
1145
+ /// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
1146
+ /// ```
1147
+ #[ unstable( feature = "provide_any" , issue = "96024" ) ]
1148
+ pub fn would_be_satisfied_by_ref_of < T > ( & self ) -> bool
1149
+ where
1150
+ T : ?Sized + ' static ,
1151
+ {
1152
+ self . would_be_satisfied_by :: < tags:: Ref < tags:: MaybeSizedValue < T > > > ( )
1153
+ }
1154
+
1155
+ fn would_be_satisfied_by < I > ( & self ) -> bool
1156
+ where
1157
+ I : tags:: Type < ' a > ,
1158
+ {
1159
+ matches ! ( self . 0 . downcast:: <I >( ) , Some ( TaggedOption ( None ) ) )
1160
+ }
949
1161
}
950
1162
951
1163
#[ unstable( feature = "provide_any" , issue = "96024" ) ]
@@ -1050,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a {
1050
1262
/// Returns some reference to the dynamic value if it is tagged with `I`,
1051
1263
/// or `None` otherwise.
1052
1264
#[ inline]
1265
+ fn downcast < I > ( & self ) -> Option < & TaggedOption < ' a , I > >
1266
+ where
1267
+ I : tags:: Type < ' a > ,
1268
+ {
1269
+ if self . tag_id ( ) == TypeId :: of :: < I > ( ) {
1270
+ // SAFETY: Just checked whether we're pointing to an I.
1271
+ Some ( unsafe { & * ( self as * const Self ) . cast :: < TaggedOption < ' a , I > > ( ) } )
1272
+ } else {
1273
+ None
1274
+ }
1275
+ }
1276
+
1277
+ /// Returns some mutable reference to the dynamic value if it is tagged with `I`,
1278
+ /// or `None` otherwise.
1279
+ #[ inline]
1053
1280
fn downcast_mut < I > ( & mut self ) -> Option < & mut TaggedOption < ' a , I > >
1054
1281
where
1055
1282
I : tags:: Type < ' a > ,
0 commit comments