152
152
/// # should_pass().unwrap();
153
153
/// ```
154
154
///
155
+ /// If `field!` is qualified by both `&` and `ref`, they can both be omitted.
156
+ ///
155
157
/// ```
156
158
/// # use googletest::prelude::*;
157
159
/// #[derive(Debug)]
158
160
/// pub struct AStruct{a_field: String};
159
161
/// # fn should_pass() -> Result<()> {
160
162
/// verify_that!(AStruct{a_field: "32".into()}, field!(&AStruct.a_field, ref eq("32")))?;
163
+ /// verify_that!(AStruct{a_field: "32".into()}, field!(AStruct.a_field, eq("32")))?;
161
164
/// # Ok(())
162
165
/// # }
163
166
/// # should_pass().unwrap();
@@ -173,12 +176,14 @@ macro_rules! __field {
173
176
174
177
// Internal-only macro created so that the macro definition does not appear in
175
178
// generated documentation.
179
+ // We cannot use `path` or `ty` to capture the type as we are terminating the
180
+ // type with a . (dot).
176
181
#[ doc( hidden) ]
177
182
#[ macro_export]
178
183
macro_rules! field_internal {
179
184
( & $( $t: ident) ::+. $field: tt, ref $m: expr) => { {
180
- use $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: field_ref_matcher ;
181
- field_ref_matcher (
185
+ use $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: field_matcher ;
186
+ field_matcher (
182
187
|o: & _| {
183
188
match o {
184
189
& $( $t) ::* { $field: ref value, .. } => Some ( value) ,
@@ -195,7 +200,7 @@ macro_rules! field_internal {
195
200
( & $( $t: ident) ::+. $field: tt, $m: expr) => { {
196
201
use $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: field_matcher;
197
202
field_matcher(
198
- |o: & _| {
203
+ |o: && _| {
199
204
match o {
200
205
& $( $t) ::* { $field: value, .. } => Some ( value) ,
201
206
// The pattern below is unreachable if the type is a struct (as opposed to an
@@ -211,7 +216,7 @@ macro_rules! field_internal {
211
216
( $( $t: ident) ::+. $field: tt, $m: expr) => { {
212
217
use $crate:: matchers:: __internal_unstable_do_not_depend_on_these:: field_matcher;
213
218
field_matcher(
214
- |o| {
219
+ |o: & _ | {
215
220
match o {
216
221
$( $t) ::* { $field: value, .. } => Some ( value) ,
217
222
// The pattern below is unreachable if the type is a struct (as opposed to an
@@ -242,36 +247,33 @@ pub mod internal {
242
247
///
243
248
/// **For internal use only. API stablility is not guaranteed!**
244
249
#[ doc( hidden) ]
245
- pub fn field_matcher < ExtractorT , InnerMatcher > (
246
- field_accessor : ExtractorT ,
250
+ pub fn field_matcher < OuterT , InnerT , InnerMatcher > (
251
+ field_accessor : fn ( & OuterT ) -> Option < & InnerT > ,
247
252
field_path : & ' static str ,
248
253
inner : InnerMatcher ,
249
- ) -> FieldMatcher < ExtractorT , InnerMatcher > {
254
+ ) -> FieldMatcher < OuterT , InnerT , InnerMatcher > {
250
255
FieldMatcher { field_accessor, field_path, inner }
251
256
}
252
257
253
258
#[ derive( MatcherBase ) ]
254
- pub struct FieldMatcher < ExtractorT , InnerMatcher > {
255
- field_accessor : ExtractorT ,
259
+ pub struct FieldMatcher < OuterT , InnerT , InnerMatcher > {
260
+ field_accessor : fn ( & OuterT ) -> Option < & InnerT > ,
256
261
field_path : & ' static str ,
257
262
inner : InnerMatcher ,
258
263
}
259
- impl <
260
- OuterT : Debug + Copy ,
261
- InnerT : Debug + Copy ,
262
- ExtractorT : Fn ( OuterT ) -> Option < InnerT > ,
263
- InnerMatcher : Matcher < InnerT > ,
264
- > Matcher < OuterT > for FieldMatcher < ExtractorT , InnerMatcher >
264
+
265
+ impl < ' a , OuterT : Debug + ' a , InnerT : Debug + ' a , InnerMatcher : Matcher < & ' a InnerT > >
266
+ Matcher < & ' a OuterT > for FieldMatcher < OuterT , InnerT , InnerMatcher >
265
267
{
266
- fn matches ( & self , actual : OuterT ) -> MatcherResult {
268
+ fn matches ( & self , actual : & ' a OuterT ) -> MatcherResult {
267
269
if let Some ( value) = ( self . field_accessor ) ( actual) {
268
270
self . inner . matches ( value)
269
271
} else {
270
272
MatcherResult :: NoMatch
271
273
}
272
274
}
273
275
274
- fn explain_match ( & self , actual : OuterT ) -> Description {
276
+ fn explain_match ( & self , actual : & ' a OuterT ) -> Description {
275
277
if let Some ( actual) = ( self . field_accessor ) ( actual) {
276
278
format ! (
277
279
"which has field `{}`, {}" ,
@@ -297,49 +299,23 @@ pub mod internal {
297
299
}
298
300
}
299
301
300
- #[ doc( hidden) ]
301
- pub fn field_ref_matcher <
302
- InnerT ,
303
- OuterT ,
304
- ExtractorT : for < ' a > Fn ( & ' a OuterT ) -> Option < & ' a InnerT > ,
305
- InnerMatcher ,
306
- > (
307
- field_accessor : ExtractorT ,
308
- field_path : & ' static str ,
309
- inner : InnerMatcher ,
310
- ) -> FieldMatcher < ExtractorT , InnerMatcher > {
311
- FieldMatcher { field_accessor, field_path, inner }
312
- }
313
-
314
- #[ derive( MatcherBase ) ]
315
- pub struct FieldRefMatcher < ExtractorT , InnerMatcher > {
316
- field_accessor : ExtractorT ,
317
- field_path : & ' static str ,
318
- inner : InnerMatcher ,
319
- }
320
-
321
- impl <
322
- ' a ,
323
- OuterT : Debug + ' a ,
324
- InnerT : Debug + ' a ,
325
- ExtractorT : Fn ( & ' a OuterT ) -> Option < & ' a InnerT > ,
326
- InnerMatcher : Matcher < & ' a InnerT > ,
327
- > Matcher < & ' a OuterT > for FieldRefMatcher < ExtractorT , InnerMatcher >
302
+ impl < OuterT : Debug + Copy , InnerT : Debug + Copy , InnerMatcher : Matcher < InnerT > > Matcher < OuterT >
303
+ for FieldMatcher < OuterT , InnerT , InnerMatcher >
328
304
{
329
- fn matches ( & self , actual : & ' a OuterT ) -> MatcherResult {
330
- if let Some ( value) = ( self . field_accessor ) ( actual) {
331
- self . inner . matches ( value)
305
+ fn matches ( & self , actual : OuterT ) -> MatcherResult {
306
+ if let Some ( value) = ( self . field_accessor ) ( & actual) {
307
+ self . inner . matches ( * value)
332
308
} else {
333
309
MatcherResult :: NoMatch
334
310
}
335
311
}
336
312
337
- fn explain_match ( & self , actual : & ' a OuterT ) -> Description {
338
- if let Some ( actual) = ( self . field_accessor ) ( actual) {
313
+ fn explain_match ( & self , actual : OuterT ) -> Description {
314
+ if let Some ( actual) = ( self . field_accessor ) ( & actual) {
339
315
format ! (
340
316
"which has field `{}`, {}" ,
341
317
self . field_path,
342
- self . inner. explain_match( actual)
318
+ self . inner. explain_match( * actual)
343
319
)
344
320
. into ( )
345
321
} else {
0 commit comments