Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
FileSystemErrorFormatter.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "../Common/ResultErrorFormatter.h"
6#include "FileSystemError.h"
7
8namespace SC
9{
10namespace detail
11{
12inline bool appendFileSystemError(ResultErrorFormatter& formatter, FileSystemError error)
13{
14 switch (error)
15 {
16 case FileSystemError::NotInitialized: formatter.append("Filesystem is not initialized"); break;
17 case FileSystemError::UnsupportedPathEncoding: formatter.append("Filesystem path encoding is not supported"); break;
18 case FileSystemError::InvalidPath: formatter.append("Filesystem path is invalid"); break;
19 case FileSystemError::PathMustBeAbsolute: formatter.append("Filesystem path must be absolute"); break;
20 case FileSystemError::PathCapacityExceeded: formatter.append("Filesystem path capacity exceeded"); break;
21 case FileSystemError::InvalidState: formatter.append("Filesystem state is invalid"); break;
22 case FileSystemError::EntryNotFound: formatter.append("Filesystem entry was not found"); break;
23 case FileSystemError::EntryAlreadyExists: formatter.append("Filesystem entry already exists"); break;
24 case FileSystemError::EntryTypeMismatch: formatter.append("Filesystem entry has an unexpected type"); break;
25 case FileSystemError::AccessDenied: formatter.append("Filesystem access was denied"); break;
26 case FileSystemError::ReadOnlyFileSystem: formatter.append("Filesystem is read-only"); break;
27 case FileSystemError::StorageCapacityExceeded: formatter.append("Filesystem storage capacity was exceeded"); break;
28 case FileSystemError::DirectoryNotEmpty: formatter.append("Filesystem directory is not empty"); break;
29 case FileSystemError::TooManyLinks: formatter.append("Filesystem link limit was exceeded"); break;
30 case FileSystemError::SymbolicLinkLoop: formatter.append("Filesystem symbolic link loop was detected"); break;
31 case FileSystemError::CrossDeviceOperation:
32 formatter.append("Filesystem operation crosses device boundaries");
33 break;
34 case FileSystemError::InvalidArgument: formatter.append("Filesystem operation argument is invalid"); break;
35 case FileSystemError::OperationUnsupported: formatter.append("Filesystem operation is unsupported"); break;
36 case FileSystemError::OutOfMemory: formatter.append("Filesystem operation ran out of memory"); break;
37 case FileSystemError::BufferCapacityExceeded: formatter.append("Filesystem buffer capacity exceeded"); break;
38 case FileSystemError::FileTooLarge: formatter.append("Filesystem file is too large"); break;
39 case FileSystemError::IncompleteRead: formatter.append("Filesystem read was incomplete"); break;
40 case FileSystemError::IncompleteWrite: formatter.append("Filesystem write was incomplete"); break;
41 case FileSystemError::UnsupportedEntryType: formatter.append("Filesystem entry type is unsupported"); break;
42 case FileSystemError::IoFailure: formatter.append("Filesystem input/output operation failed"); break;
43 case FileSystemError::OperationFailed: formatter.append("Filesystem operation failed"); break;
44 default: return false;
45 }
46 return true;
47}
48
49inline bool appendFileSystemErrorDetail(ResultErrorFormatter& formatter, FileSystemErrorDetail detail)
50{
51 switch (detail)
52 {
53 case FileSystemErrorDetail::None: return true;
54 case FileSystemErrorDetail::ValidatePathEncoding: formatter.append("validate path encoding"); break;
55 case FileSystemErrorDetail::NormalizePath: formatter.append("normalize path"); break;
56 case FileSystemErrorDetail::ValidateAbsoluteBasePath: formatter.append("validate absolute base path"); break;
57 case FileSystemErrorDetail::BuildTransportPath: formatter.append("build native transport path"); break;
58 case FileSystemErrorDetail::ChangeDirectory: formatter.append("change filesystem directory"); break;
59 case FileSystemErrorDetail::CheckAccess: formatter.append("check entry access"); break;
60 case FileSystemErrorDetail::QueryEntryMetadata: formatter.append("query entry metadata"); break;
61 case FileSystemErrorDetail::OpenFileForRead: formatter.append("open file for reading"); break;
62 case FileSystemErrorDetail::OpenFileForWrite: formatter.append("open file for writing"); break;
63 case FileSystemErrorDetail::QueryFileSize: formatter.append("query file size"); break;
64 case FileSystemErrorDetail::GrowReadBuffer: formatter.append("grow read buffer"); break;
65 case FileSystemErrorDetail::ReadFileContent: formatter.append("read file content"); break;
66 case FileSystemErrorDetail::WriteFileContent: formatter.append("write file content"); break;
67 case FileSystemErrorDetail::AppendFileContent: formatter.append("append file content"); break;
68 case FileSystemErrorDetail::CreateDirectoryEntry: formatter.append("create directory"); break;
69 case FileSystemErrorDetail::CreateParentDirectory: formatter.append("create parent directory"); break;
70 case FileSystemErrorDetail::RemoveFileEntry: formatter.append("remove file"); break;
71 case FileSystemErrorDetail::RemoveDirectoryEntry: formatter.append("remove directory"); break;
72 case FileSystemErrorDetail::RenameEntry: formatter.append("rename entry"); break;
73 case FileSystemErrorDetail::CreateSymbolicLinkEntry: formatter.append("create symbolic link"); break;
74 case FileSystemErrorDetail::CreateHardLinkEntry: formatter.append("create hard link"); break;
75 case FileSystemErrorDetail::ReadSymbolicLinkTarget: formatter.append("read symbolic link target"); break;
76 case FileSystemErrorDetail::StoreSymbolicLinkTarget: formatter.append("store symbolic link target"); break;
77 case FileSystemErrorDetail::ChangePermissions: formatter.append("change entry permissions"); break;
78 case FileSystemErrorDetail::ChangeOwnership: formatter.append("change entry ownership"); break;
79 case FileSystemErrorDetail::ChangeLinkPermissions: formatter.append("change link permissions"); break;
80 case FileSystemErrorDetail::ChangeLinkOwnership: formatter.append("change link ownership"); break;
81 case FileSystemErrorDetail::ChangeModifiedTime: formatter.append("change modified time"); break;
82 case FileSystemErrorDetail::CopyFileEntry: formatter.append("copy file"); break;
83 case FileSystemErrorDetail::CopyDirectoryTree: formatter.append("copy directory"); break;
84 case FileSystemErrorDetail::CloneEntry: formatter.append("clone entry"); break;
85 case FileSystemErrorDetail::OpenSourceFile: formatter.append("open source file"); break;
86 case FileSystemErrorDetail::OpenDestinationFile: formatter.append("open destination file"); break;
87 case FileSystemErrorDetail::OpenSourceDirectory: formatter.append("open source directory"); break;
88 case FileSystemErrorDetail::EnumerateDirectory: formatter.append("enumerate directory"); break;
89 case FileSystemErrorDetail::BuildChildPath: formatter.append("build child path"); break;
90 case FileSystemErrorDetail::QueryChildMetadata: formatter.append("query child metadata"); break;
91 case FileSystemErrorDetail::CopyChildEntry: formatter.append("copy child entry"); break;
92 case FileSystemErrorDetail::RemoveChildEntry: formatter.append("remove child entry"); break;
93 case FileSystemErrorDetail::WindowsQueryReparsePoint: formatter.append("query Windows reparse point"); break;
94 case FileSystemErrorDetail::QueryFileTimes: formatter.append("query file times"); break;
95 case FileSystemErrorDetail::SetFileTimes: formatter.append("set file times"); break;
96 default: return false;
97 }
98 return true;
99}
100
101inline ResultErrorFormat formatFileSystemErrorWithContext(FileSystemError error, FileSystemErrorDetail detail,
102 FileSystemErrorContextKind contextKind,
103 FileSystemErrorContext context, Span<char> output)
104{
105 ResultErrorFormatter formatter(output);
106 if (not appendFileSystemError(formatter, error))
107 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
108 if (detail != FileSystemErrorDetail::None)
109 {
110 formatter.append(" (detail: ");
111 if (not appendFileSystemErrorDetail(formatter, detail))
112 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
113 formatter.append(")");
114 }
115 switch (contextKind)
116 {
117 case FileSystemErrorContextKind::None: break;
118 case FileSystemErrorContextKind::NativeError:
119 formatter.append(" (native error: ");
120 formatter.append(static_cast<uint64_t>(context.nativeError));
121 formatter.append(")");
122 break;
123 case FileSystemErrorContextKind::RequiredBytes:
124 formatter.append(" (required capacity: ");
125 formatter.append(static_cast<uint64_t>(context.requiredBytes));
126 formatter.append(" bytes)");
127 break;
128 case FileSystemErrorContextKind::ActualBytes:
129 formatter.append(" (actual bytes: ");
130 formatter.append(static_cast<uint64_t>(context.actualBytes));
131 formatter.append(")");
132 break;
133 default: return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
134 }
135 return formatter.finish();
136}
137} // namespace detail
138
139inline ResultErrorFormat formatFileSystemError(FileSystemError error, Span<char> output)
140{
141 return detail::formatFileSystemErrorWithContext(error, FileSystemErrorDetail::None,
142 FileSystemErrorContextKind::None, {}, output);
143}
144
145inline ResultErrorFormat formatFileSystemError(Result result, Span<char> output)
146{
147 if (result)
148 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
149 if (result.category() != FileSystemResultCategory)
150 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
151 return formatFileSystemError(static_cast<FileSystemError>(result.errorValue()), output);
152}
153
154inline ResultErrorFormat formatFileSystemError(ResultFileSystem result, Span<char> output)
155{
156 if (result)
157 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
158 if (result.result.category() != FileSystemResultCategory)
159 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
160 return detail::formatFileSystemErrorWithContext(static_cast<FileSystemError>(result.result.errorValue()),
161 result.detail, result.contextKind, result.context, output);
162}
163} // namespace SC
FileSystemErrorContextKind
Kind of scalar diagnostic context stored in ResultFileSystem.
Definition FileSystemError.h:93
FileSystemErrorDetail
Stable logical operation or backend stage retained for a FileSystem failure.
Definition FileSystemError.h:45
FileSystemError
Stable portable failures returned by the FileSystem library.
Definition FileSystemError.h:14