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