xref: /openbmc/sdbusplus/include/sdbusplus/async/client.hpp (revision f1d999b55c148b378b44100da56d5c5768ca5a49)
14a594c01SPatrick Williams #pragma once
24a594c01SPatrick Williams 
34a594c01SPatrick Williams #include <sdbusplus/async/proxy.hpp>
44a594c01SPatrick Williams 
54a594c01SPatrick Williams namespace sdbusplus::async
64a594c01SPatrick Williams {
74a594c01SPatrick Williams 
84a594c01SPatrick Williams namespace client
94a594c01SPatrick Williams {
104a594c01SPatrick Williams 
11351f8cd5SPatrick Williams namespace details
12351f8cd5SPatrick Williams {
13351f8cd5SPatrick Williams struct client_context_friend;
14351f8cd5SPatrick Williams }
15351f8cd5SPatrick Williams 
164a594c01SPatrick Williams /** An aggregation class of sdbusplus::async::proxy-based client types.
174a594c01SPatrick Williams  *
184a594c01SPatrick Williams  *  The resulting class acts as a union of all Types from the template
194a594c01SPatrick Williams  *  arguments.
204a594c01SPatrick Williams  *
214a594c01SPatrick Williams  *  Like a `proxy`, the class only becomes functional once the service and
224a594c01SPatrick Williams  *  path are populated.
234a594c01SPatrick Williams  */
24351f8cd5SPatrick Williams template <bool S, bool P, bool Preserved,
25351f8cd5SPatrick Williams           template <typename, typename> typename... Types>
264a594c01SPatrick Williams class client :
274a9e4221SPatrick Williams     public context_ref,
28351f8cd5SPatrick Williams     public Types<client<S, P, Preserved, Types...>,
29351f8cd5SPatrick Williams                  sdbusplus::async::proxy_ns::proxy<S, P, false, Preserved>>...
304a594c01SPatrick Williams {
31351f8cd5SPatrick Williams   public:
32351f8cd5SPatrick Williams     using Self = client<S, P, Preserved, Types...>;
33351f8cd5SPatrick Williams     using Proxy = sdbusplus::async::proxy_ns::proxy<S, P, false, Preserved>;
34351f8cd5SPatrick Williams     friend details::client_context_friend;
35351f8cd5SPatrick Williams 
364a594c01SPatrick Williams   private:
37351f8cd5SPatrick Williams     Proxy proxy{};
384a594c01SPatrick Williams 
394a594c01SPatrick Williams   public:
403cd1c348SPatrick Williams     constexpr client() = delete;
414a594c01SPatrick Williams     /* Delete default constructor if Service or Path have been provided. */
423cd1c348SPatrick Williams     explicit client(sdbusplus::async::context& ctx)
434a594c01SPatrick Williams         requires(S || P)
444a594c01SPatrick Williams     = delete;
454a594c01SPatrick Williams     /* Default (empty) constructor only when Service and Path are missing. */
client(sdbusplus::async::context & ctx)463cd1c348SPatrick Williams     explicit client(sdbusplus::async::context& ctx)
474a594c01SPatrick Williams         requires(!S && !P)
48351f8cd5SPatrick Williams         : context_ref(ctx), Types<Self, Proxy>(Proxy{})...
494a594c01SPatrick Williams     {}
504a594c01SPatrick Williams 
514a594c01SPatrick Williams     /* Conversion constructor for a non-empty (Service and/or Path) proxy. */
client(sdbusplus::async::context & ctx,Proxy p)52351f8cd5SPatrick Williams     explicit client(sdbusplus::async::context& ctx, Proxy p)
534a594c01SPatrick Williams         requires(S || P)
54351f8cd5SPatrick Williams         : context_ref(ctx), Types<Self, Proxy>(p)..., proxy(p)
554a594c01SPatrick Williams     {}
564a594c01SPatrick Williams 
574a594c01SPatrick Williams     /* Convert a non-Service instance to a Service instance. */
service(auto & s) const583cd1c348SPatrick Williams     auto service(auto& s) const noexcept
594a594c01SPatrick Williams         requires(!S)
604a594c01SPatrick Williams     {
613cd1c348SPatrick Williams         return client<true, P, Preserved, Types...>(ctx, proxy.service(s));
624a594c01SPatrick Williams     }
634a594c01SPatrick Williams 
644a594c01SPatrick Williams     /* Convert a non-Path instance to a Path instance. */
path(auto & p) const653cd1c348SPatrick Williams     auto path(auto& p) const noexcept
664a594c01SPatrick Williams         requires(!P)
674a594c01SPatrick Williams     {
683cd1c348SPatrick Williams         return client<S, true, Preserved, Types...>(ctx, proxy.path(p));
694a594c01SPatrick Williams     }
70*f1d999b5SPatrick Williams 
71*f1d999b5SPatrick Williams     /* Convert client into a Preserved Proxy. */
preserve() const72*f1d999b5SPatrick Williams     auto preserve() const noexcept
73*f1d999b5SPatrick Williams         requires(!Preserved)
74*f1d999b5SPatrick Williams     {
75*f1d999b5SPatrick Williams         return client<S, P, true, Types...>(ctx, proxy.preserve());
76*f1d999b5SPatrick Williams     }
774a594c01SPatrick Williams };
784a594c01SPatrick Williams 
794a594c01SPatrick Williams } // namespace client
804a594c01SPatrick Williams 
814a594c01SPatrick Williams /** A non-Preserved client alias.
824a594c01SPatrick Williams  *
834a594c01SPatrick Williams  *  This holds Service/Path in string-views, which must exist longer than
844a594c01SPatrick Williams  *  the lifetime of this client_t.
854a594c01SPatrick Williams  */
86351f8cd5SPatrick Williams template <template <typename, typename> typename... Types>
874a594c01SPatrick Williams using client_t = client::client<false, false, false, Types...>;
884a594c01SPatrick Williams /** A Preserved client alias.
894a594c01SPatrick Williams  *
904a594c01SPatrick Williams  *  This holds Service/Path in strings, which thus have lifetimes that are
914a594c01SPatrick Williams  *  the same as the client itself.
924a594c01SPatrick Williams  */
93351f8cd5SPatrick Williams template <template <typename, typename> typename... Types>
94556eae9fSVlad Sytchenko using client_preserved_t = client::client<false, false, true, Types...>;
954a594c01SPatrick Williams 
96351f8cd5SPatrick Williams namespace client::details
97351f8cd5SPatrick Williams {
98351f8cd5SPatrick Williams /* Indirect so that the generated Types can access the client_t's context.
99351f8cd5SPatrick Williams  *
100351f8cd5SPatrick Williams  * If P2893 gets into C++26 we could eliminate this because we can set all
101351f8cd5SPatrick Williams  * the Types as friends directly.
102351f8cd5SPatrick Williams  */
103351f8cd5SPatrick Williams struct client_context_friend
104351f8cd5SPatrick Williams {
105ae019280SPatrick Williams     template <typename Client, typename Self>
contextsdbusplus::async::client::details::client_context_friend106ae019280SPatrick Williams     static sdbusplus::async::context& context(Self* self)
107351f8cd5SPatrick Williams     {
108ae019280SPatrick Williams         return static_cast<Client*>(self)->ctx;
109351f8cd5SPatrick Williams     }
110351f8cd5SPatrick Williams };
111351f8cd5SPatrick Williams } // namespace client::details
112351f8cd5SPatrick Williams 
1134a594c01SPatrick Williams } // namespace sdbusplus::async
114