forked from qt-creator/qt-creator
Utils: Add std::expected implementation
Adds a std::expected implementation that is compatible with >= C++11. FilePath::fileContents and FilePath::writeFileContents as well as FilePath::copyFile are changed to return std::expected. A couple of macros have been added to aid in using the expected types. An auto test was added showing how to use the library. Change-Id: Ibe3aecfc1029a0cf13b45bf5184ff03a04a2393b Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -9,15 +9,17 @@
|
||||
#include "fileutils.h"
|
||||
#include "hostosinfo.h"
|
||||
#include "qtcassert.h"
|
||||
#include "utilstr.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
#include <QRegularExpression>
|
||||
#include <QUrl>
|
||||
#include <QStringView>
|
||||
#include <QUrl>
|
||||
#include <QtGlobal>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef QTCREATOR_PCH_H
|
||||
@@ -494,7 +496,7 @@ void FilePath::iterateDirectories(const FilePaths &dirs,
|
||||
dir.iterateDirectory(callBack, filter);
|
||||
}
|
||||
|
||||
std::optional<QByteArray> FilePath::fileContents(qint64 maxSize, qint64 offset) const
|
||||
expected_str<QByteArray> FilePath::fileContents(qint64 maxSize, qint64 offset) const
|
||||
{
|
||||
return fileAccess()->fileContents(*this, maxSize, offset);
|
||||
}
|
||||
@@ -510,15 +512,14 @@ bool FilePath::ensureReachable(const FilePath &other) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void FilePath::asyncFileContents(
|
||||
const Continuation<const std::optional<QByteArray> &> &cont,
|
||||
qint64 maxSize,
|
||||
qint64 offset) const
|
||||
void FilePath::asyncFileContents(const Continuation<const expected_str<QByteArray> &> &cont,
|
||||
qint64 maxSize,
|
||||
qint64 offset) const
|
||||
{
|
||||
return fileAccess()->asyncFileContents(*this, cont, maxSize, offset);
|
||||
}
|
||||
|
||||
bool FilePath::writeFileContents(const QByteArray &data, qint64 offset) const
|
||||
expected_str<qint64> FilePath::writeFileContents(const QByteArray &data, qint64 offset) const
|
||||
{
|
||||
return fileAccess()->writeFileContents(*this, data, offset);
|
||||
}
|
||||
@@ -528,10 +529,9 @@ FilePathInfo FilePath::filePathInfo() const
|
||||
return fileAccess()->filePathInfo(*this);
|
||||
}
|
||||
|
||||
void FilePath::asyncWriteFileContents(
|
||||
const Continuation<bool> &cont,
|
||||
const QByteArray &data,
|
||||
qint64 offset) const
|
||||
void FilePath::asyncWriteFileContents(const Continuation<const expected_str<qint64> &> &cont,
|
||||
const QByteArray &data,
|
||||
qint64 offset) const
|
||||
{
|
||||
return fileAccess()->asyncWriteFileContents(*this, cont, data, offset);
|
||||
}
|
||||
@@ -1315,33 +1315,47 @@ bool FilePath::removeRecursively(QString *error) const
|
||||
return fileAccess()->removeRecursively(*this, error);
|
||||
}
|
||||
|
||||
bool FilePath::copyFile(const FilePath &target) const
|
||||
expected_str<void> FilePath::copyFile(const FilePath &target) const
|
||||
{
|
||||
if (host() != target.host()) {
|
||||
// FIXME: This does not scale.
|
||||
const std::optional<QByteArray> ba = fileContents();
|
||||
if (!ba)
|
||||
return false;
|
||||
const auto perms = permissions();
|
||||
if (!target.writeFileContents(*ba))
|
||||
return false;
|
||||
const expected_str<QByteArray> contents = fileContents();
|
||||
if (!contents) {
|
||||
return make_unexpected(
|
||||
Tr::tr("Error while trying to copy file: %1").arg(contents.error()));
|
||||
}
|
||||
|
||||
const QFile::Permissions perms = permissions();
|
||||
const expected_str<qint64> copyResult = target.writeFileContents(*contents);
|
||||
|
||||
if (!copyResult)
|
||||
return make_unexpected(Tr::tr("Could not copy file: %1").arg(copyResult.error()));
|
||||
|
||||
if (!target.setPermissions(perms)) {
|
||||
target.removeFile();
|
||||
return false;
|
||||
return make_unexpected(
|
||||
Tr::tr("Could not set permissions on \"%1\"").arg(target.toString()));
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
return fileAccess()->copyFile(*this, target);
|
||||
}
|
||||
|
||||
void FilePath::asyncCopyFile(const std::function<void(bool)> &cont, const FilePath &target) const
|
||||
void FilePath::asyncCopyFile(const Continuation<const expected_str<void> &> &cont,
|
||||
const FilePath &target) const
|
||||
{
|
||||
if (host() != target.host()) {
|
||||
asyncFileContents([cont, target](const std::optional<QByteArray> &ba) {
|
||||
if (ba)
|
||||
target.asyncWriteFileContents(cont, *ba);
|
||||
asyncFileContents([cont, target](const expected_str<QByteArray> &contents) {
|
||||
if (contents)
|
||||
target.asyncWriteFileContents(
|
||||
[cont](const expected_str<qint64> &result) {
|
||||
if (result)
|
||||
cont({});
|
||||
else
|
||||
cont(make_unexpected(result.error()));
|
||||
},
|
||||
*contents);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user