// Copyright (c) Facebook, Inc. and its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include "yarpl/single/SingleObserver.h" #include namespace yarpl { namespace single { /// Helper methods for constructing subscriber instances from functions: /// one or two functions (callables; can be lamda, for instance) /// may be specified, corresponding to onNext, onError and onComplete /// method bodies in the subscriber. class SingleObservers { private: /// Defined if Success and Error are signature-compatible with /// onSuccess and onError subscriber methods respectively. template < typename T, typename Success, typename Error = void (*)(folly::exception_wrapper)> using EnableIfCompatible = typename std::enable_if< folly::is_invocable&, T>::value && folly::is_invocable&, folly::exception_wrapper>:: value>::type; public: template > static auto create(Next&& next) { return std::make_shared>>( std::forward(next)); } template < typename T, typename Success, typename Error, typename = EnableIfCompatible> static auto create(Success&& next, Error&& error) { return std::make_shared< WithError, std::decay_t>>( std::forward(next), std::forward(error)); } template static auto create() { return std::make_shared>(); } private: template class Base : public SingleObserverBase { static_assert(std::is_same, Next>::value, "undecayed"); public: template explicit Base(FNext&& next) : next_(std::forward(next)) {} void onSuccess(T value) override { next_(std::move(value)); // TODO how do we call the super to trigger release? // SingleObserver::onSuccess(value); } private: Next next_; }; template class WithError : public Base { static_assert(std::is_same, Error>::value, "undecayed"); public: template WithError(FSuccess&& success, FError&& error) : Base(std::forward(success)), error_(std::forward(error)) {} void onError(folly::exception_wrapper error) override { error_(error); // TODO do we call the super here to trigger release? Base::onError(std::move(error)); } private: Error error_; }; SingleObservers() = delete; }; } // namespace single } // namespace yarpl