File indexing completed on 2024-04-28 16:53:08

0001 /*
0002  *   SPDX-FileCopyrightText: 2016 Ivan Cukic <ivan.cukic(at)kde.org>
0003  *
0004  *   SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #ifndef ASYNQT_CONS_PROCESS_H
0008 #define ASYNQT_CONS_PROCESS_H
0009 
0010 #include <QFuture>
0011 #include <QFutureInterface>
0012 #include <QProcess>
0013 
0014 #include "../private/wrappers/process_p.h"
0015 
0016 namespace AsynQt
0017 {
0018 /**
0019  * Creates a future that will be completed when the process finishes.
0020  * @arg process process to wrap inside a future
0021  * @arg map function that extracts the needed information from the process
0022  *
0023  * <code>
0024  *     // If we want to get the exit code of the process
0025  *     makeFuture(process, [] (QProcess *p) { return p->exitCode(); })
0026  *
0027  *     // If we want to get the output of the process
0028  *     makeFuture(process, [] (QProcess *p) { return p->readAllStandardOutput(); })
0029  * </code>
0030  */
0031 template<typename _Function>
0032 auto makeFuture(QProcess *process, _Function map) -> QFuture<decltype(map(Q_NULLPTR))>
0033 {
0034     using namespace detail;
0035 
0036     auto futureInterface = new ProcessFutureInterface<decltype(map(Q_NULLPTR)), _Function>(process, map);
0037 
0038     return futureInterface->start();
0039 }
0040 
0041 inline auto makeFuture(QProcess *process) -> QFuture<QProcess *>
0042 {
0043     using namespace detail;
0044 
0045     auto id = [](QProcess *process) {
0046         return process;
0047     };
0048 
0049     auto futureInterface = new ProcessFutureInterface<QProcess *, decltype(id)>(process, id);
0050 
0051     return futureInterface->start();
0052 }
0053 
0054 namespace Process
0055 {
0056 /**
0057  * Executes the specified command, with the specified arguments.
0058  */
0059 template<typename _Function>
0060 auto exec(const QString &command, const QStringList &arguments, _Function &&map) -> QFuture<decltype(map(Q_NULLPTR))>
0061 {
0062     // TODO: Where to delete this process?
0063     auto process = new QProcess();
0064 
0065     // process->setProcessChannelMode(QProcess::ForwardedChannels);
0066     process->setProgram(command);
0067     process->setArguments(arguments);
0068 
0069     return AsynQt::makeFuture(process, std::forward<_Function>(map));
0070 }
0071 
0072 /**
0073  * Executes the specified command, with the specified arguments,
0074  * and returns the future containing the process it created.
0075  */
0076 inline QFuture<QProcess *> exec(const QString &command, const QStringList &arguments)
0077 {
0078     return exec(command, arguments, [](QProcess *process) {
0079         return process;
0080     });
0081 }
0082 
0083 /**
0084  * Executes the specified command, with the specified arguments,
0085  * and it returns a future containing the output of that command.
0086  */
0087 inline QFuture<QByteArray> getOutput(const QString &command, const QStringList &arguments)
0088 {
0089     return exec(command, arguments, [](QProcess *process) {
0090         return process->readAllStandardOutput();
0091     });
0092 }
0093 
0094 } // namespace Process
0095 
0096 } // namespace qfuture
0097 
0098 #endif // ASYNQT_CONS_PROCESS_H