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