1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_FEED_CORE_V2_TEST_CALLBACK_RECEIVER_H_
6 #define COMPONENTS_FEED_CORE_V2_TEST_CALLBACK_RECEIVER_H_
7 
8 #include <tuple>
9 #include <utility>
10 
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/optional.h"
14 #include "base/run_loop.h"
15 
16 namespace feed {
17 namespace internal {
18 
19 template <typename T>
Nullopt()20 base::Optional<T> Nullopt() {
21   return base::nullopt;
22 }
23 
24 }  // namespace internal
25 
26 template <typename... T>
27 class CallbackReceiver {
28  public:
29   explicit CallbackReceiver(base::RunLoop* run_loop = nullptr)
run_loop_(run_loop)30       : run_loop_(run_loop) {}
Done(T...results)31   void Done(T... results) {
32     results_ = std::make_tuple(std::move(results)...);
33     if (run_loop_)
34       run_loop_->Quit();
35   }
Bind()36   base::OnceCallback<void(T...)> Bind() {
37     return base::BindOnce(&CallbackReceiver::Done, base::Unretained(this));
38   }
39 
Clear()40   void Clear() { results_ = std::make_tuple(internal::Nullopt<T>()...); }
41 
42   // Get a result by its position in the arguments to Done().
43   // Call GetResult() for the first argument or GetResult<I>().
44   template <size_t I = 0>
45   typename std::tuple_element<I, std::tuple<base::Optional<T>...>>::type&
GetResult()46   GetResult() {
47     return std::get<I>(results_);
48   }
49 
50   // Get a result by its type. Won't compile if there is more than one matching
51   // type.
52   template <class C>
GetResult()53   base::Optional<C>& GetResult() {
54     return std::get<base::Optional<C>>(results_);
55   }
56 
57  private:
58   std::tuple<base::Optional<T>...> results_;
59   base::RunLoop* run_loop_;
60 };
61 
62 }  // namespace feed
63 
64 #endif  // COMPONENTS_FEED_CORE_V2_TEST_CALLBACK_RECEIVER_H_
65