@@ -1008,6 +1008,156 @@ impl<'a> Demand<'a> {
1008
1008
}
1009
1009
self
1010
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
+ }
1011
1161
}
1012
1162
1013
1163
#[ unstable( feature = "provide_any" , issue = "96024" ) ]
@@ -1112,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a {
1112
1262
/// Returns some reference to the dynamic value if it is tagged with `I`,
1113
1263
/// or `None` otherwise.
1114
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]
1115
1280
fn downcast_mut < I > ( & mut self ) -> Option < & mut TaggedOption < ' a , I > >
1116
1281
where
1117
1282
I : tags:: Type < ' a > ,
0 commit comments