1 // vim: tw=80
2 use super::*;
3
4 use quote::ToTokens;
5
6 /// Convert a trait object reference into a reference to a Boxed trait
7 ///
8 /// # Returns
9 ///
10 /// Returns `true` if it was necessary to box the type.
dedynify(ty: &mut Type) -> bool11 fn dedynify(ty: &mut Type) -> bool {
12 if let Type::Reference(ref mut tr) = ty {
13 if let Type::TraitObject(ref tto) = tr.elem.as_ref() {
14 if let Some(lt) = &tr.lifetime {
15 if lt.ident == "static" {
16 // For methods that return 'static references, the user can
17 // usually actually supply one, unlike nonstatic references.
18 // dedynify is unneeded and harmful in such cases.
19 //
20 // But we do need to add parens to prevent parsing errors
21 // when methods like returning add a `+ Send` to the output
22 // type.
23 *tr.elem = parse2(quote!((#tto))).unwrap();
24 return false;
25 }
26 }
27
28 *tr.elem = parse2(quote!(Box<#tto>)).unwrap();
29 return true;
30 }
31 }
32 false
33 }
34
35 /// Convert a special reference type like "&str" into a reference to its owned
36 /// type like "&String".
destrify(ty: &mut Type)37 fn destrify(ty: &mut Type) {
38 if let Type::Reference(ref mut tr) = ty {
39 if let Some(lt) = &tr.lifetime {
40 if lt.ident == "static" {
41 // For methods that return 'static references, the user can
42 // usually actually supply one, unlike nonstatic references.
43 // destrify is unneeded and harmful in such cases.
44 return;
45 }
46 }
47
48 let path_ty: TypePath = parse2(quote!(Path)).unwrap();
49 let pathbuf_ty: Type = parse2(quote!(::std::path::PathBuf)).unwrap();
50
51 let str_ty: TypePath = parse2(quote!(str)).unwrap();
52 let string_ty: Type = parse2(quote!(::std::string::String)).unwrap();
53
54 let cstr_ty: TypePath = parse2(quote!(CStr)).unwrap();
55 let cstring_ty: Type = parse2(quote!(::std::ffi::CString)).unwrap();
56
57 let osstr_ty: TypePath = parse2(quote!(OsStr)).unwrap();
58 let osstring_ty: Type = parse2(quote!(::std::ffi::OsString)).unwrap();
59
60 match tr.elem.as_ref() {
61 Type::Path(ref path) if *path == cstr_ty =>
62 *tr.elem = cstring_ty,
63 Type::Path(ref path) if *path == osstr_ty =>
64 *tr.elem = osstring_ty,
65 Type::Path(ref path) if *path == path_ty =>
66 *tr.elem = pathbuf_ty,
67 Type::Path(ref path) if *path == str_ty =>
68 *tr.elem = string_ty,
69 Type::Slice(ts) => {
70 let inner = (*ts.elem).clone();
71 let mut segments = Punctuated::new();
72 segments.push(format_ident!("std").into());
73 segments.push(format_ident!("vec").into());
74 let mut v: PathSegment = format_ident!("Vec").into();
75 let mut abga_args = Punctuated::new();
76 abga_args.push(GenericArgument::Type(inner));
77 v.arguments = PathArguments::AngleBracketed(
78 AngleBracketedGenericArguments {
79 colon2_token: None,
80 lt_token: Token),
81 args: abga_args,
82 gt_token: Token),
83 }
84 );
85 segments.push(v);
86
87 *tr.elem = Type::Path(TypePath {
88 qself: None,
89 path: Path {
90 leading_colon: Some(Token)),
91 segments
92 }
93 });
94 },
95 _ => (), // Nothing to do
96 };
97 }
98 }
99
100 /// Return the owned version of the input.
ownify(ty: &Type) -> Type101 fn ownify(ty: &Type) -> Type {
102 if let Type::Reference(ref tr) = &ty {
103 if tr.lifetime.as_ref().map_or(false, |lt| lt.ident == "static")
104 {
105 // Just a static expectation
106 ty.clone()
107 } else {
108 *tr.elem.clone()
109 }
110 } else {
111 ty.clone()
112 }
113 }
114
115 /// Add Send + Sync to a where clause
send_syncify(wc: &mut Option<WhereClause>, bounded_ty: Type)116 fn send_syncify(wc: &mut Option<WhereClause>, bounded_ty: Type) {
117 let mut bounds = Punctuated::new();
118 bounds.push(TypeParamBound::Trait(TraitBound {
119 paren_token: None,
120 modifier: TraitBoundModifier::None,
121 lifetimes: None,
122 path: Path::from(format_ident!("Send"))
123 }));
124 bounds.push(TypeParamBound::Trait(TraitBound {
125 paren_token: None,
126 modifier: TraitBoundModifier::None,
127 lifetimes: None,
128 path: Path::from(format_ident!("Sync"))
129 }));
130 if wc.is_none() {
131 *wc = Some(WhereClause {
132 where_token: <Token![where]>::default(),
133 predicates: Punctuated::new()
134 });
135 }
136 wc.as_mut().unwrap()
137 .predicates.push(
138 WherePredicate::Type(
139 PredicateType {
140 lifetimes: None,
141 bounded_ty,
142 colon_token: Default::default(),
143 bounds
144 }
145 )
146 );
147 }
148
149 /// Build a MockFunction.
150 #[derive(Clone, Copy, Debug)]
151 pub(crate) struct Builder<'a> {
152 attrs: &'a [Attribute],
153 call_levels: Option<usize>,
154 concretize: bool,
155 levels: usize,
156 parent: Option<&'a Ident>,
157 sig: &'a Signature,
158 struct_: Option<&'a Ident>,
159 struct_generics: Option<&'a Generics>,
160 trait_: Option<&'a Ident>,
161 vis: &'a Visibility
162 }
163
164 impl<'a> Builder<'a> {
attrs(&mut self, attrs: &'a[Attribute]) -> &mut Self165 pub fn attrs(&mut self, attrs: &'a[Attribute]) -> &mut Self {
166 self.attrs = attrs;
167 if attrs.iter()
168 .any(is_concretize)
169 {
170 self.concretize = true;
171 }
172 self
173 }
174
build(self) -> MockFunction175 pub fn build(self) -> MockFunction {
176 let mut argnames = Vec::new();
177 let mut argty = Vec::new();
178 let mut is_static = true;
179 let mut predexprs = Vec::new();
180 let mut predty = Vec::new();
181 let mut refpredty = Vec::new();
182
183 let (mut declosured_generics, declosured_inputs, call_exprs) =
184 if self.concretize {
185 concretize_args(&self.sig.generics, &self.sig.inputs)
186 } else {
187 declosurefy(&self.sig.generics, &self.sig.inputs)
188 };
189 // TODO: make concretize and declosurefy work for the same function
190
191 for fa in declosured_inputs.iter() {
192 if let FnArg::Typed(pt) = fa {
193 let argname = (*pt.pat).clone();
194 assert!(!pat_is_self(&argname));
195 let aty = supersuperfy(&pt.ty, self.levels);
196 if let Type::Reference(ref tr) = aty {
197 predexprs.push(quote!(#argname));
198 predty.push((*tr.elem).clone());
199 let tr2 = Type::Reference(TypeReference {
200 and_token: tr.and_token,
201 lifetime: None,
202 mutability: None,
203 elem: tr.elem.clone()
204 });
205 refpredty.push(tr2);
206 } else {
207 predexprs.push(quote!(&#argname));
208 predty.push(aty.clone());
209 let tr = TypeReference {
210 and_token: Token),
211 lifetime: None,
212 mutability: None,
213 elem: Box::new(aty.clone())
214 };
215 refpredty.push(Type::Reference(tr));
216 };
217 argnames.push(argname);
218 argty.push(aty.clone());
219 } else {
220 is_static = false;
221 }
222 }
223 let (output, boxed) = match self.sig.output {
224 ReturnType::Default => (
225 Type::Tuple(TypeTuple {
226 paren_token: token::Paren::default(),
227 elems: Punctuated::new(),
228 }),
229 false,
230 ),
231 ReturnType::Type(_, ref ty) => {
232 let mut output_ty = supersuperfy(ty, self.levels);
233 destrify(&mut output_ty);
234 let boxed = dedynify(&mut output_ty);
235 (output_ty, boxed)
236 }
237 };
238 supersuperfy_generics(&mut declosured_generics, self.levels);
239 let owned_output = ownify(&output);
240 let mut return_ref = false;
241 let mut return_refmut = false;
242 if let Type::Reference(ref tr) = &output {
243 if tr.lifetime.as_ref().map_or(true, |lt| lt.ident != "static")
244 {
245 if tr.mutability.is_none() {
246 return_ref = true;
247 } else {
248 return_refmut = true;
249 }
250 }
251 };
252 if is_static && (return_ref || return_refmut) {
253 compile_error(self.sig.span(),
254 "Mockall cannot mock static methods that return non-'static references. It's unclear what the return value's lifetime should be.");
255 }
256 let struct_generics = self.struct_generics.cloned()
257 .unwrap_or_default();
258 let (type_generics, salifetimes, srlifetimes) = split_lifetimes(
259 struct_generics.clone(),
260 &declosured_inputs,
261 &ReturnType::Type(<Token![->]>::default(),
262 Box::new(owned_output.clone()))
263 );
264 let srltg = lifetimes_to_generics(&srlifetimes);
265 let (call_generics, malifetimes, mrlifetimes) = split_lifetimes(
266 declosured_generics,
267 &declosured_inputs,
268 &ReturnType::Type(<Token![->]>::default(),
269 Box::new(owned_output.clone()))
270 );
271 let mrltg = lifetimes_to_generics(&mrlifetimes);
272 let cgenerics = merge_generics(&type_generics, &call_generics);
273 let egenerics = merge_generics(
274 &merge_generics(&cgenerics, &srltg),
275 &mrltg);
276 let alifetimes = salifetimes.into_iter()
277 .collect::<HashSet<LifetimeParam>>()
278 .union(&malifetimes.into_iter().collect::<HashSet<_>>())
279 .cloned()
280 .collect();
281
282 let fn_params = egenerics.type_params()
283 .map(|tp| tp.ident.clone())
284 .collect();
285 let call_levels = self.call_levels.unwrap_or(self.levels);
286
287 MockFunction {
288 alifetimes,
289 argnames,
290 argty,
291 attrs: self.attrs.to_vec(),
292 call_exprs,
293 call_generics,
294 call_vis: expectation_visibility(self.vis, call_levels),
295 concretize: self.concretize,
296 egenerics,
297 cgenerics,
298 fn_params,
299 is_static,
300 mod_ident: self.parent.unwrap_or(&Ident::new("FIXME", Span::call_site())).clone(),
301 output,
302 owned_output,
303 boxed,
304 predexprs,
305 predty,
306 refpredty,
307 return_ref,
308 return_refmut,
309 sig: self.sig.clone(),
310 struct_: self.struct_.cloned(),
311 struct_generics,
312 trait_: self.trait_.cloned(),
313 type_generics,
314 privmod_vis: expectation_visibility(self.vis, self.levels)
315 }
316 }
317
318 /// How many levels of modules beneath the original function this one is
319 /// nested.
call_levels(&mut self, levels: usize) -> &mut Self320 pub fn call_levels(&mut self, levels: usize) -> &mut Self {
321 self.call_levels = Some(levels);
322 self
323 }
324
325 /// How many levels of modules beneath the original function this one's
326 /// private module is nested.
levels(&mut self, levels: usize) -> &mut Self327 pub fn levels(&mut self, levels: usize) -> &mut Self {
328 self.levels = levels;
329 self
330 }
331
332 /// # Arguments
333 ///
334 /// * sig: The signature of the mockable function
335 /// * v: The visibility of the mockable function
new(sig: &'a Signature, vis: &'a Visibility) -> Self336 pub fn new(sig: &'a Signature, vis: &'a Visibility) -> Self {
337 Builder {
338 attrs: &[],
339 concretize: false,
340 levels: 0,
341 call_levels: None,
342 parent: None,
343 sig,
344 struct_: None,
345 struct_generics: None,
346 trait_: None,
347 vis
348 }
349 }
350
351 /// Supply the name of the parent module
parent(&mut self, ident: &'a Ident) -> &mut Self352 pub fn parent(&mut self, ident: &'a Ident) -> &mut Self {
353 self.parent = Some(ident);
354 self
355 }
356
357 /// Supply the name of the parent struct, if any
struct_(&mut self, ident: &'a Ident) -> &mut Self358 pub fn struct_(&mut self, ident: &'a Ident) -> &mut Self {
359 self.struct_= Some(ident);
360 self
361 }
362
363 /// Supply the Generics of the parent struct, if any
struct_generics(&mut self, generics: &'a Generics) -> &mut Self364 pub fn struct_generics(&mut self, generics: &'a Generics) -> &mut Self {
365 self.struct_generics = Some(generics);
366 self
367 }
368
369 /// Supply the name of the method's trait, if any
trait_(&mut self, ident: &'a Ident) -> &mut Self370 pub fn trait_(&mut self, ident: &'a Ident) -> &mut Self {
371 self.trait_ = Some(ident);
372 self
373 }
374 }
375
376 #[derive(Clone)]
377 pub(crate) struct MockFunction {
378 /// Lifetimes of the mocked method that relate to the arguments but not the
379 /// return value
380 alifetimes: Punctuated<LifetimeParam, token::Comma>,
381 /// Names of the method arguments
382 argnames: Vec<Pat>,
383 /// Types of the method arguments
384 argty: Vec<Type>,
385 /// any attributes on the original function, like #[inline]
386 pub attrs: Vec<Attribute>,
387 /// Expressions that should be used for Expectation::call's arguments
388 call_exprs: Vec<TokenStream>,
389 /// Generics used for the expectation call
390 call_generics: Generics,
391 /// Visibility of the mock function itself
392 call_vis: Visibility,
393 /// Are we turning generic arguments into concrete trait objects?
394 concretize: bool,
395 /// Generics of the Expectation object
396 egenerics: Generics,
397 /// Generics of the Common object
398 cgenerics: Generics,
399 /// The mock function's generic types as a list of types
400 fn_params: Vec<Ident>,
401 /// Is this for a static method or free function?
402 is_static: bool,
403 /// name of the function's parent module
404 mod_ident: Ident,
405 /// Output type of the Method, supersuperfied.
406 output: Type,
407 /// Owned version of the output type of the Method, supersuperfied.
408 ///
409 /// If the real output type is a non-'static reference, then it will differ
410 /// from this field.
411 owned_output: Type,
412 /// True if the `owned_type` is boxed by `Box<>`.
413 boxed: bool,
414 /// Expressions that create the predicate arguments from the call arguments
415 predexprs: Vec<TokenStream>,
416 /// Types used for Predicates. Will be almost the same as args, but every
417 /// type will be a non-reference type.
418 predty: Vec<Type>,
419 /// Does the function return a non-'static reference?
420 return_ref: bool,
421 /// Does the function return a mutable reference?
422 return_refmut: bool,
423 /// References to every type in `predty`.
424 refpredty: Vec<Type>,
425 /// The signature of the mockable function
426 sig: Signature,
427 /// Name of the parent structure, if any
428 struct_: Option<Ident>,
429 /// Generics of the parent structure
430 struct_generics: Generics,
431 /// Name of this method's trait, if the method comes from a trait
432 trait_: Option<Ident>,
433 /// Type generics of the mock structure
434 type_generics: Generics,
435 /// Visibility of the expectation and its methods
436 privmod_vis: Visibility
437 }
438
439 impl MockFunction {
440 /// Return the mock function itself
441 ///
442 /// # Arguments
443 ///
444 /// * `modname`: Name of the parent struct's private module
445 // Supplying modname is an unfortunately hack. Ideally MockFunction
446 // wouldn't need to know that.
call(&self, modname: Option<&Ident>) -> impl ToTokens447 pub fn call(&self, modname: Option<&Ident>) -> impl ToTokens {
448 let attrs = AttrFormatter::new(&self.attrs).format();
449 let call_exprs = &self.call_exprs;
450 let (_, tg, _) = if self.is_method_generic() || self.is_static() {
451 &self.egenerics
452 } else {
453 &self.call_generics
454 }.split_for_impl();
455 let tbf = tg.as_turbofish();
456 let name = self.name();
457 let desc = self.desc();
458 let no_match_msg = quote!(std::format!(
459 "{}: No matching expectation found", #desc));
460 let sig = &self.sig;
461 let (vis, dead_code) = if self.trait_.is_some() {
462 (&Visibility::Inherited, quote!())
463 } else {
464 let dead_code = if let Visibility::Inherited = self.call_vis {
465 // This private method may be a helper only used by the struct's
466 // other methods, which we are mocking. If so, the mock method
467 // will be dead code. But we can't simply eliminate it, because
468 // it might also be used by other code in the same module.
469 quote!(#[allow(dead_code)])
470 } else {
471 quote!()
472 };
473 (&self.call_vis, dead_code)
474 };
475 // Add #[no_mangle] attribute to preserve the function name
476 // as-is, without mangling, for compatibility with C functions.
477 let no_mangle = if let Some(ref abi) = self.sig.abi {
478 if let Some(ref name) = abi.name {
479 if name.value().ne("Rust") {
480 quote!(#[no_mangle])
481 } else {
482 quote!()
483 }
484 } else {
485 // This is the same as extern "C"
486 quote!(#[no_mangle])
487 }
488 } else {
489 quote!()
490 };
491 let substruct_obj: TokenStream = if let Some(trait_) = &self.trait_ {
492 let ident = format_ident!("{}_expectations", trait_);
493 quote!(#ident.)
494 } else {
495 quote!()
496 };
497 let call = if self.return_refmut {
498 Ident::new("call_mut", Span::call_site())
499 } else {
500 Ident::new("call", Span::call_site())
501 };
502 let mut deref = quote!();
503 if self.boxed {
504 if self.return_ref {
505 deref = quote!(&**);
506 } else if self.return_refmut {
507 deref = quote!(&mut **);
508 }
509 }
510 if self.is_static {
511 let outer_mod_path = self.outer_mod_path(modname);
512 quote!(
513 // Don't add a doc string. The original is included in #attrs
514 #(#attrs)*
515 #dead_code
516 #no_mangle
517 #vis #sig {
518 use ::mockall::{ViaDebug, ViaNothing};
519 let no_match_msg = #no_match_msg;
520 #deref {
521 let __mockall_guard = #outer_mod_path::EXPECTATIONS
522 .lock().unwrap();
523 /*
524 * TODO: catch panics, then gracefully release the mutex
525 * so it won't be poisoned. This requires bounding any
526 * generic parameters with UnwindSafe
527 */
528 /* std::panic::catch_unwind(|| */
529 __mockall_guard.#call #tbf(#(#call_exprs,)*)
530 /*)*/
531 }.expect(&no_match_msg)
532 }
533 )
534 } else {
535 quote!(
536 // Don't add a doc string. The original is included in #attrs
537 #(#attrs)*
538 #dead_code
539 #no_mangle
540 #vis #sig {
541 use ::mockall::{ViaDebug, ViaNothing};
542 let no_match_msg = #no_match_msg;
543 #deref self.#substruct_obj #name.#call #tbf(#(#call_exprs,)*)
544 .expect(&no_match_msg)
545 }
546
547 )
548 }
549 }
550
551 /// Return this method's contribution to its parent's checkpoint method
checkpoint(&self) -> impl ToTokens552 pub fn checkpoint(&self) -> impl ToTokens {
553 let attrs = AttrFormatter::new(&self.attrs)
554 .doc(false)
555 .format();
556 let inner_mod_ident = self.inner_mod_ident();
557 if self.is_static {
558 quote!(
559 #(#attrs)*
560 {
561 let __mockall_timeses = #inner_mod_ident::EXPECTATIONS.lock()
562 .unwrap()
563 .checkpoint()
564 .collect::<Vec<_>>();
565 }
566 )
567 } else {
568 let name = &self.name();
569 quote!(#(#attrs)* { self.#name.checkpoint(); })
570 }
571 }
572
573 /// Return a function that creates a Context object for this function
574 ///
575 /// # Arguments
576 ///
577 /// * `modname`: Name of the parent struct's private module
578 // Supplying modname is an unfortunately hack. Ideally MockFunction
579 // wouldn't need to know that.
context_fn(&self, modname: Option<&Ident>) -> impl ToTokens580 pub fn context_fn(&self, modname: Option<&Ident>) -> impl ToTokens {
581 let attrs = AttrFormatter::new(&self.attrs)
582 .doc(false)
583 .format();
584 let context_docstr = format!("Create a [`Context`]({}{}/struct.Context.html) for mocking the `{}` method",
585 modname.map(|m| format!("{m}/")).unwrap_or_default(),
586 self.inner_mod_ident(),
587 self.name());
588 let context_ident = format_ident!("{}_context", self.name());
589 let (_, tg, _) = self.type_generics.split_for_impl();
590 let outer_mod_path = self.outer_mod_path(modname);
591 let v = &self.call_vis;
592 quote!(
593 #(#attrs)*
594 #[doc = #context_docstr]
595 #v fn #context_ident() -> #outer_mod_path::Context #tg
596 {
597 #outer_mod_path::Context::default()
598 }
599 )
600 }
601
602 /// Generate a code fragment that will print a description of the invocation
desc(&self) -> impl ToTokens603 fn desc(&self) -> impl ToTokens {
604 let argnames = &self.argnames;
605 let name = if let Some(s) = &self.struct_ {
606 format!("{}::{}", s, self.sig.ident)
607 } else {
608 format!("{}::{}", self.mod_ident, self.sig.ident)
609 };
610 let fields = vec!["{:?}"; argnames.len()].join(", ");
611 let fstr = format!("{name}({fields})");
612 quote!(std::format!(#fstr, #((&&::mockall::ArgPrinter(&#argnames)).debug_string()),*))
613 }
614
615 /// Generate code for the expect_ method
616 ///
617 /// # Arguments
618 ///
619 /// * `modname`: Name of the parent struct's private module
620 /// * `self_args`: If supplied, these are the
621 /// AngleBracketedGenericArguments of the self type of the
622 /// trait impl. e.g. The `T` in `impl Foo for Bar<T>`.
623 // Supplying modname is an unfortunately hack. Ideally MockFunction
624 // wouldn't need to know that.
expect(&self, modname: &Ident, self_args: Option<&PathArguments>) -> impl ToTokens625 pub fn expect(&self, modname: &Ident, self_args: Option<&PathArguments>)
626 -> impl ToTokens
627 {
628 let attrs = AttrFormatter::new(&self.attrs)
629 .doc(false)
630 .format();
631 let name = self.name();
632 let expect_ident = format_ident!("expect_{}", name);
633 let expectation_obj = self.expectation_obj(self_args);
634 let funcname = &self.sig.ident;
635 let (_, tg, _) = if self.is_method_generic() {
636 &self.egenerics
637 } else {
638 &self.call_generics
639 }.split_for_impl();
640 let (ig, _, wc) = self.call_generics.split_for_impl();
641 let mut wc = wc.cloned();
642 if self.is_method_generic() && (self.return_ref || self.return_refmut) {
643 // Add Senc + Sync, required for downcast, since Expectation
644 // stores an Option<#owned_output>
645 send_syncify(&mut wc, self.owned_output.clone());
646 }
647 let tbf = tg.as_turbofish();
648 let vis = &self.call_vis;
649
650 #[cfg(not(feature = "nightly_derive"))]
651 let must_use = quote!(#[must_use =
652 "Must set return value when not using the \"nightly\" feature"
653 ]);
654 #[cfg(feature = "nightly_derive")]
655 let must_use = quote!();
656
657 let substruct_obj = if let Some(trait_) = &self.trait_ {
658 let ident = format_ident!("{trait_}_expectations");
659 quote!(#ident.)
660 } else {
661 quote!()
662 };
663 let docstr = format!("Create an [`Expectation`]({}/{}/struct.Expectation.html) for mocking the `{}` method",
664 modname, self.inner_mod_ident(), funcname);
665 quote!(
666 #must_use
667 #[doc = #docstr]
668 #(#attrs)*
669 #vis fn #expect_ident #ig(&mut self)
670 -> &mut #modname::#expectation_obj
671 #wc
672 {
673 self.#substruct_obj #name.expect #tbf()
674 }
675 )
676 }
677
678 /// Return the name of this function's expecation object
expectation_obj(&self, self_args: Option<&PathArguments>) -> impl ToTokens679 fn expectation_obj(&self, self_args: Option<&PathArguments>)
680 -> impl ToTokens
681 {
682 let inner_mod_ident = self.inner_mod_ident();
683 if let Some(PathArguments::AngleBracketed(abga)) = self_args {
684 // staticize any lifetimes that might be present in the Expectation
685 // object but not in the self args. These come from the method's
686 // return type.
687 let mut abga2 = abga.clone();
688 for _ in self.egenerics.lifetimes() {
689 let lt = Lifetime::new("'static", Span::call_site());
690 let la = GenericArgument::Lifetime(lt);
691 abga2.args.insert(0, la);
692 }
693 assert!(!self.is_method_generic(),
694 "specific impls with generic methods are TODO");
695 quote!(#inner_mod_ident::Expectation #abga2)
696 } else {
697 // staticize any lifetimes. This is necessary for methods that
698 // return non-static types, because the Expectation itself must be
699 // 'static.
700 let segenerics = staticize(&self.egenerics);
701 let (_, tg, _) = segenerics.split_for_impl();
702 quote!(#inner_mod_ident::Expectation #tg)
703 }
704 }
705
706 /// Return the name of this function's expecations object
expectations_obj(&self) -> impl ToTokens707 pub fn expectations_obj(&self) -> impl ToTokens {
708 let inner_mod_ident = self.inner_mod_ident();
709 if self.is_method_generic() {
710 quote!(#inner_mod_ident::GenericExpectations)
711 } else {
712 quote!(#inner_mod_ident::Expectations)
713 }
714 }
715
field_definition(&self, modname: Option<&Ident>) -> TokenStream716 pub fn field_definition(&self, modname: Option<&Ident>) -> TokenStream {
717 let name = self.name();
718 let attrs = AttrFormatter::new(&self.attrs)
719 .doc(false)
720 .format();
721 let expectations_obj = &self.expectations_obj();
722 if self.is_method_generic() {
723 quote!(#(#attrs)* #name: #modname::#expectations_obj)
724 } else {
725 // staticize any lifetimes. This is necessary for methods that
726 // return non-static types, because the Expectation itself must be
727 // 'static.
728 let segenerics = staticize(&self.egenerics);
729 let (_, tg, _) = segenerics.split_for_impl();
730 quote!(#(#attrs)* #name: #modname::#expectations_obj #tg)
731 }
732 }
733
734 /// Human-readable name of the mock function
funcname(&self) -> String735 fn funcname(&self) -> String {
736 if let Some(si) = &self.struct_ {
737 format!("{}::{}", si, self.name())
738 } else {
739 format!("{}", self.name())
740 }
741 }
742
hrtb(&self) -> Option<BoundLifetimes>743 fn hrtb(&self) -> Option<BoundLifetimes> {
744 if self.alifetimes.is_empty() {
745 None
746 } else {
747 let lifetimes = lifetimes_to_generic_params(&self.alifetimes);
748 Some(BoundLifetimes {
749 lifetimes,
750 lt_token: <Token![<]>::default(),
751 gt_token: <Token![>]>::default(),
752 .. Default::default()
753 })
754 }
755 }
756
is_expectation_generic(&self) -> bool757 fn is_expectation_generic(&self) -> bool {
758 self.egenerics.params.iter().any(|p| {
759 matches!(p, GenericParam::Type(_))
760 }) || self.egenerics.where_clause.is_some()
761 }
762
763 /// Is the mock method generic (as opposed to a non-generic method of a
764 /// generic mock struct)?
is_method_generic(&self) -> bool765 pub fn is_method_generic(&self) -> bool {
766 self.call_generics.params.iter().any(|p| {
767 matches!(p, GenericParam::Type(_))
768 }) || self.call_generics.where_clause.is_some()
769 }
770
outer_mod_path(&self, modname: Option<&Ident>) -> Path771 fn outer_mod_path(&self, modname: Option<&Ident>) -> Path {
772 let mut path = if let Some(m) = modname {
773 Path::from(PathSegment::from(m.clone()))
774 } else {
775 Path { leading_colon: None, segments: Punctuated::new() }
776 };
777 path.segments.push(PathSegment::from(self.inner_mod_ident()));
778 path
779 }
780
inner_mod_ident(&self) -> Ident781 fn inner_mod_ident(&self) -> Ident {
782 format_ident!("__{}", &self.name())
783 }
784
is_static(&self) -> bool785 pub fn is_static(&self) -> bool {
786 self.is_static
787 }
788
name(&self) -> &Ident789 pub fn name(&self) -> &Ident {
790 &self.sig.ident
791 }
792
793 /// Generate code for this function's private module
priv_module(&self) -> impl ToTokens794 pub fn priv_module(&self) -> impl ToTokens {
795 let attrs = AttrFormatter::new(&self.attrs)
796 .doc(false)
797 .format();
798 let common = &Common{f: self};
799 let context = &Context{f: self};
800 let expectation: Box<dyn ToTokens> = if self.return_ref {
801 Box::new(RefExpectation{f: self})
802 } else if self.return_refmut {
803 Box::new(RefMutExpectation{f: self})
804 } else {
805 Box::new(StaticExpectation{f: self})
806 };
807 let expectations: Box<dyn ToTokens> = if self.return_ref {
808 Box::new(RefExpectations{f: self})
809 } else if self.return_refmut {
810 Box::new(RefMutExpectations{f: self})
811 } else {
812 Box::new(StaticExpectations{f: self})
813 };
814 let generic_expectations = GenericExpectations{f: self};
815 let guard: Box<dyn ToTokens> = if self.is_expectation_generic() {
816 Box::new(GenericExpectationGuard{f: self})
817 } else {
818 Box::new(ConcreteExpectationGuard{f: self})
819 };
820 let matcher = &Matcher{f: self};
821 let std_mutexguard = if self.is_static {
822 quote!(use ::std::sync::MutexGuard;)
823 } else {
824 quote!()
825 };
826 let inner_mod_ident = self.inner_mod_ident();
827 let rfunc: Box<dyn ToTokens> = if self.return_ref {
828 Box::new(RefRfunc{f: self})
829 } else if self.return_refmut {
830 Box::new(RefMutRfunc{f: self})
831 } else {
832 Box::new(StaticRfunc{f: self})
833 };
834 quote!(
835 #(#attrs)*
836 #[allow(missing_docs)]
837 #[allow(clippy::too_many_arguments)]
838 pub mod #inner_mod_ident {
839 use super::*;
840 use ::mockall::CaseTreeExt;
841 #std_mutexguard
842 use ::std::{
843 boxed::Box,
844 mem,
845 ops::{DerefMut, Range},
846 sync::Mutex,
847 vec::Vec,
848 };
849 #rfunc
850 #matcher
851 #common
852 #expectation
853 #expectations
854 #generic_expectations
855 #guard
856 #context
857 }
858 )
859 }
860 }
861
862 /// Holds parts of the expectation that are common for all output types
863 struct Common<'a> {
864 f: &'a MockFunction
865 }
866
867 impl<'a> ToTokens for Common<'a> {
to_tokens(&self, tokens: &mut TokenStream)868 fn to_tokens(&self, tokens: &mut TokenStream) {
869 let argnames = &self.f.argnames;
870 let predty = &self.f.predty;
871 let hrtb = self.f.hrtb();
872 let funcname = self.f.funcname();
873 let (ig, tg, wc) = self.f.cgenerics.split_for_impl();
874 let lg = lifetimes_to_generics(&self.f.alifetimes);
875 let refpredty = &self.f.refpredty;
876 let with_generics_idents = (0..self.f.predty.len())
877 .map(|i| format_ident!("MockallMatcher{i}"))
878 .collect::<Vec<_>>();
879 let with_generics = with_generics_idents.iter()
880 .zip(self.f.predty.iter())
881 .map(|(id, mt)|
882 quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, )
883 ).collect::<TokenStream>();
884 let with_args = self.f.argnames.iter()
885 .zip(with_generics_idents.iter())
886 .map(|(argname, id)| quote!(#argname: #id, ))
887 .collect::<TokenStream>();
888 let boxed_withargs = argnames.iter()
889 .map(|aa| quote!(Box::new(#aa), ))
890 .collect::<TokenStream>();
891 let with_method = if self.f.concretize {
892 quote!(
893 // No `with` method when concretizing generics
894 )
895 } else {
896 quote!(
897 fn with<#with_generics>(&mut self, #with_args)
898 {
899 let mut __mockall_guard = self.matcher.lock().unwrap();
900 *__mockall_guard.deref_mut() =
901 Matcher::Pred(Box::new((#boxed_withargs)));
902 }
903 )
904 };
905
906 quote!(
907 /// Holds the stuff that is independent of the output type
908 struct Common #ig #wc {
909 matcher: Mutex<Matcher #tg>,
910 seq_handle: Option<::mockall::SeqHandle>,
911 times: ::mockall::Times
912 }
913
914 impl #ig std::default::Default for Common #tg #wc
915 {
916 fn default() -> Self {
917 Common {
918 matcher: Mutex::new(Matcher::default()),
919 seq_handle: None,
920 times: ::mockall::Times::default()
921 }
922 }
923 }
924
925 impl #ig Common #tg #wc {
926 fn call(&self, desc: &str) {
927 self.times.call()
928 .unwrap_or_else(|m| {
929 let desc = std::format!(
930 "{}", self.matcher.lock().unwrap());
931 panic!("{}: Expectation({}) {}", #funcname, desc,
932 m);
933 });
934 self.verify_sequence(desc);
935 if ::mockall::ExpectedCalls::TooFew != self.times.is_satisfied() {
936 self.satisfy_sequence()
937 }
938 }
939
940 fn in_sequence(&mut self, __mockall_seq: &mut ::mockall::Sequence)
941 -> &mut Self
942 {
943 assert!(self.times.is_exact(),
944 "Only Expectations with an exact call count have sequences");
945 self.seq_handle = Some(__mockall_seq.next_handle());
946 self
947 }
948
949 fn is_done(&self) -> bool {
950 self.times.is_done()
951 }
952
953 #[allow(clippy::ptr_arg)]
954 fn matches #lg (&self, #( #argnames: &#predty, )*) -> bool {
955 self.matcher.lock().unwrap().matches(#(#argnames, )*)
956 }
957
958 /// Forbid this expectation from ever being called.
959 fn never(&mut self) {
960 self.times.never();
961 }
962
963 fn satisfy_sequence(&self) {
964 if let Some(__mockall_handle) = &self.seq_handle {
965 __mockall_handle.satisfy()
966 }
967 }
968
969 /// Expect this expectation to be called any number of times
970 /// contained with the given range.
971 fn times<MockallR>(&mut self, __mockall_r: MockallR)
972 where MockallR: Into<::mockall::TimesRange>
973 {
974 self.times.times(__mockall_r)
975 }
976
977 #with_method
978
979 fn withf<MockallF>(&mut self, __mockall_f: MockallF)
980 where MockallF: #hrtb Fn(#( #refpredty, )*)
981 -> bool + Send + 'static
982 {
983 let mut __mockall_guard = self.matcher.lock().unwrap();
984 *__mockall_guard.deref_mut() =
985 Matcher::Func(Box::new(__mockall_f));
986 }
987
988 fn withf_st<MockallF>(&mut self, __mockall_f: MockallF)
989 where MockallF: #hrtb Fn(#( #refpredty, )*)
990 -> bool + 'static
991 {
992 let mut __mockall_guard = self.matcher.lock().unwrap();
993 *__mockall_guard.deref_mut() =
994 Matcher::FuncSt(
995 ::mockall::Fragile::new(Box::new(__mockall_f))
996 );
997 }
998
999 fn verify_sequence(&self, desc: &str) {
1000 if let Some(__mockall_handle) = &self.seq_handle {
1001 __mockall_handle.verify(desc)
1002 }
1003 }
1004 }
1005
1006 impl #ig Drop for Common #tg #wc {
1007 fn drop(&mut self) {
1008 if !::std::thread::panicking() {
1009 let desc = std::format!(
1010 "{}", self.matcher.lock().unwrap());
1011 match self.times.is_satisfied() {
1012 ::mockall::ExpectedCalls::TooFew => {
1013 panic!("{}: Expectation({}) called {} time(s) which is fewer than expected {}",
1014 #funcname,
1015 desc,
1016 self.times.count(),
1017 self.times.minimum());
1018 },
1019 ::mockall::ExpectedCalls::TooMany => {
1020 panic!("{}: Expectation({}) called {} time(s) which is more than expected {}",
1021 #funcname,
1022 desc,
1023 self.times.count(),
1024 self.times.maximum());
1025 },
1026 _ => ()
1027 }
1028 }
1029 }
1030 }
1031 ).to_tokens(tokens);
1032 }
1033 }
1034
1035 /// Generates methods that are common for all Expectation types
1036 struct CommonExpectationMethods<'a> {
1037 f: &'a MockFunction
1038 }
1039
1040 impl<'a> ToTokens for CommonExpectationMethods<'a> {
to_tokens(&self, tokens: &mut TokenStream)1041 fn to_tokens(&self, tokens: &mut TokenStream) {
1042 let argnames = &self.f.argnames;
1043 let hrtb = self.f.hrtb();
1044 let lg = lifetimes_to_generics(&self.f.alifetimes);
1045 let predty = &self.f.predty;
1046 let with_generics_idents = (0..self.f.predty.len())
1047 .map(|i| format_ident!("MockallMatcher{i}"))
1048 .collect::<Vec<_>>();
1049 let with_generics = with_generics_idents.iter()
1050 .zip(self.f.predty.iter())
1051 .map(|(id, mt)|
1052 quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, )
1053 ).collect::<TokenStream>();
1054 let with_args = self.f.argnames.iter()
1055 .zip(with_generics_idents.iter())
1056 .map(|(argname, id)| quote!(#argname: #id, ))
1057 .collect::<TokenStream>();
1058 let v = &self.f.privmod_vis;
1059 let with_method = if self.f.concretize {
1060 quote!(
1061 // No `with` method when concretizing generics
1062 )
1063 } else {
1064 quote!(
1065 /// Set matching criteria for this Expectation.
1066 ///
1067 /// The matching predicate can be anything implemening the
1068 /// [`Predicate`](../../../mockall/trait.Predicate.html) trait. Only
1069 /// one matcher can be set per `Expectation` at a time.
1070 #v fn with<#with_generics>(&mut self, #with_args) -> &mut Self
1071 {
1072 self.common.with(#(#argnames, )*);
1073 self
1074 }
1075 )
1076 };
1077 quote!(
1078 /// Add this expectation to a
1079 /// [`Sequence`](../../../mockall/struct.Sequence.html).
1080 #v fn in_sequence(&mut self, __mockall_seq: &mut ::mockall::Sequence)
1081 -> &mut Self
1082 {
1083 self.common.in_sequence(__mockall_seq);
1084 self
1085 }
1086
1087 fn is_done(&self) -> bool {
1088 self.common.is_done()
1089 }
1090
1091 /// Validate this expectation's matcher.
1092 #[allow(clippy::ptr_arg)]
1093 fn matches #lg (&self, #(#argnames: &#predty, )*) -> bool {
1094 self.common.matches(#(#argnames, )*)
1095 }
1096
1097 /// Forbid this expectation from ever being called.
1098 #v fn never(&mut self) -> &mut Self {
1099 self.common.never();
1100 self
1101 }
1102
1103 /// Create a new, default, [`Expectation`](struct.Expectation.html)
1104 #v fn new() -> Self {
1105 Self::default()
1106 }
1107
1108 /// Expect this expectation to be called exactly once. Shortcut for
1109 /// [`times(1)`](#method.times).
1110 #v fn once(&mut self) -> &mut Self {
1111 self.times(1)
1112 }
1113
1114 /// Restrict the number of times that that this method may be called.
1115 ///
1116 /// The argument may be:
1117 /// * A fixed number: `.times(4)`
1118 /// * Various types of range:
1119 /// - `.times(5..10)`
1120 /// - `.times(..10)`
1121 /// - `.times(5..)`
1122 /// - `.times(5..=10)`
1123 /// - `.times(..=10)`
1124 /// * The wildcard: `.times(..)`
1125 #v fn times<MockallR>(&mut self, __mockall_r: MockallR) -> &mut Self
1126 where MockallR: Into<::mockall::TimesRange>
1127 {
1128 self.common.times(__mockall_r);
1129 self
1130 }
1131
1132 #with_method
1133
1134 /// Set a matching function for this Expectation.
1135 ///
1136 /// This is equivalent to calling [`with`](#method.with) with a
1137 /// function argument, like `with(predicate::function(f))`.
1138 #v fn withf<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
1139 where MockallF: #hrtb Fn(#(&#predty, )*)
1140 -> bool + Send + 'static
1141 {
1142 self.common.withf(__mockall_f);
1143 self
1144 }
1145
1146 /// Single-threaded version of [`withf`](#method.withf).
1147 /// Can be used when the argument type isn't `Send`.
1148 #v fn withf_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
1149 where MockallF: #hrtb Fn(#(&#predty, )*)
1150 -> bool + 'static
1151 {
1152 self.common.withf_st(__mockall_f);
1153 self
1154 }
1155 ).to_tokens(tokens);
1156 }
1157 }
1158
1159 /// Holds the moethods of the Expectations object that are common for all
1160 /// Expectation types
1161 struct CommonExpectationsMethods<'a> {
1162 f: &'a MockFunction
1163 }
1164
1165 impl<'a> ToTokens for CommonExpectationsMethods<'a> {
to_tokens(&self, tokens: &mut TokenStream)1166 fn to_tokens(&self, tokens: &mut TokenStream) {
1167 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
1168 let v = &self.f.privmod_vis;
1169 quote!(
1170 /// A collection of [`Expectation`](struct.Expectations.html)
1171 /// objects. Users will rarely if ever use this struct directly.
1172 #[doc(hidden)]
1173 #v struct Expectations #ig ( Vec<Expectation #tg>) #wc;
1174
1175 impl #ig Expectations #tg #wc {
1176 /// Verify that all current expectations are satisfied and clear
1177 /// them.
1178 #v fn checkpoint(&mut self) -> std::vec::Drain<Expectation #tg>
1179 {
1180 self.0.drain(..)
1181 }
1182
1183 /// Create a new expectation for this method.
1184 #v fn expect(&mut self) -> &mut Expectation #tg
1185 {
1186 self.0.push(Expectation::default());
1187 let __mockall_l = self.0.len();
1188 &mut self.0[__mockall_l - 1]
1189 }
1190
1191 #v fn new() -> Self {
1192 Self::default()
1193 }
1194 }
1195 impl #ig Default for Expectations #tg #wc
1196 {
1197 fn default() -> Self {
1198 Expectations(Vec::new())
1199 }
1200 }
1201 ).to_tokens(tokens);
1202 }
1203 }
1204
1205 /// The ExpectationGuard structure for static methods with no generic types
1206 struct ExpectationGuardCommonMethods<'a> {
1207 f: &'a MockFunction
1208 }
1209
1210 impl<'a> ToTokens for ExpectationGuardCommonMethods<'a> {
to_tokens(&self, tokens: &mut TokenStream)1211 fn to_tokens(&self, tokens: &mut TokenStream) {
1212 if !self.f.is_static {
1213 return;
1214 }
1215
1216 let argnames = &self.f.argnames;
1217 let argty = &self.f.argty;
1218 let (_, tg, _) = self.f.egenerics.split_for_impl();
1219 let keyid = gen_keyid(&self.f.egenerics);
1220 let expectations = if self.f.is_expectation_generic() {
1221 quote!(self.guard
1222 .store
1223 .get_mut(&::mockall::Key::new::#keyid())
1224 .unwrap()
1225 .downcast_mut::<Expectations #tg>()
1226 .unwrap())
1227 } else {
1228 quote!(self.guard)
1229 };
1230 let hrtb = self.f.hrtb();
1231 let output = &self.f.output;
1232 let predty = &self.f.predty;
1233 let with_generics_idents = (0..self.f.predty.len())
1234 .map(|i| format_ident!("MockallMatcher{i}"))
1235 .collect::<Vec<_>>();
1236 let with_generics = with_generics_idents.iter()
1237 .zip(self.f.predty.iter())
1238 .map(|(id, mt)|
1239 quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, )
1240 ).collect::<TokenStream>();
1241 let with_args = self.f.argnames.iter()
1242 .zip(with_generics_idents.iter())
1243 .map(|(argname, id)| quote!(#argname: #id, ))
1244 .collect::<TokenStream>();
1245 let v = &self.f.privmod_vis;
1246 let with_method = if self.f.concretize {
1247 quote!()
1248 } else {
1249 quote!(
1250 /// Just like
1251 /// [`Expectation::with`](struct.Expectation.html#method.with)
1252 #v fn with<#with_generics> (&mut self, #with_args)
1253 -> &mut Expectation #tg
1254 {
1255 #expectations.0[self.i].with(#(#argnames, )*)
1256 }
1257 )
1258 };
1259 quote!(
1260 /// Just like
1261 /// [`Expectation::in_sequence`](struct.Expectation.html#method.in_sequence)
1262 #v fn in_sequence(&mut self,
1263 __mockall_seq: &mut ::mockall::Sequence)
1264 -> &mut Expectation #tg
1265 {
1266 #expectations.0[self.i].in_sequence(__mockall_seq)
1267 }
1268
1269 /// Just like
1270 /// [`Expectation::never`](struct.Expectation.html#method.never)
1271 #v fn never(&mut self) -> &mut Expectation #tg {
1272 #expectations.0[self.i].never()
1273 }
1274
1275 /// Just like
1276 /// [`Expectation::once`](struct.Expectation.html#method.once)
1277 #v fn once(&mut self) -> &mut Expectation #tg {
1278 #expectations.0[self.i].once()
1279 }
1280
1281 /// Just like
1282 /// [`Expectation::return_const`](struct.Expectation.html#method.return_const)
1283 #v fn return_const<MockallOutput>
1284 (&mut self, __mockall_c: MockallOutput)
1285 -> &mut Expectation #tg
1286 where MockallOutput: Clone + Into<#output> + Send + 'static
1287 {
1288 #expectations.0[self.i].return_const(__mockall_c)
1289 }
1290
1291 /// Just like
1292 /// [`Expectation::return_const_st`](struct.Expectation.html#method.return_const_st)
1293 #v fn return_const_st<MockallOutput>
1294 (&mut self, __mockall_c: MockallOutput)
1295 -> &mut Expectation #tg
1296 where MockallOutput: Clone + Into<#output> + 'static
1297 {
1298 #expectations.0[self.i].return_const_st(__mockall_c)
1299 }
1300
1301 /// Just like
1302 /// [`Expectation::returning`](struct.Expectation.html#method.returning)
1303 #v fn returning<MockallF>(&mut self, __mockall_f: MockallF)
1304 -> &mut Expectation #tg
1305 where MockallF: #hrtb FnMut(#(#argty, )*)
1306 -> #output + Send + 'static
1307 {
1308 #expectations.0[self.i].returning(__mockall_f)
1309 }
1310
1311 /// Just like
1312 /// [`Expectation::return_once`](struct.Expectation.html#method.return_once)
1313 #v fn return_once<MockallF>(&mut self, __mockall_f: MockallF)
1314 -> &mut Expectation #tg
1315 where MockallF: #hrtb FnOnce(#(#argty, )*)
1316 -> #output + Send + 'static
1317 {
1318 #expectations.0[self.i].return_once(__mockall_f)
1319 }
1320
1321 /// Just like
1322 /// [`Expectation::return_once_st`](struct.Expectation.html#method.return_once_st)
1323 #v fn return_once_st<MockallF>(&mut self, __mockall_f: MockallF)
1324 -> &mut Expectation #tg
1325 where MockallF: #hrtb FnOnce(#(#argty, )*)
1326 -> #output + 'static
1327 {
1328 #expectations.0[self.i].return_once_st(__mockall_f)
1329 }
1330
1331
1332 /// Just like
1333 /// [`Expectation::returning_st`](struct.Expectation.html#method.returning_st)
1334 #v fn returning_st<MockallF>(&mut self, __mockall_f: MockallF)
1335 -> &mut Expectation #tg
1336 where MockallF: #hrtb FnMut(#(#argty, )*)
1337 -> #output + 'static
1338 {
1339 #expectations.0[self.i].returning_st(__mockall_f)
1340 }
1341
1342 /// Just like
1343 /// [`Expectation::times`](struct.Expectation.html#method.times)
1344 #v fn times<MockallR>(&mut self, __mockall_r: MockallR)
1345 -> &mut Expectation #tg
1346 where MockallR: Into<::mockall::TimesRange>
1347 {
1348 #expectations.0[self.i].times(__mockall_r)
1349 }
1350
1351 #with_method
1352
1353 /// Just like
1354 /// [`Expectation::withf`](struct.Expectation.html#method.withf)
1355 #v fn withf<MockallF>(&mut self, __mockall_f: MockallF)
1356 -> &mut Expectation #tg
1357 where MockallF: #hrtb Fn(#(&#predty, )*)
1358 -> bool + Send + 'static
1359 {
1360 #expectations.0[self.i].withf(__mockall_f)
1361 }
1362
1363 /// Just like
1364 /// [`Expectation::withf_st`](struct.Expectation.html#method.withf_st)
1365 #v fn withf_st<MockallF>(&mut self, __mockall_f: MockallF)
1366 -> &mut Expectation #tg
1367 where MockallF: #hrtb Fn(#(&#predty, )*)
1368 -> bool + 'static
1369 {
1370 #expectations.0[self.i].withf_st(__mockall_f)
1371 }
1372 ).to_tokens(tokens);
1373 }
1374 }
1375
1376 /// The ExpectationGuard structure for static methods with no generic types
1377 struct ConcreteExpectationGuard<'a> {
1378 f: &'a MockFunction
1379 }
1380
1381 impl<'a> ToTokens for ConcreteExpectationGuard<'a> {
to_tokens(&self, tokens: &mut TokenStream)1382 fn to_tokens(&self, tokens: &mut TokenStream) {
1383 if !self.f.is_static {
1384 return;
1385 }
1386
1387 let common_methods = ExpectationGuardCommonMethods{f: self.f};
1388 let (_, tg, _) = self.f.egenerics.split_for_impl();
1389 let ltdef = LifetimeParam::new(
1390 Lifetime::new("'__mockall_lt", Span::call_site())
1391 );
1392 let mut e_generics = self.f.egenerics.clone();
1393 e_generics.lt_token.get_or_insert(<Token![<]>::default());
1394 e_generics.params.push(GenericParam::Lifetime(ltdef));
1395 e_generics.gt_token.get_or_insert(<Token![>]>::default());
1396 let (e_ig, e_tg, e_wc) = e_generics.split_for_impl();
1397 let (ei_ig, _, _) = e_generics.split_for_impl();
1398 let v = &self.f.privmod_vis;
1399 quote!(
1400 ::mockall::lazy_static! {
1401 #[doc(hidden)]
1402 #v static ref EXPECTATIONS:
1403 ::std::sync::Mutex<Expectations #tg> =
1404 ::std::sync::Mutex::new(Expectations::new());
1405 }
1406 /// Like an [`&Expectation`](struct.Expectation.html) but
1407 /// protected by a Mutex guard. Useful for mocking static
1408 /// methods. Forwards accesses to an `Expectation` object.
1409 // We must return the MutexGuard to the caller so he can
1410 // configure the expectation. But we can't bundle both the
1411 // guard and the &Expectation into the same structure; the
1412 // borrow checker won't let us. Instead we'll record the
1413 // expectation's position within the Expectations vector so we
1414 // can proxy its methods.
1415 //
1416 // ExpectationGuard is only defined for expectations that return
1417 // 'static return types.
1418 #v struct ExpectationGuard #e_ig #e_wc {
1419 guard: MutexGuard<'__mockall_lt, Expectations #tg>,
1420 i: usize
1421 }
1422
1423 #[allow(clippy::unused_unit)]
1424 impl #ei_ig ExpectationGuard #e_tg #e_wc
1425 {
1426 // Should only be called from the mockall_derive generated
1427 // code
1428 #[doc(hidden)]
1429 #v fn new(mut __mockall_guard: MutexGuard<'__mockall_lt, Expectations #tg>)
1430 -> Self
1431 {
1432 __mockall_guard.expect(); // Drop the &Expectation
1433 let __mockall_i = __mockall_guard.0.len() - 1;
1434 ExpectationGuard{guard: __mockall_guard, i: __mockall_i}
1435 }
1436
1437 #common_methods
1438 }
1439 ).to_tokens(tokens);
1440 }
1441 }
1442
1443 /// The ExpectationGuard structure for static methods with generic types
1444 struct GenericExpectationGuard<'a> {
1445 f: &'a MockFunction
1446 }
1447
1448 impl<'a> ToTokens for GenericExpectationGuard<'a> {
to_tokens(&self, tokens: &mut TokenStream)1449 fn to_tokens(&self, tokens: &mut TokenStream) {
1450 if !self.f.is_static {
1451 return;
1452 }
1453
1454 let common_methods = ExpectationGuardCommonMethods{f: self.f};
1455 let (_, tg, _) = self.f.egenerics.split_for_impl();
1456 let keyid = gen_keyid(&self.f.egenerics);
1457 let ltdef = LifetimeParam::new(
1458 Lifetime::new("'__mockall_lt", Span::call_site())
1459 );
1460 let mut egenerics = self.f.egenerics.clone();
1461 egenerics.lt_token.get_or_insert(<Token![<]>::default());
1462 egenerics.params.push(GenericParam::Lifetime(ltdef));
1463 egenerics.gt_token.get_or_insert(<Token![>]>::default());
1464 let (e_ig, e_tg, e_wc) = egenerics.split_for_impl();
1465 let fn_params = &self.f.fn_params;
1466 let tbf = tg.as_turbofish();
1467 let v = &self.f.privmod_vis;
1468 quote!(
1469 ::mockall::lazy_static! {
1470 #v static ref EXPECTATIONS:
1471 ::std::sync::Mutex<GenericExpectations> =
1472 ::std::sync::Mutex::new(GenericExpectations::new());
1473 }
1474 /// Like an [`&Expectation`](struct.Expectation.html) but
1475 /// protected by a Mutex guard. Useful for mocking static
1476 /// methods. Forwards accesses to an `Expectation` object.
1477 #v struct ExpectationGuard #e_ig #e_wc{
1478 guard: MutexGuard<'__mockall_lt, GenericExpectations>,
1479 i: usize,
1480 _phantom: ::std::marker::PhantomData<(#(#fn_params,)*)>,
1481 }
1482
1483 #[allow(clippy::unused_unit)]
1484 impl #e_ig ExpectationGuard #e_tg #e_wc
1485 {
1486 // Should only be called from the mockall_derive generated
1487 // code
1488 #[doc(hidden)]
1489 #v fn new(mut __mockall_guard: MutexGuard<'__mockall_lt, GenericExpectations>)
1490 -> Self
1491 {
1492 let __mockall_ee: &mut Expectations #tg =
1493 __mockall_guard.store.entry(
1494 ::mockall::Key::new::#keyid()
1495 ).or_insert_with(||
1496 Box::new(Expectations #tbf ::new()))
1497 .downcast_mut()
1498 .unwrap();
1499 __mockall_ee.expect(); // Drop the &Expectation
1500 let __mockall_i = __mockall_ee.0.len() - 1;
1501 ExpectationGuard{guard: __mockall_guard, i: __mockall_i,
1502 _phantom: ::std::marker::PhantomData}
1503 }
1504
1505 #common_methods
1506 }
1507 ).to_tokens(tokens);
1508 }
1509 }
1510
1511 /// Generates Context, which manages the context for expectations of static
1512 /// methods.
1513 struct Context<'a> {
1514 f: &'a MockFunction
1515 }
1516
1517 impl<'a> ToTokens for Context<'a> {
to_tokens(&self, tokens: &mut TokenStream)1518 fn to_tokens(&self, tokens: &mut TokenStream) {
1519 if !self.f.is_static {
1520 return;
1521 }
1522
1523 let ltdef = LifetimeParam::new(
1524 Lifetime::new("'__mockall_lt", Span::call_site())
1525 );
1526 let mut egenerics = self.f.egenerics.clone();
1527 egenerics.lt_token.get_or_insert(<Token![<]>::default());
1528 egenerics.params.push(GenericParam::Lifetime(ltdef));
1529 egenerics.gt_token.get_or_insert(<Token![>]>::default());
1530 let (_, e_tg, _) = egenerics.split_for_impl();
1531 let (ty_ig, ty_tg, ty_wc) = self.f.type_generics.split_for_impl();
1532 let mut meth_generics = self.f.call_generics.clone();
1533 let ltdef = LifetimeParam::new(
1534 Lifetime::new("'__mockall_lt", Span::call_site())
1535 );
1536 meth_generics.params.push(GenericParam::Lifetime(ltdef));
1537 let (meth_ig, _meth_tg, meth_wc) = meth_generics.split_for_impl();
1538 let ctx_fn_params = self.f.struct_generics.type_params()
1539 .map(|tp| tp.ident.clone())
1540 .collect::<Punctuated::<Ident, Token![,]>>();
1541 let v = &self.f.privmod_vis;
1542
1543 #[cfg(not(feature = "nightly_derive"))]
1544 let must_use = quote!(#[must_use =
1545 "Must set return value when not using the \"nightly\" feature"
1546 ]);
1547 #[cfg(feature = "nightly_derive")]
1548 let must_use = quote!();
1549
1550 quote!(
1551 /// Manages the context for expectations of static methods.
1552 ///
1553 /// Expectations on this method will be validated and cleared when
1554 /// the `Context` object drops. The `Context` object does *not*
1555 /// provide any form of synchronization, so multiple tests that set
1556 /// expectations on the same static method must provide their own.
1557 #[must_use = "Context only serves to create expectations" ]
1558 #v struct Context #ty_ig #ty_wc {
1559 // Prevent "unused type parameter" errors
1560 // Surprisingly, PhantomData<Fn(generics)> is Send even if
1561 // generics are not, unlike PhantomData<generics>
1562 _phantom: ::std::marker::PhantomData<
1563 Box<dyn Fn(#ctx_fn_params) + Send>
1564 >
1565 }
1566 impl #ty_ig Context #ty_tg #ty_wc {
1567 /// Verify that all current expectations for this method are
1568 /// satisfied and clear them.
1569 #v fn checkpoint(&self) {
1570 Self::do_checkpoint()
1571 }
1572 #[doc(hidden)]
1573 #v fn do_checkpoint() {
1574 let __mockall_timeses = EXPECTATIONS
1575 .lock()
1576 .unwrap()
1577 .checkpoint()
1578 .collect::<Vec<_>>();
1579 }
1580
1581 /// Create a new expectation for this method.
1582 #must_use
1583 #v fn expect #meth_ig ( &self,) -> ExpectationGuard #e_tg
1584 #meth_wc
1585 {
1586 ExpectationGuard::new(EXPECTATIONS.lock().unwrap())
1587 }
1588 }
1589 impl #ty_ig Default for Context #ty_tg #ty_wc {
1590 fn default() -> Self {
1591 Context {_phantom: std::marker::PhantomData}
1592 }
1593 }
1594 impl #ty_ig Drop for Context #ty_tg #ty_wc {
1595 fn drop(&mut self) {
1596 if ::std::thread::panicking() {
1597 // Drain all expectations so other tests can run with a
1598 // blank slate. But ignore errors so we don't
1599 // double-panic.
1600 let _ = EXPECTATIONS
1601 .lock()
1602 .map(|mut g| g.checkpoint().collect::<Vec<_>>());
1603 } else {
1604 // Verify expectations are satisfied
1605 Self::do_checkpoint();
1606 }
1607 }
1608 }
1609 ).to_tokens(tokens);
1610 }
1611 }
1612
1613 struct Matcher<'a> {
1614 f: &'a MockFunction
1615 }
1616
1617 impl<'a> ToTokens for Matcher<'a> {
to_tokens(&self, tokens: &mut TokenStream)1618 fn to_tokens(&self, tokens: &mut TokenStream) {
1619 let (ig, tg, wc) = self.f.cgenerics.split_for_impl();
1620 let argnames = &self.f.argnames;
1621 let braces = argnames.iter()
1622 .fold(String::new(), |mut acc, _argname| {
1623 if acc.is_empty() {
1624 acc.push_str("{}");
1625 } else {
1626 acc.push_str(", {}");
1627 }
1628 acc
1629 });
1630 let fn_params = &self.f.fn_params;
1631 let hrtb = self.f.hrtb();
1632 let indices = (0..argnames.len())
1633 .map(|i| {
1634 syn::Index::from(i)
1635 }).collect::<Vec<_>>();
1636 let lg = lifetimes_to_generics(&self.f.alifetimes);
1637 let pred_matches = argnames.iter().enumerate()
1638 .map(|(i, argname)| {
1639 let idx = syn::Index::from(i);
1640 quote!(__mockall_pred.#idx.eval(#argname),)
1641 }).collect::<TokenStream>();
1642 let preds = if self.f.concretize {
1643 quote!(())
1644 } else {
1645 self.f.predty.iter()
1646 .map(|t| quote!(Box<dyn #hrtb ::mockall::Predicate<#t> + Send>,))
1647 .collect::<TokenStream>()
1648 };
1649 let predty = &self.f.predty;
1650 let refpredty = &self.f.refpredty;
1651 let predmatches_body = if self.f.concretize {
1652 quote!()
1653 } else {
1654 quote!(Matcher::Pred(__mockall_pred) => [#pred_matches].iter().all(|__mockall_x| *__mockall_x),)
1655 };
1656 let preddbg_body = if self.f.concretize {
1657 quote!()
1658 } else {
1659 quote!(
1660 Matcher::Pred(__mockall_p) => {
1661 write!(__mockall_fmt, #braces,
1662 #(__mockall_p.#indices,)*)
1663 }
1664 )
1665 };
1666 quote!(
1667 enum Matcher #ig #wc {
1668 Always,
1669 Func(Box<dyn #hrtb Fn(#( #refpredty, )*) -> bool + Send>),
1670 // Version of Matcher::Func for closures that aren't Send
1671 FuncSt(::mockall::Fragile<Box<dyn #hrtb Fn(#( #refpredty, )*) -> bool>>),
1672 Pred(Box<(#preds)>),
1673 // Prevent "unused type parameter" errors
1674 // Surprisingly, PhantomData<Fn(generics)> is Send even if
1675 // generics are not, unlike PhantomData<generics>
1676 _Phantom(Box<dyn Fn(#(#fn_params,)*) + Send>)
1677 }
1678 impl #ig Matcher #tg #wc {
1679 #[allow(clippy::ptr_arg)]
1680 fn matches #lg (&self, #( #argnames: &#predty, )*) -> bool {
1681 match self {
1682 Matcher::Always => true,
1683 Matcher::Func(__mockall_f) =>
1684 __mockall_f(#(#argnames, )*),
1685 Matcher::FuncSt(__mockall_f) =>
1686 (__mockall_f.get())(#(#argnames, )*),
1687 #predmatches_body
1688 _ => unreachable!()
1689 }
1690 }
1691 }
1692
1693 impl #ig Default for Matcher #tg #wc {
1694 #[allow(unused_variables)]
1695 fn default() -> Self {
1696 Matcher::Always
1697 }
1698 }
1699
1700 impl #ig ::std::fmt::Display for Matcher #tg #wc {
1701 fn fmt(&self, __mockall_fmt: &mut ::std::fmt::Formatter<'_>)
1702 -> ::std::fmt::Result
1703 {
1704 match self {
1705 Matcher::Always => write!(__mockall_fmt, "<anything>"),
1706 Matcher::Func(_) => write!(__mockall_fmt, "<function>"),
1707 Matcher::FuncSt(_) => write!(__mockall_fmt, "<single threaded function>"),
1708 #preddbg_body
1709 _ => unreachable!(),
1710 }
1711 }
1712 }
1713 ).to_tokens(tokens);
1714 }
1715 }
1716
1717 struct RefRfunc<'a> {
1718 f: &'a MockFunction
1719 }
1720
1721 impl<'a> ToTokens for RefRfunc<'a> {
to_tokens(&self, tokens: &mut TokenStream)1722 fn to_tokens(&self, tokens: &mut TokenStream) {
1723 let fn_params = &self.f.fn_params;
1724 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
1725 let lg = lifetimes_to_generics(&self.f.alifetimes);
1726 let owned_output = &self.f.owned_output;
1727
1728 #[cfg(not(feature = "nightly_derive"))]
1729 let default_err_msg =
1730 "Returning default values requires the \"nightly\" feature";
1731 #[cfg(feature = "nightly_derive")]
1732 let default_err_msg =
1733 "Can only return default values for types that impl std::Default";
1734
1735 quote!(
1736 enum Rfunc #ig #wc {
1737 Default(Option<#owned_output>),
1738 Const(#owned_output),
1739 // Prevent "unused type parameter" errors Surprisingly,
1740 // PhantomData<Fn(generics)> is Send even if generics are not,
1741 // unlike PhantomData<generics>
1742 _Phantom(Mutex<Box<dyn Fn(#(#fn_params,)*) + Send>>)
1743 }
1744
1745 impl #ig Rfunc #tg #wc {
1746 fn call #lg (&self)
1747 -> std::result::Result<&#owned_output, &'static str>
1748 {
1749 match self {
1750 Rfunc::Default(Some(ref __mockall_o)) => {
1751 ::std::result::Result::Ok(__mockall_o)
1752 },
1753 Rfunc::Default(None) => {
1754 Err(#default_err_msg)
1755 },
1756 Rfunc::Const(ref __mockall_o) => {
1757 ::std::result::Result::Ok(__mockall_o)
1758 },
1759 Rfunc::_Phantom(_) => unreachable!()
1760 }
1761 }
1762 }
1763
1764 impl #ig std::default::Default for Rfunc #tg #wc
1765 {
1766 fn default() -> Self {
1767 use ::mockall::ReturnDefault;
1768 Rfunc::Default(::mockall::DefaultReturner::<#owned_output>
1769 ::maybe_return_default())
1770 }
1771 }
1772 ).to_tokens(tokens);
1773 }
1774 }
1775
1776 struct RefMutRfunc<'a> {
1777 f: &'a MockFunction
1778 }
1779
1780 impl<'a> ToTokens for RefMutRfunc<'a> {
to_tokens(&self, tokens: &mut TokenStream)1781 fn to_tokens(&self, tokens: &mut TokenStream) {
1782 let argnames = &self.f.argnames;
1783 let argty = &self.f.argty;
1784 let fn_params = &self.f.fn_params;
1785 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
1786 let lg = lifetimes_to_generics(&self.f.alifetimes);
1787 let owned_output = &self.f.owned_output;
1788 let output = &self.f.output;
1789
1790 #[cfg(not(feature = "nightly_derive"))]
1791 let default_err_msg =
1792 "Returning default values requires the \"nightly\" feature";
1793 #[cfg(feature = "nightly_derive")]
1794 let default_err_msg =
1795 "Can only return default values for types that impl std::Default";
1796
1797 quote!(
1798 #[allow(clippy::unused_unit)]
1799 enum Rfunc #ig #wc {
1800 Default(Option<#owned_output>),
1801 Mut((Box<dyn FnMut(#(#argty, )*) -> #owned_output + Send + Sync>),
1802 Option<#owned_output>),
1803 // Version of Rfunc::Mut for closures that aren't Send
1804 MutSt((::mockall::Fragile<
1805 Box<dyn FnMut(#(#argty, )*) -> #owned_output >>
1806 ), Option<#owned_output>
1807 ),
1808 Var(#owned_output),
1809 // Prevent "unused type parameter" errors Surprisingly,
1810 // PhantomData<Fn(generics)> is Send even if generics are not,
1811 // unlike PhantomData<generics>
1812 _Phantom(Mutex<Box<dyn Fn(#(#fn_params,)*) + Send>>)
1813 }
1814
1815 impl #ig Rfunc #tg #wc {
1816 fn call_mut #lg (&mut self, #(#argnames: #argty, )*)
1817 -> std::result::Result<#output, &'static str>
1818 {
1819 match self {
1820 Rfunc::Default(Some(ref mut __mockall_o)) => {
1821 ::std::result::Result::Ok(__mockall_o)
1822 },
1823 Rfunc::Default(None) => {
1824 Err(#default_err_msg)
1825 },
1826 Rfunc::Mut(ref mut __mockall_f, ref mut __mockall_o) =>
1827 {
1828 *__mockall_o = Some(__mockall_f(#(#argnames, )*));
1829 if let Some(ref mut __mockall_o2) = __mockall_o {
1830 ::std::result::Result::Ok(__mockall_o2)
1831 } else {
1832 unreachable!()
1833 }
1834 },
1835 Rfunc::MutSt(ref mut __mockall_f, ref mut __mockall_o)=>
1836 {
1837 *__mockall_o = Some((__mockall_f.get_mut())(
1838 #(#argnames, )*)
1839 );
1840 if let Some(ref mut __mockall_o2) = __mockall_o {
1841 ::std::result::Result::Ok(__mockall_o2)
1842 } else {
1843 unreachable!()
1844 }
1845 },
1846 Rfunc::Var(ref mut __mockall_o) => {
1847 ::std::result::Result::Ok(__mockall_o)
1848 },
1849 Rfunc::_Phantom(_) => unreachable!()
1850 }
1851 }
1852 }
1853
1854 impl #ig std::default::Default for Rfunc #tg #wc
1855 {
1856 fn default() -> Self {
1857 use ::mockall::ReturnDefault;
1858 Rfunc::Default(::mockall::DefaultReturner::<#owned_output>
1859 ::maybe_return_default())
1860 }
1861 }
1862 ).to_tokens(tokens);
1863 }
1864 }
1865
1866 struct StaticRfunc<'a> {
1867 f: &'a MockFunction
1868 }
1869
1870 impl<'a> ToTokens for StaticRfunc<'a> {
to_tokens(&self, tokens: &mut TokenStream)1871 fn to_tokens(&self, tokens: &mut TokenStream) {
1872 let argnames = &self.f.argnames;
1873 let argty = &self.f.argty;
1874 let fn_params = &self.f.fn_params;
1875 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
1876 let hrtb = self.f.hrtb();
1877 let lg = lifetimes_to_generics(&self.f.alifetimes);
1878 let output = &self.f.output;
1879 quote!(
1880 #[allow(clippy::unused_unit)]
1881 enum Rfunc #ig #wc {
1882 Default,
1883 // Indicates that a `return_once` expectation has already
1884 // returned
1885 Expired,
1886 Mut(Box<dyn #hrtb FnMut(#(#argty, )*) -> #output + Send>),
1887 // Version of Rfunc::Mut for closures that aren't Send
1888 MutSt(::mockall::Fragile<
1889 Box<dyn #hrtb FnMut(#(#argty, )*) -> #output >>
1890 ),
1891 Once(Box<dyn #hrtb FnOnce(#(#argty, )*) -> #output + Send>),
1892 // Version of Rfunc::Once for closure that aren't Send
1893 OnceSt(::mockall::Fragile<
1894 Box<dyn #hrtb FnOnce(#(#argty, )*) -> #output>>
1895 ),
1896 // Prevent "unused type parameter" errors Surprisingly,
1897 // PhantomData<Fn(generics)> is Send even if generics are not,
1898 // unlike PhantomData<generics>
1899 _Phantom(Box<dyn Fn(#(#fn_params,)*) + Send>)
1900 }
1901
1902 impl #ig Rfunc #tg #wc {
1903 fn call_mut #lg (&mut self, #( #argnames: #argty, )* )
1904 -> std::result::Result<#output, &'static str>
1905 {
1906 match self {
1907 Rfunc::Default => {
1908 use ::mockall::ReturnDefault;
1909 ::mockall::DefaultReturner::<#output>
1910 ::return_default()
1911 },
1912 Rfunc::Expired => {
1913 Err("called twice, but it returns by move")
1914 },
1915 Rfunc::Mut(__mockall_f) => {
1916 ::std::result::Result::Ok(__mockall_f( #(#argnames, )* ))
1917 },
1918 Rfunc::MutSt(__mockall_f) => {
1919 ::std::result::Result::Ok((__mockall_f.get_mut())(#(#argnames,)*))
1920 },
1921 Rfunc::Once(_) => {
1922 if let Rfunc::Once(mut __mockall_f) =
1923 mem::replace(self, Rfunc::Expired) {
1924 ::std::result::Result::Ok(__mockall_f( #(#argnames, )* ))
1925 } else {
1926 unreachable!()
1927 }
1928 },
1929 Rfunc::OnceSt(_) => {
1930 if let Rfunc::OnceSt(mut __mockall_f) =
1931 mem::replace(self, Rfunc::Expired) {
1932 ::std::result::Result::Ok((__mockall_f.into_inner())(#(#argnames,)*))
1933 } else {
1934 unreachable!()
1935 }
1936 },
1937 Rfunc::_Phantom(_) => unreachable!()
1938 }
1939 }
1940 }
1941
1942 impl #ig std::default::Default for Rfunc #tg #wc
1943 {
1944 fn default() -> Self {
1945 Rfunc::Default
1946 }
1947 }
1948 ).to_tokens(tokens);
1949 }
1950 }
1951
1952 /// An expectation type for functions that take a &self and return a reference
1953 struct RefExpectation<'a> {
1954 f: &'a MockFunction
1955 }
1956
1957 impl<'a> ToTokens for RefExpectation<'a> {
to_tokens(&self, tokens: &mut TokenStream)1958 fn to_tokens(&self, tokens: &mut TokenStream) {
1959 let argnames = &self.f.argnames;
1960 let argty = &self.f.argty;
1961 let common_methods = CommonExpectationMethods{f: self.f};
1962 let desc = self.f.desc();
1963 let funcname = self.f.funcname();
1964 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
1965
1966 let (_, common_tg, _) = self.f.cgenerics.split_for_impl();
1967 let lg = lifetimes_to_generics(&self.f.alifetimes);
1968 let output = &self.f.output;
1969 let owned_output = &self.f.owned_output;
1970 let v = &self.f.privmod_vis;
1971 quote!(
1972 /// Expectation type for methods taking a `&self` argument and
1973 /// returning immutable references. This is the type returned by
1974 /// the `expect_*` methods.
1975 #v struct Expectation #ig #wc {
1976 common: Common #common_tg,
1977 rfunc: Rfunc #tg,
1978 }
1979
1980 #[allow(clippy::unused_unit)]
1981 impl #ig Expectation #tg #wc {
1982 /// Call this [`Expectation`] as if it were the real method.
1983 #v fn call #lg (&self, #(#argnames: #argty, )*) -> #output
1984 {
1985 use ::mockall::{ViaDebug, ViaNothing};
1986 self.common.call(&#desc);
1987 self.rfunc.call().unwrap_or_else(|m| {
1988 let desc = std::format!(
1989 "{}", self.common.matcher.lock().unwrap());
1990 panic!("{}: Expectation({}) {}", #funcname, desc,
1991 m);
1992 })
1993 }
1994
1995 /// Return a reference to a constant value from the `Expectation`
1996 #v fn return_const(&mut self, __mockall_o: #owned_output)
1997 -> &mut Self
1998 {
1999 self.rfunc = Rfunc::Const(__mockall_o);
2000 self
2001 }
2002
2003 #common_methods
2004 }
2005 impl #ig Default for Expectation #tg #wc
2006 {
2007 fn default() -> Self {
2008 Expectation {
2009 common: Common::default(),
2010 rfunc: Rfunc::default()
2011 }
2012 }
2013 }
2014 ).to_tokens(tokens);
2015 }
2016 }
2017
2018 /// For methods that take &mut self and return a reference
2019 struct RefMutExpectation<'a> {
2020 f: &'a MockFunction
2021 }
2022
2023 impl<'a> ToTokens for RefMutExpectation<'a> {
to_tokens(&self, tokens: &mut TokenStream)2024 fn to_tokens(&self, tokens: &mut TokenStream) {
2025 let common_methods = CommonExpectationMethods{f: self.f};
2026 let argnames = &self.f.argnames;
2027 let argty = &self.f.argty;
2028 let desc = self.f.desc();
2029 let funcname = self.f.funcname();
2030 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
2031 let (_, common_tg, _) = self.f.cgenerics.split_for_impl();
2032 let lg = lifetimes_to_generics(&self.f.alifetimes);
2033 let owned_output = &self.f.owned_output;
2034 let v = &self.f.privmod_vis;
2035 quote!(
2036 /// Expectation type for methods taking a `&mut self` argument and
2037 /// returning references. This is the type returned by the
2038 /// `expect_*` methods.
2039 #v struct Expectation #ig #wc {
2040 common: Common #common_tg,
2041 rfunc: Rfunc #tg
2042 }
2043
2044 #[allow(clippy::unused_unit)]
2045 impl #ig Expectation #tg #wc {
2046 /// Simulating calling the real method for this expectation
2047 #v fn call_mut #lg (&mut self, #(#argnames: #argty, )*)
2048 -> &mut #owned_output
2049 {
2050 use ::mockall::{ViaDebug, ViaNothing};
2051 self.common.call(&#desc);
2052 let desc = std::format!(
2053 "{}", self.common.matcher.lock().unwrap());
2054 self.rfunc.call_mut(#(#argnames, )*).unwrap_or_else(|m| {
2055 panic!("{}: Expectation({}) {}", #funcname, desc,
2056 m);
2057 })
2058 }
2059
2060 /// Convenience method that can be used to supply a return value
2061 /// for a `Expectation`. The value will be returned by mutable
2062 /// reference.
2063 #v fn return_var(&mut self, __mockall_o: #owned_output) -> &mut Self
2064 {
2065 self.rfunc = Rfunc::Var(__mockall_o);
2066 self
2067 }
2068
2069 /// Supply a closure that the `Expectation` will use to create its
2070 /// return value. The return value will be returned by mutable
2071 /// reference.
2072 #v fn returning<MockallF>(&mut self, __mockall_f: MockallF)
2073 -> &mut Self
2074 where MockallF: FnMut(#(#argty, )*) -> #owned_output + Send + Sync + 'static
2075 {
2076 self.rfunc = Rfunc::Mut(Box::new(__mockall_f), None);
2077 self
2078 }
2079
2080 /// Single-threaded version of [`returning`](#method.returning).
2081 /// Can be used when the argument or return type isn't `Send`.
2082 #v fn returning_st<MockallF>(&mut self, __mockall_f: MockallF)
2083 -> &mut Self
2084 where MockallF: FnMut(#(#argty, )*) -> #owned_output + 'static
2085 {
2086 self.rfunc = Rfunc::MutSt(
2087 ::mockall::Fragile::new(Box::new(__mockall_f)), None);
2088 self
2089 }
2090
2091 #common_methods
2092 }
2093 impl #ig Default for Expectation #tg #wc
2094 {
2095 fn default() -> Self {
2096 Expectation {
2097 common: Common::default(),
2098 rfunc: Rfunc::default()
2099 }
2100 }
2101 }
2102 ).to_tokens(tokens);
2103 }
2104 }
2105
2106 /// An expectation type for functions return a `'static` value
2107 struct StaticExpectation<'a> {
2108 f: &'a MockFunction
2109 }
2110
2111 impl<'a> ToTokens for StaticExpectation<'a> {
to_tokens(&self, tokens: &mut TokenStream)2112 fn to_tokens(&self, tokens: &mut TokenStream) {
2113 let common_methods = CommonExpectationMethods{f: self.f};
2114 let argnames = &self.f.argnames;
2115 let argty = &self.f.argty;
2116 let desc = self.f.desc();
2117 let hrtb = self.f.hrtb();
2118 let funcname = self.f.funcname();
2119 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
2120 let (_, common_tg, _) = self.f.cgenerics.split_for_impl();
2121 let lg = lifetimes_to_generics(&self.f.alifetimes);
2122 let output = &self.f.output;
2123 let v = &self.f.privmod_vis;
2124
2125 quote!(
2126 /// Expectation type for methods that return a `'static` type.
2127 /// This is the type returned by the `expect_*` methods.
2128 #v struct Expectation #ig #wc {
2129 common: Common #common_tg,
2130 rfunc: Mutex<Rfunc #tg>,
2131 }
2132
2133 #[allow(clippy::unused_unit)]
2134 impl #ig Expectation #tg #wc {
2135 /// Call this [`Expectation`] as if it were the real method.
2136 #[doc(hidden)]
2137 #v fn call #lg (&self, #(#argnames: #argty, )* ) -> #output
2138 {
2139 use ::mockall::{ViaDebug, ViaNothing};
2140 self.common.call(&#desc);
2141 self.rfunc.lock().unwrap().call_mut(#(#argnames, )*)
2142 .unwrap_or_else(|message| {
2143 let desc = std::format!(
2144 "{}", self.common.matcher.lock().unwrap());
2145 panic!("{}: Expectation({}) {}", #funcname, desc,
2146 message);
2147 })
2148 }
2149
2150 /// Return a constant value from the `Expectation`
2151 ///
2152 /// The output type must be `Clone`. The compiler can't always
2153 /// infer the proper type to use with this method; you will
2154 /// usually need to specify it explicitly. i.e.
2155 /// `return_const(42i32)` instead of `return_const(42)`.
2156 // We must use Into<#output> instead of #output because where
2157 // clauses don't accept equality constraints.
2158 // https://github.com/rust-lang/rust/issues/20041
2159 #[allow(unused_variables)]
2160 #v fn return_const<MockallOutput>(&mut self,
2161 __mockall_c: MockallOutput)
2162 -> &mut Self
2163 where MockallOutput: Clone + Into<#output> + Send + 'static
2164 {
2165 self.returning(move |#(#argnames, )*| __mockall_c.clone().into())
2166 }
2167
2168 /// Single-threaded version of
2169 /// [`return_const`](#method.return_const). This is useful for
2170 /// return types that are not `Send`.
2171 ///
2172 /// The output type must be `Clone`. The compiler can't always
2173 /// infer the proper type to use with this method; you will
2174 /// usually need to specify it explicitly. i.e.
2175 /// `return_const(42i32)` instead of `return_const(42)`.
2176 ///
2177 /// It is a runtime error to call the mock method from a
2178 /// different thread than the one that originally called this
2179 /// method.
2180 // We must use Into<#output> instead of #output because where
2181 // clauses don't accept equality constraints.
2182 // https://github.com/rust-lang/rust/issues/20041
2183 #[allow(unused_variables)]
2184 #v fn return_const_st<MockallOutput>(&mut self,
2185 __mockall_c: MockallOutput)
2186 -> &mut Self
2187 where MockallOutput: Clone + Into<#output> + 'static
2188 {
2189 self.returning_st(move |#(#argnames, )*| __mockall_c.clone().into())
2190 }
2191
2192 /// Supply an `FnOnce` closure that will provide the return
2193 /// value for this Expectation. This is useful for return types
2194 /// that aren't `Clone`. It will be an error to call this
2195 /// method multiple times.
2196 #v fn return_once<MockallF>(&mut self, __mockall_f: MockallF)
2197 -> &mut Self
2198 where MockallF: #hrtb FnOnce(#(#argty, )*)
2199 -> #output + Send + 'static
2200 {
2201 {
2202 let mut __mockall_guard = self.rfunc.lock().unwrap();
2203 *__mockall_guard.deref_mut() =
2204 Rfunc::Once(Box::new(__mockall_f));
2205 }
2206 self
2207 }
2208
2209 /// Single-threaded version of
2210 /// [`return_once`](#method.return_once). This is useful for
2211 /// return types that are neither `Send` nor `Clone`.
2212 ///
2213 /// It is a runtime error to call the mock method from a
2214 /// different thread than the one that originally called this
2215 /// method. It is also a runtime error to call the method more
2216 /// than once.
2217 #v fn return_once_st<MockallF>(&mut self, __mockall_f:
2218 MockallF) -> &mut Self
2219 where MockallF: #hrtb FnOnce(#(#argty, )*)
2220 -> #output + 'static
2221 {
2222 {
2223 let mut __mockall_guard = self.rfunc.lock().unwrap();
2224 *__mockall_guard.deref_mut() = Rfunc::OnceSt(
2225 ::mockall::Fragile::new(Box::new(__mockall_f)));
2226 }
2227 self
2228 }
2229
2230 /// Supply a closure that will provide the return value for this
2231 /// `Expectation`. The method's arguments are passed to the
2232 /// closure by value.
2233 #v fn returning<MockallF>(&mut self, __mockall_f: MockallF)
2234 -> &mut Self
2235 where MockallF: #hrtb FnMut(#(#argty, )*)
2236 -> #output + Send + 'static
2237 {
2238 {
2239 let mut __mockall_guard = self.rfunc.lock().unwrap();
2240 *__mockall_guard.deref_mut() =
2241 Rfunc::Mut(Box::new(__mockall_f));
2242 }
2243 self
2244 }
2245
2246 /// Single-threaded version of [`returning`](#method.returning).
2247 /// Can be used when the argument or return type isn't `Send`.
2248 ///
2249 /// It is a runtime error to call the mock method from a
2250 /// different thread than the one that originally called this
2251 /// method.
2252 #v fn returning_st<MockallF>(&mut self, __mockall_f: MockallF)
2253 -> &mut Self
2254 where MockallF: #hrtb FnMut(#(#argty, )*)
2255 -> #output + 'static
2256 {
2257 {
2258 let mut __mockall_guard = self.rfunc.lock().unwrap();
2259 *__mockall_guard.deref_mut() = Rfunc::MutSt(
2260 ::mockall::Fragile::new(Box::new(__mockall_f)));
2261 }
2262 self
2263 }
2264
2265 #common_methods
2266 }
2267 impl #ig Default for Expectation #tg #wc
2268 {
2269 fn default() -> Self {
2270 Expectation {
2271 common: Common::default(),
2272 rfunc: Mutex::new(Rfunc::default())
2273 }
2274 }
2275 }
2276 ).to_tokens(tokens);
2277 }
2278 }
2279
2280 /// An collection of RefExpectation's
2281 struct RefExpectations<'a> {
2282 f: &'a MockFunction
2283 }
2284
2285 impl<'a> ToTokens for RefExpectations<'a> {
to_tokens(&self, tokens: &mut TokenStream)2286 fn to_tokens(&self, tokens: &mut TokenStream) {
2287 let common_methods = CommonExpectationsMethods{f: self.f};
2288 let argnames = &self.f.argnames;
2289 let argty = &self.f.argty;
2290 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
2291 let lg = lifetimes_to_generics(&self.f.alifetimes);
2292 let output = &self.f.output;
2293 let predexprs = &self.f.predexprs;
2294 let v = &self.f.privmod_vis;
2295 quote!(
2296 #common_methods
2297 impl #ig Expectations #tg #wc {
2298 /// Simulate calling the real method. Every current expectation
2299 /// will be checked in FIFO order and the first one with
2300 /// matching arguments will be used.
2301 #v fn call #lg (&self, #(#argnames: #argty, )* )
2302 -> Option<#output>
2303 {
2304 self.0.iter()
2305 .find(|__mockall_e|
2306 __mockall_e.matches(#(#predexprs, )*) &&
2307 (!__mockall_e.is_done() || self.0.len() == 1))
2308 .map(move |__mockall_e|
2309 __mockall_e.call(#(#argnames),*)
2310 )
2311 }
2312
2313 }
2314 ).to_tokens(tokens);
2315 }
2316 }
2317
2318 /// An collection of RefMutExpectation's
2319 struct RefMutExpectations<'a> {
2320 f: &'a MockFunction
2321 }
2322
2323 impl<'a> ToTokens for RefMutExpectations<'a> {
to_tokens(&self, tokens: &mut TokenStream)2324 fn to_tokens(&self, tokens: &mut TokenStream) {
2325 let common_methods = CommonExpectationsMethods{f: self.f};
2326 let argnames = &self.f.argnames;
2327 let argty = &self.f.argty;
2328 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
2329 let lg = lifetimes_to_generics(&self.f.alifetimes);
2330 let output = &self.f.output;
2331 let predexprs = &self.f.predexprs;
2332 let v = &self.f.privmod_vis;
2333 quote!(
2334 #common_methods
2335 impl #ig Expectations #tg #wc {
2336 /// Simulate calling the real method. Every current expectation
2337 /// will be checked in FIFO order and the first one with
2338 /// matching arguments will be used.
2339 #v fn call_mut #lg (&mut self, #(#argnames: #argty, )* )
2340 -> Option<#output>
2341 {
2342 let __mockall_n = self.0.len();
2343 self.0.iter_mut()
2344 .find(|__mockall_e|
2345 __mockall_e.matches(#(#predexprs, )*) &&
2346 (!__mockall_e.is_done() || __mockall_n == 1))
2347 .map(move |__mockall_e|
2348 __mockall_e.call_mut(#(#argnames, )*)
2349 )
2350 }
2351
2352 }
2353 ).to_tokens(tokens);
2354 }
2355 }
2356
2357 /// An collection of Expectation's for methods returning static values
2358 struct StaticExpectations<'a> {
2359 f: &'a MockFunction
2360 }
2361
2362 impl<'a> ToTokens for StaticExpectations<'a> {
to_tokens(&self, tokens: &mut TokenStream)2363 fn to_tokens(&self, tokens: &mut TokenStream) {
2364 let common_methods = CommonExpectationsMethods{f: self.f};
2365 let argnames = &self.f.argnames;
2366 let argty = &self.f.argty;
2367 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
2368 let lg = lifetimes_to_generics(&self.f.alifetimes);
2369 let output = &self.f.output;
2370 let predexprs = &self.f.predexprs;
2371 let v = &self.f.privmod_vis;
2372 quote!(
2373 #common_methods
2374 impl #ig Expectations #tg #wc {
2375 /// Simulate calling the real method. Every current expectation
2376 /// will be checked in FIFO order and the first one with
2377 /// matching arguments will be used.
2378 #v fn call #lg (&self, #(#argnames: #argty, )* )
2379 -> Option<#output>
2380 {
2381 self.0.iter()
2382 .find(|__mockall_e|
2383 __mockall_e.matches(#(#predexprs, )*) &&
2384 (!__mockall_e.is_done() || self.0.len() == 1))
2385 .map(move |__mockall_e|
2386 __mockall_e.call(#(#argnames, )*)
2387 )
2388 }
2389
2390 }
2391 ).to_tokens(tokens);
2392 }
2393 }
2394
2395 struct GenericExpectations<'a> {
2396 f: &'a MockFunction
2397 }
2398
2399 impl<'a> ToTokens for GenericExpectations<'a> {
to_tokens(&self, tokens: &mut TokenStream)2400 fn to_tokens(&self, tokens: &mut TokenStream) {
2401 if ! self.f.is_expectation_generic() {
2402 return;
2403 }
2404 if ! self.f.is_static() && ! self.f.is_method_generic() {
2405 return;
2406 }
2407
2408 let ge = StaticGenericExpectations{f: self.f};
2409 let v = &self.f.privmod_vis;
2410 quote!(
2411 /// A collection of [`Expectation`](struct.Expectations.html)
2412 /// objects for a generic method. Users will rarely if ever use
2413 /// this struct directly.
2414 #[doc(hidden)]
2415 #[derive(Default)]
2416 #v struct GenericExpectations{
2417 store: std::collections::hash_map::HashMap<::mockall::Key,
2418 Box<dyn ::mockall::AnyExpectations>>
2419 }
2420 impl GenericExpectations {
2421 /// Verify that all current expectations are satisfied and clear
2422 /// them. This applies to all sets of generic parameters!
2423 #v fn checkpoint(&mut self) ->
2424 std::collections::hash_map::Drain<::mockall::Key,
2425 Box<dyn ::mockall::AnyExpectations>>
2426 {
2427 self.store.drain()
2428 }
2429
2430 #v fn new() -> Self {
2431 Self::default()
2432 }
2433 }
2434 #ge
2435 ).to_tokens(tokens);
2436 }
2437 }
2438
2439 /// Generates methods for GenericExpectations for methods returning static
2440 /// values
2441 struct StaticGenericExpectations<'a> {
2442 f: &'a MockFunction
2443 }
2444
2445 impl<'a> ToTokens for StaticGenericExpectations<'a> {
to_tokens(&self, tokens: &mut TokenStream)2446 fn to_tokens(&self, tokens: &mut TokenStream) {
2447 let argnames = &self.f.argnames;
2448 let argty = &self.f.argty;
2449 let (ig, tg, wc) = self.f.egenerics.split_for_impl();
2450 let keyid = gen_keyid(&self.f.egenerics);
2451 let mut any_wc = wc.cloned();
2452 if self.f.return_ref || self.f.return_refmut {
2453 // Add Senc + Sync, required for downcast, since Expectation
2454 // stores an Option<#owned_output>
2455 send_syncify(&mut any_wc, self.f.owned_output.clone());
2456 }
2457 let tbf = tg.as_turbofish();
2458 let output = &self.f.output;
2459 let v = &self.f.privmod_vis;
2460 let (call, get, self_, downcast) = if self.f.return_refmut {
2461 (format_ident!("call_mut"),
2462 format_ident!("get_mut"),
2463 quote!(&mut self),
2464 format_ident!("downcast_mut"))
2465 } else {
2466 (format_ident!("call"),
2467 format_ident!("get"),
2468 quote!(&self),
2469 format_ident!("downcast_ref"))
2470 };
2471 quote!(
2472 impl #ig ::mockall::AnyExpectations for Expectations #tg #any_wc {}
2473 impl GenericExpectations {
2474 /// Simulating calling the real method.
2475 #v fn #call #ig (#self_, #(#argnames: #argty, )* )
2476 -> Option<#output> #wc
2477 {
2478 self.store.#get(&::mockall::Key::new::#keyid())
2479 .map(|__mockall_e| {
2480 __mockall_e.#downcast::<Expectations #tg>()
2481 .unwrap()
2482 .#call(#(#argnames, )*)
2483 }).flatten()
2484 }
2485
2486 /// Create a new Expectation.
2487 #v fn expect #ig (&mut self) -> &mut Expectation #tg #any_wc
2488 {
2489 self.store.entry(::mockall::Key::new::#keyid())
2490 .or_insert_with(|| Box::new(Expectations #tbf::new()))
2491 .downcast_mut::<Expectations #tg>()
2492 .unwrap()
2493 .expect()
2494 }
2495 }
2496 ).to_tokens(tokens)
2497 }
2498 }
2499
2500