From 4f2d59ccbe1363afc79f11bf7e46964e328be55b Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sun, 2 Apr 2023 00:50:19 +0300 Subject: [PATCH] [FS] Integrate Result to codebase --- include/fs/archive_base.hpp | 18 +++---- include/fs/archive_ext_save_data.hpp | 4 +- include/fs/archive_ncch.hpp | 4 +- include/fs/archive_save_data.hpp | 6 +-- include/fs/archive_sdmc.hpp | 4 +- include/fs/archive_self_ncch.hpp | 4 +- include/logger.hpp | 2 + include/services/fs.hpp | 2 +- src/core/fs/archive_ext_save_data.cpp | 16 +++--- src/core/fs/archive_ncch.cpp | 8 +-- src/core/fs/archive_save_data.cpp | 21 ++++---- src/core/fs/archive_sdmc.cpp | 8 +-- src/core/fs/archive_self_ncch.cpp | 8 +-- src/core/services/fs.cpp | 61 +++++++++++------------ third_party/result/include/result.hpp | 70 ++++++++++++++------------- 15 files changed, 122 insertions(+), 114 deletions(-) diff --git a/include/fs/archive_base.hpp b/include/fs/archive_base.hpp index 8374a4cd..9f2cf43d 100644 --- a/include/fs/archive_base.hpp +++ b/include/fs/archive_base.hpp @@ -9,6 +9,7 @@ #include #include "helpers.hpp" #include "memory.hpp" +#include "result.hpp" namespace PathType { enum : u32 { @@ -127,14 +128,10 @@ struct DirectorySession { // Otherwise the fd of the opened file is returned (or nullptr if the opened file doesn't require one) using FileDescriptor = std::optional; -enum class CreateFileResult : u32 { +enum class FSResult : u32 { Success = 0, AlreadyExists = 0x82044BE, - FileTooLarge = 0x86044D2 -}; - -enum class DeleteFileResult : u32 { - Success = 0, + FileTooLarge = 0x86044D2, FileNotFound = 0xC8804470 }; @@ -149,6 +146,7 @@ public: protected: using Handle = u32; + static constexpr FileDescriptor NoFile = nullptr; static constexpr FileDescriptor FileError = std::nullopt; Memory& mem; @@ -201,8 +199,8 @@ protected: public: virtual std::string name() = 0; virtual u64 getFreeBytes() = 0; - virtual CreateFileResult createFile(const FSPath& path, u64 size) = 0; - virtual DeleteFileResult deleteFile(const FSPath& path) = 0; + virtual FSResult createFile(const FSPath& path, u64 size) = 0; + virtual FSResult deleteFile(const FSPath& path) = 0; virtual FormatInfo getFormatInfo(const FSPath& path) { Helpers::panic("Unimplemented GetFormatInfo for %s archive", name().c_str()); // Return a dummy struct just to avoid the UB of not returning anything, even if we panic @@ -213,9 +211,9 @@ public: virtual FileDescriptor openFile(const FSPath& path, const FilePerms& perms) = 0; virtual ArchiveBase* openArchive(const FSPath& path) = 0; - virtual std::optional openDirectory(const FSPath& path) { + virtual Rust::Result openDirectory(const FSPath& path) { Helpers::panic("Unimplemented OpenDirectory for %s archive", name().c_str()); - return std::nullopt; + return Err(FSResult::FileNotFound); } // Read size bytes from a file starting at offset "offset" into a certain buffer in memory diff --git a/include/fs/archive_ext_save_data.hpp b/include/fs/archive_ext_save_data.hpp index b12ce1c9..207ab455 100644 --- a/include/fs/archive_ext_save_data.hpp +++ b/include/fs/archive_ext_save_data.hpp @@ -8,8 +8,8 @@ public: u64 getFreeBytes() override { Helpers::panic("ExtSaveData::GetFreeBytes unimplemented"); return 0; } std::string name() override { return "ExtSaveData"; } - CreateFileResult createFile(const FSPath& path, u64 size) override; - DeleteFileResult deleteFile(const FSPath& path) override; + FSResult createFile(const FSPath& path, u64 size) override; + FSResult deleteFile(const FSPath& path) override; ArchiveBase* openArchive(const FSPath& path) override; FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; diff --git a/include/fs/archive_ncch.hpp b/include/fs/archive_ncch.hpp index 558c8175..8ce3a3b5 100644 --- a/include/fs/archive_ncch.hpp +++ b/include/fs/archive_ncch.hpp @@ -8,8 +8,8 @@ public: u64 getFreeBytes() override { Helpers::panic("NCCH::GetFreeBytes unimplemented"); return 0; } std::string name() override { return "NCCH"; } - CreateFileResult createFile(const FSPath& path, u64 size) override; - DeleteFileResult deleteFile(const FSPath& path) override; + FSResult createFile(const FSPath& path, u64 size) override; + FSResult deleteFile(const FSPath& path) override; ArchiveBase* openArchive(const FSPath& path) override; FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; diff --git a/include/fs/archive_save_data.hpp b/include/fs/archive_save_data.hpp index d45c0014..a10a8b0d 100644 --- a/include/fs/archive_save_data.hpp +++ b/include/fs/archive_save_data.hpp @@ -8,12 +8,12 @@ public: u64 getFreeBytes() override { Helpers::panic("SaveData::GetFreeBytes unimplemented"); return 0; } std::string name() override { return "SaveData"; } - CreateFileResult createFile(const FSPath& path, u64 size) override; - DeleteFileResult deleteFile(const FSPath& path) override; + FSResult createFile(const FSPath& path, u64 size) override; + FSResult deleteFile(const FSPath& path) override; FormatInfo getFormatInfo(const FSPath& path) override; ArchiveBase* openArchive(const FSPath& path) override; - std::optional openDirectory(const FSPath& path) override; + Rust::Result openDirectory(const FSPath& path) override; FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; std::optional readFile(FileSession* file, u64 offset, u32 size, u32 dataPointer) override; diff --git a/include/fs/archive_sdmc.hpp b/include/fs/archive_sdmc.hpp index b772aedc..df8f0221 100644 --- a/include/fs/archive_sdmc.hpp +++ b/include/fs/archive_sdmc.hpp @@ -8,8 +8,8 @@ public: u64 getFreeBytes() override { Helpers::panic("SDMC::GetFreeBytes unimplemented"); return 0; } std::string name() override { return "SDMC"; } - CreateFileResult createFile(const FSPath& path, u64 size) override; - DeleteFileResult deleteFile(const FSPath& path) override; + FSResult createFile(const FSPath& path, u64 size) override; + FSResult deleteFile(const FSPath& path) override; ArchiveBase* openArchive(const FSPath& path) override; FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; diff --git a/include/fs/archive_self_ncch.hpp b/include/fs/archive_self_ncch.hpp index 5e325f91..9b8bbeed 100644 --- a/include/fs/archive_self_ncch.hpp +++ b/include/fs/archive_self_ncch.hpp @@ -8,8 +8,8 @@ public: u64 getFreeBytes() override { return 0; } std::string name() override { return "SelfNCCH"; } - CreateFileResult createFile(const FSPath& path, u64 size) override; - DeleteFileResult deleteFile(const FSPath& path) override; + FSResult createFile(const FSPath& path, u64 size) override; + FSResult deleteFile(const FSPath& path) override; ArchiveBase* openArchive(const FSPath& path) override; FileDescriptor openFile(const FSPath& path, const FilePerms& perms) override; diff --git a/include/logger.hpp b/include/logger.hpp index b2376b35..51505f10 100644 --- a/include/logger.hpp +++ b/include/logger.hpp @@ -17,6 +17,7 @@ namespace Log { } }; +#define false 0 // Our loggers here. Enable/disable by toggling the template param static Logger kernelLogger; static Logger debugStringLogger; // Enables output for the outputDebugString SVC @@ -48,6 +49,7 @@ namespace Log { static Logger ptmLogger; static Logger y2rLogger; static Logger srvLogger; +#undef false #define MAKE_LOG_FUNCTION(functionName, logger) \ template \ diff --git a/include/services/fs.hpp b/include/services/fs.hpp index 1ead706a..f13341f7 100644 --- a/include/services/fs.hpp +++ b/include/services/fs.hpp @@ -29,7 +29,7 @@ class FSService { ArchiveBase* getArchiveFromID(u32 id); std::optional openArchiveHandle(u32 archiveID, const FSPath& path); - std::optional openDirectoryHandle(ArchiveBase* archive, const FSPath& path); + Rust::Result openDirectoryHandle(ArchiveBase* archive, const FSPath& path); std::optional openFileHandle(ArchiveBase* archive, const FSPath& path, const FSPath& archivePath, const FilePerms& perms); FSPath readPath(u32 type, u32 pointer, u32 size); diff --git a/src/core/fs/archive_ext_save_data.cpp b/src/core/fs/archive_ext_save_data.cpp index 568431d6..c9f336c3 100644 --- a/src/core/fs/archive_ext_save_data.cpp +++ b/src/core/fs/archive_ext_save_data.cpp @@ -3,7 +3,7 @@ namespace fs = std::filesystem; -CreateFileResult ExtSaveDataArchive::createFile(const FSPath& path, u64 size) { +FSResult ExtSaveDataArchive::createFile(const FSPath& path, u64 size) { if (size == 0) Helpers::panic("ExtSaveData file does not support size == 0"); @@ -15,22 +15,22 @@ CreateFileResult ExtSaveDataArchive::createFile(const FSPath& path, u64 size) { p += fs::path(path.utf16_string).make_preferred(); if (fs::exists(p)) - return CreateFileResult::AlreadyExists; + return FSResult::AlreadyExists; // Create a file of size "size" by creating an empty one, seeking to size - 1 and just writing a 0 there IOFile file(p.string().c_str(), "wb"); if (file.seek(size - 1, SEEK_SET) && file.writeBytes("", 1).second == 1) { - return CreateFileResult::Success; + return FSResult::Success; } - return CreateFileResult::FileTooLarge; + return FSResult::FileTooLarge; } Helpers::panic("ExtSaveDataArchive::OpenFile: Failed"); - return CreateFileResult::Success; + return FSResult::Success; } -DeleteFileResult ExtSaveDataArchive::deleteFile(const FSPath& path) { +FSResult ExtSaveDataArchive::deleteFile(const FSPath& path) { if (path.type == PathType::UTF16) { if (!isPathSafe(path)) Helpers::panic("Unsafe path in ExtSaveData::DeleteFile"); @@ -40,11 +40,11 @@ DeleteFileResult ExtSaveDataArchive::deleteFile(const FSPath& path) { std::error_code ec; bool success = fs::remove(p, ec); - return success ? DeleteFileResult::Success : DeleteFileResult::FileNotFound; + return success ? FSResult::Success : FSResult::FileNotFound; } Helpers::panic("ExtSaveDataArchive::DeleteFile: Failed"); - return DeleteFileResult::Success; + return FSResult::Success; } FileDescriptor ExtSaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) { diff --git a/src/core/fs/archive_ncch.cpp b/src/core/fs/archive_ncch.cpp index f3b1ba5c..ac6c412f 100644 --- a/src/core/fs/archive_ncch.cpp +++ b/src/core/fs/archive_ncch.cpp @@ -21,14 +21,14 @@ namespace MediaType { }; }; -CreateFileResult NCCHArchive::createFile(const FSPath& path, u64 size) { +FSResult NCCHArchive::createFile(const FSPath& path, u64 size) { Helpers::panic("[NCCH] CreateFile not yet supported"); - return CreateFileResult::Success; + return FSResult::Success; } -DeleteFileResult NCCHArchive::deleteFile(const FSPath& path) { +FSResult NCCHArchive::deleteFile(const FSPath& path) { Helpers::panic("[NCCH] Unimplemented DeleteFile"); - return DeleteFileResult::Success; + return FSResult::Success; } FileDescriptor NCCHArchive::openFile(const FSPath& path, const FilePerms& perms) { diff --git a/src/core/fs/archive_save_data.cpp b/src/core/fs/archive_save_data.cpp index 70af569f..499036fd 100644 --- a/src/core/fs/archive_save_data.cpp +++ b/src/core/fs/archive_save_data.cpp @@ -4,14 +4,14 @@ namespace fs = std::filesystem; -CreateFileResult SaveDataArchive::createFile(const FSPath& path, u64 size) { +FSResult SaveDataArchive::createFile(const FSPath& path, u64 size) { Helpers::panic("[SaveData] CreateFile not yet supported"); - return CreateFileResult::Success; + return FSResult::Success; } -DeleteFileResult SaveDataArchive::deleteFile(const FSPath& path) { +FSResult SaveDataArchive::deleteFile(const FSPath& path) { Helpers::panic("[SaveData] Unimplemented DeleteFile"); - return DeleteFileResult::Success; + return FSResult::Success; } FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& perms) { @@ -53,10 +53,10 @@ FileDescriptor SaveDataArchive::openFile(const FSPath& path, const FilePerms& pe return FileError; } -std::optional SaveDataArchive::openDirectory(const FSPath& path) { +Rust::Result SaveDataArchive::openDirectory(const FSPath& path) { if (!cartHasSaveData()) { printf("Tried to open SaveData directory without save data\n"); - return std::nullopt; + return Err(FSResult::Success); } if (path.type == PathType::UTF16) { @@ -66,15 +66,18 @@ std::optional SaveDataArchive::openDirectory(const FSPath& pat fs::path p = IOFile::getAppData() / "SaveData"; p += fs::path(path.utf16_string).make_preferred(); + if (fs::is_regular_file(p)) + Helpers::panic("OpenDirectory: Tried to open directory but it's actually a file"); + if (fs::is_directory(p)) { - return DirectorySession(this, p); + return Ok(DirectorySession(this, p)); } else { - Helpers::panic("Directory not found in SaveData::OpenDirectory"); + return Err(FSResult::FileNotFound); } } Helpers::panic("SaveDataArchive::OpenDirectory: Unimplemented path type"); - return std::nullopt; + return Err(FSResult::Success); } ArchiveBase::FormatInfo SaveDataArchive::getFormatInfo(const FSPath& path) { diff --git a/src/core/fs/archive_sdmc.cpp b/src/core/fs/archive_sdmc.cpp index 8109f352..cef78dec 100644 --- a/src/core/fs/archive_sdmc.cpp +++ b/src/core/fs/archive_sdmc.cpp @@ -1,14 +1,14 @@ #include "fs/archive_sdmc.hpp" #include -CreateFileResult SDMCArchive::createFile(const FSPath& path, u64 size) { +FSResult SDMCArchive::createFile(const FSPath& path, u64 size) { Helpers::panic("[SDMC] CreateFile not yet supported"); - return CreateFileResult::Success; + return FSResult::Success; } -DeleteFileResult SDMCArchive::deleteFile(const FSPath& path) { +FSResult SDMCArchive::deleteFile(const FSPath& path) { Helpers::panic("[SDMC] Unimplemented DeleteFile"); - return DeleteFileResult::Success; + return FSResult::Success; } FileDescriptor SDMCArchive::openFile(const FSPath& path, const FilePerms& perms) { diff --git a/src/core/fs/archive_self_ncch.cpp b/src/core/fs/archive_self_ncch.cpp index a6b12be7..e1d74774 100644 --- a/src/core/fs/archive_self_ncch.cpp +++ b/src/core/fs/archive_self_ncch.cpp @@ -9,14 +9,14 @@ namespace PathType { }; }; -CreateFileResult SelfNCCHArchive::createFile(const FSPath& path, u64 size) { +FSResult SelfNCCHArchive::createFile(const FSPath& path, u64 size) { Helpers::panic("[SelfNCCH] CreateFile not yet supported"); - return CreateFileResult::Success; + return FSResult::Success; } -DeleteFileResult SelfNCCHArchive::deleteFile(const FSPath& path) { +FSResult SelfNCCHArchive::deleteFile(const FSPath& path) { Helpers::panic("[SelfNCCH] Unimplemented DeleteFile"); - return DeleteFileResult::Success; + return FSResult::Success; } FileDescriptor SelfNCCHArchive::openFile(const FSPath& path, const FilePerms& perms) { diff --git a/src/core/services/fs.cpp b/src/core/services/fs.cpp index ea41d473..2170a8fe 100644 --- a/src/core/services/fs.cpp +++ b/src/core/services/fs.cpp @@ -25,7 +25,7 @@ namespace FSCommands { }; } -namespace Result { +namespace ResultCode { enum : u32 { Success = 0, FileNotFound = 0xC8804464, // TODO: Verify this @@ -81,16 +81,16 @@ std::optional FSService::openFileHandle(ArchiveBase* archive, const FSPa } } -std::optional FSService::openDirectoryHandle(ArchiveBase* archive, const FSPath& path) { - std::optional opened = archive->openDirectory(path); - if (opened.has_value()) { // If opened doesn't have a value, we failed to open the directory +Rust::Result FSService::openDirectoryHandle(ArchiveBase* archive, const FSPath& path) { + Rust::Result opened = archive->openDirectory(path); + if (opened.isOk()) { // If opened doesn't have a value, we failed to open the directory auto handle = kernel.makeObject(KernelObjectType::Directory); auto& object = kernel.getObjects()[handle]; - object.data = new DirectorySession(opened.value()); + object.data = new DirectorySession(opened.unwrap()); - return handle; + return Ok(handle); } else { - return std::nullopt; + return Err(opened.unwrapErr()); } } @@ -147,7 +147,7 @@ void FSService::handleSyncRequest(u32 messagePointer) { void FSService::initialize(u32 messagePointer) { log("FS::Initialize\n"); - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); } // TODO: Figure out how this is different from Initialize @@ -165,10 +165,10 @@ void FSService::closeArchive(u32 messagePointer) { if (object == nullptr) { log("FSService::CloseArchive: Tried to close invalid archive %X\n", handle); - mem.write32(messagePointer + 4, Result::Failure); + mem.write32(messagePointer + 4, ResultCode::Failure); } else { object->getData()->isOpen = false; - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); } } @@ -183,11 +183,11 @@ void FSService::openArchive(u32 messagePointer) { std::optional handle = openArchiveHandle(archiveID, archivePath); if (handle.has_value()) { - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); mem.write64(messagePointer + 8, handle.value()); } else { log("FS::OpenArchive: Failed to open archive with id = %d\n", archiveID); - mem.write32(messagePointer + 4, Result::Failure); + mem.write32(messagePointer + 4, ResultCode::Failure); } } @@ -204,7 +204,7 @@ void FSService::openFile(u32 messagePointer) { auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive); if (archiveObject == nullptr) [[unlikely]] { log("FS::OpenFile: Invalid archive handle %d\n", archiveHandle); - mem.write32(messagePointer + 4, Result::Failure); + mem.write32(messagePointer + 4, ResultCode::Failure); return; } @@ -217,9 +217,9 @@ void FSService::openFile(u32 messagePointer) { std::optional handle = openFileHandle(archive, filePath, archivePath, perms); if (!handle.has_value()) { printf("OpenFile failed\n"); - mem.write32(messagePointer + 4, Result::FileNotFound); + mem.write32(messagePointer + 4, ResultCode::FileNotFound); } else { - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); mem.write32(messagePointer + 8, 0x10); // "Move handle descriptor" mem.write32(messagePointer + 12, handle.value()); } @@ -235,19 +235,20 @@ void FSService::openDirectory(u32 messagePointer) { KernelObject* archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive); if (archiveObject == nullptr) [[unlikely]] { log("FS::OpenDirectory: Invalid archive handle %d\n", archiveHandle); - mem.write32(messagePointer + 4, Result::Failure); + mem.write32(messagePointer + 4, ResultCode::Failure); return; } ArchiveBase* archive = archiveObject->getData()->archive; const auto dirPath = readPath(pathType, pathPointer, pathSize); - std::optional dir = openDirectoryHandle(archive, dirPath); + auto dir = openDirectoryHandle(archive, dirPath); - if (dir.has_value()) { - mem.write32(messagePointer + 4, Result::Success); - mem.write32(messagePointer + 12, dir.value()); + if (dir.isOk()) { + mem.write32(messagePointer + 4, ResultCode::Success); + mem.write32(messagePointer + 12, dir.unwrap()); } else { - Helpers::panic("FS::OpenDirectory failed"); + printf("FS::OpenDirectory failed\n"); + mem.write32(messagePointer + 4, static_cast(dir.unwrapErr())); } } @@ -282,7 +283,7 @@ void FSService::openFileDirectly(u32 messagePointer) { if (!handle.has_value()) { Helpers::panic("OpenFileDirectly: Failed to open file with given path"); } else { - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); mem.write32(messagePointer + 12, handle.value()); } } @@ -300,14 +301,14 @@ void FSService::createFile(u32 messagePointer) { auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive); if (archiveObject == nullptr) [[unlikely]] { log("FS::OpenFile: Invalid archive handle %d\n", archiveHandle); - mem.write32(messagePointer + 4, Result::Failure); + mem.write32(messagePointer + 4, ResultCode::Failure); return; } ArchiveBase* archive = archiveObject->getData()->archive; auto filePath = readPath(filePathType, filePathPointer, filePathSize); - CreateFileResult res = archive->createFile(filePath, size); + FSResult res = archive->createFile(filePath, size); mem.write32(messagePointer + 4, static_cast(res)); } @@ -321,14 +322,14 @@ void FSService::deleteFile(u32 messagePointer) { auto archiveObject = kernel.getObject(archiveHandle, KernelObjectType::Archive); if (archiveObject == nullptr) [[unlikely]] { log("FS::DeleteFile: Invalid archive handle %d\n", archiveHandle); - mem.write32(messagePointer + 4, Result::Failure); + mem.write32(messagePointer + 4, ResultCode::Failure); return; } ArchiveBase* archive = archiveObject->getData()->archive; auto filePath = readPath(filePathType, filePathPointer, filePathSize); - DeleteFileResult res = archive->deleteFile(filePath); + FSResult res = archive->deleteFile(filePath); mem.write32(messagePointer + 4, static_cast(res)); } @@ -347,7 +348,7 @@ void FSService::getFormatInfo(u32 messagePointer) { } ArchiveBase::FormatInfo info = archive->getFormatInfo(path); - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); mem.write32(messagePointer + 8, info.size); mem.write32(messagePointer + 12, info.numOfDirectories); mem.write32(messagePointer + 16, info.numOfFiles); @@ -357,7 +358,7 @@ void FSService::getFormatInfo(u32 messagePointer) { void FSService::getPriority(u32 messagePointer) { log("FS::GetPriority\n"); - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); mem.write32(messagePointer + 8, priority); } @@ -365,12 +366,12 @@ void FSService::setPriority(u32 messagePointer) { const u32 value = mem.read32(messagePointer + 4); log("FS::SetPriority (priority = %d)\n", value); - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); priority = value; } void FSService::isSdmcDetected(u32 messagePointer) { log("FS::IsSdmcDetected\n"); - mem.write32(messagePointer + 4, Result::Success); + mem.write32(messagePointer + 4, ResultCode::Success); mem.write32(messagePointer + 8, 0); // Whether SD is detected. For now we emulate a 3DS without an SD. } \ No newline at end of file diff --git a/third_party/result/include/result.hpp b/third_party/result/include/result.hpp index 744a0049..214fe777 100644 --- a/third_party/result/include/result.hpp +++ b/third_party/result/include/result.hpp @@ -49,7 +49,9 @@ types::Err Err(E&& val) { return types::Err(std::forward(val)); } +namespace Rust { template struct Result; +} namespace details { @@ -84,7 +86,7 @@ template struct ResultOkType { typedef typename std::decay::type type; }; template -struct ResultOkType> { +struct ResultOkType> { typedef T type; }; @@ -92,13 +94,13 @@ template struct ResultErrType { typedef R type; }; template -struct ResultErrType> { +struct ResultErrType> { typedef typename std::remove_reference::type type; }; template struct IsResult : public std::false_type { }; template -struct IsResult> : public std::true_type { }; +struct IsResult> : public std::true_type { }; namespace ok { @@ -120,7 +122,7 @@ struct Map { "Can not map a callback returning a Result, use andThen instead"); template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { static_assert( std::is_same::value || @@ -141,7 +143,7 @@ template struct Map { template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { if (result.isOk()) { func(result.storage().template get()); @@ -157,7 +159,7 @@ template struct Map { template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { static_assert(std::is_same::value, "Can not map a void callback on a non-void Result"); @@ -175,7 +177,7 @@ template<> struct Map { template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { static_assert(std::is_same::value, "Can not map a void callback on a non-void Result"); @@ -190,10 +192,10 @@ struct Map { // General specialization for a callback returning a Result template -struct Map (Arg)> { +struct Map (Arg)> { template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { static_assert( std::is_same::value || std::is_convertible::value, @@ -210,10 +212,10 @@ struct Map (Arg)> { // Specialization for a void callback returning a Result template -struct Map (void)> { +struct Map (void)> { template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { static_assert(std::is_same::value, "Can not call a void-callback on a non-void Result"); if (result.isOk()) { @@ -258,7 +260,7 @@ struct Map { "Can not map a callback returning a Result, use orElse instead"); template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { if (result.isErr()) { auto res = func(result.storage().template get()); return types::Err(res); @@ -268,7 +270,7 @@ struct Map { } template - static Result map(const Result& result, Func func) { + static Rust::Result map(const Rust::Result& result, Func func) { if (result.isErr()) { auto res = func(result.storage().template get()); return types::Err(res); @@ -307,7 +309,7 @@ namespace impl { "then() should not return anything, use map() instead"); template - static Result then(const Result& result, Func func) { + static Rust::Result then(const Rust::Result& result, Func func) { if (result.isOk()) { func(result.storage().template get()); } @@ -321,7 +323,7 @@ namespace impl { "then() should not return anything, use map() instead"); template - static Result then(const Result& result, Func func) { + static Rust::Result then(const Rust::Result& result, Func func) { static_assert(std::is_same::value, "Can not call a void-callback on a non-void Result"); if (result.isOk()) { @@ -365,10 +367,10 @@ namespace impl { struct Else : public Else { }; template - struct Else (Arg)> { + struct Else (Arg)> { template - static Result orElse(const Result& result, Func func) { + static Rust::Result orElse(const Rust::Result& result, Func func) { static_assert( std::is_same::value || std::is_convertible::value, @@ -383,7 +385,7 @@ namespace impl { } template - static Result orElse(const Result& result, Func func) { + static Rust::Result orElse(const Rust::Result& result, Func func) { if (result.isErr()) { auto res = func(result.storage().template get()); return res; @@ -395,10 +397,10 @@ namespace impl { }; template - struct Else (void)> { + struct Else (void)> { template - static Result orElse(const Result& result, Func func) { + static Rust::Result orElse(const Rust::Result& result, Func func) { static_assert(std::is_same::value, "Can not call a void-callback on a non-void Result"); @@ -411,7 +413,7 @@ namespace impl { } template - static Result orElse(const Result& result, Func func) { + static Rust::Result orElse(const Rust::Result& result, Func func) { if (result.isErr()) { auto res = func(); return res; @@ -457,7 +459,7 @@ namespace impl { struct Wise { template - static Result otherwise(const Result& result, Func func) { + static Rust::Result otherwise(const Rust::Result& result, Func func) { static_assert( std::is_same::value || std::is_convertible::value, @@ -492,13 +494,13 @@ struct Wise : public impl::Wise { }; template::type >::type, E> > -Ret map(const Result& result, Func func) { +Ret map(const Rust::Result& result, Func func) { return ok::Map::map(result, func); } @@ -510,29 +512,29 @@ template::type > > -Ret mapError(const Result& result, Func func) { +Ret mapError(const Rust::Result& result, Func func) { return err::Map::map(result, func); } template -Result then(const Result& result, Func func) { +Rust::Result then(const Rust::Result& result, Func func) { return And::Then::then(result, func); } template -Result otherwise(const Result& result, Func func) { +Rust::Result otherwise(const Rust::Result& result, Func func) { return Other::Wise::otherwise(result, func); } template::type >::type > > -Ret orElse(const Result& result, Func func) { +Ret orElse(const Rust::Result& result, Func func) { return Or::Else::orElse(result, func); } @@ -700,6 +702,7 @@ typename std::enable_if< } // namespace rpog +namespace Rust { template struct Result { @@ -860,7 +863,7 @@ private: }; template -bool operator==(const Result& lhs, const Result& rhs) { +bool operator==(const Rust::Result& lhs, const Rust::Result& rhs) { static_assert(rpog::EqualityComparable::value, "T must be EqualityComparable for Result to be comparable"); static_assert(rpog::EqualityComparable::value, "E must be EqualityComparable for Result to be comparable"); @@ -873,7 +876,7 @@ bool operator==(const Result& lhs, const Result& rhs) { } template -bool operator==(const Result& lhs, types::Ok ok) { +bool operator==(const Rust::Result& lhs, types::Ok ok) { static_assert(rpog::EqualityComparable::value, "T must be EqualityComparable for Result to be comparable"); if (!lhs.isOk()) return false; @@ -882,17 +885,18 @@ bool operator==(const Result& lhs, types::Ok ok) { } template -bool operator==(const Result& lhs, types::Ok) { +bool operator==(const Rust::Result& lhs, types::Ok) { return lhs.isOk(); } template -bool operator==(const Result& lhs, types::Err err) { +bool operator==(const Rust::Result& lhs, types::Err err) { static_assert(rpog::EqualityComparable::value, "E must be EqualityComparable for Result to be comparable"); if (!lhs.isErr()) return false; return lhs.storage().template get() == err.val; } +} // end namespace Rust #define TRY(...) \ ({ \