Serenity Operating System
at master 77 lines 2.8 kB view raw
1/* 2 * Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/DeprecatedFlyString.h> 10#include <AK/Error.h> 11#include <errno.h> 12 13namespace Audio { 14 15struct LoaderError { 16 17 enum class Category : u32 { 18 // The error category is unknown. 19 Unknown = 0, 20 IO, 21 // The read file doesn't follow the file format. 22 Format, 23 // Equivalent to an ASSERT(), except non-crashing. 24 Internal, 25 // The loader encountered something in the format that is not yet implemented. 26 Unimplemented, 27 }; 28 Category category { Category::Unknown }; 29 // Binary index: where in the file the error occurred. 30 size_t index { 0 }; 31 DeprecatedFlyString description { DeprecatedString::empty() }; 32 33 constexpr LoaderError() = default; 34 LoaderError(Category category, size_t index, DeprecatedFlyString description) 35 : category(category) 36 , index(index) 37 , description(move(description)) 38 { 39 } 40 LoaderError(DeprecatedFlyString description) 41 : description(move(description)) 42 { 43 } 44 LoaderError(Category category, DeprecatedFlyString description) 45 : category(category) 46 , description(move(description)) 47 { 48 } 49 50 LoaderError(LoaderError&) = default; 51 LoaderError(LoaderError&&) = default; 52 53 LoaderError(Error&& error) 54 { 55 if (error.is_errno()) { 56 auto code = error.code(); 57 description = DeprecatedString::formatted("{} ({})", strerror(code), code); 58 if (code == EBADF || code == EBUSY || code == EEXIST || code == EIO || code == EISDIR || code == ENOENT || code == ENOMEM || code == EPIPE) 59 category = Category::IO; 60 } else { 61 description = error.string_literal(); 62 } 63 } 64}; 65 66} 67 68// Convenience TRY-like macro to convert an Error to a LoaderError 69#define LOADER_TRY(expression) \ 70 ({ \ 71 auto&& _temporary_result = (expression); \ 72 if (_temporary_result.is_error()) \ 73 return LoaderError(_temporary_result.release_error()); \ 74 static_assert(!::AK::Detail::IsLvalueReference<decltype(_temporary_result.release_value())>, \ 75 "Do not return a reference from a fallible expression"); \ 76 _temporary_result.release_value(); \ 77 })