Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
FileErrorFormatter.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "../Common/ResultErrorFormatter.h"
6#include "FileError.h"
7
8namespace SC
9{
10namespace detail
11{
12inline bool appendFileError(ResultErrorFormatter& formatter, FileError error)
13{
14 switch (error)
15 {
16 case FileError::InvalidHandle: formatter.append("File descriptor is invalid"); break;
17 case FileError::UnsupportedPathEncoding: formatter.append("File path encoding is not supported"); break;
18 case FileError::InvalidPath: formatter.append("File path is invalid"); break;
19 case FileError::PathMustBeAbsolute: formatter.append("File path must be absolute"); break;
20 case FileError::PathCapacityExceeded: formatter.append("File path capacity exceeded"); break;
21 case FileError::InvalidNamedPipeName: formatter.append("Named pipe name is invalid"); break;
22 case FileError::InvalidState: formatter.append("File object state is invalid"); break;
23 case FileError::OperationUnsupported: formatter.append("File operation is unsupported"); break;
24 case FileError::OpenFailed: formatter.append("Failed to open file descriptor"); break;
25 case FileError::CloseFailed: formatter.append("Failed to close file descriptor"); break;
26 case FileError::ReadFailed: formatter.append("Failed to read file descriptor"); break;
27 case FileError::WriteFailed: formatter.append("Failed to write file descriptor"); break;
28 case FileError::IncompleteWrite: formatter.append("File descriptor write was incomplete"); break;
29 case FileError::SeekFailed: formatter.append("Failed to seek file descriptor"); break;
30 case FileError::MetadataQueryFailed: formatter.append("Failed to query file descriptor metadata"); break;
31 case FileError::PermissionsChangeFailed: formatter.append("Failed to change file descriptor permissions"); break;
32 case FileError::OwnershipChangeFailed: formatter.append("Failed to change file descriptor ownership"); break;
33 case FileError::SyncFailed: formatter.append("Failed to synchronize file descriptor"); break;
34 case FileError::TruncateFailed: formatter.append("Failed to truncate file descriptor"); break;
35 case FileError::DuplicateFailed: formatter.append("Failed to duplicate file descriptor"); break;
36 case FileError::DescriptorConfigurationFailed: formatter.append("Failed to configure file descriptor"); break;
37 case FileError::PipeCreationFailed: formatter.append("Failed to create pipe"); break;
38 case FileError::NamedPipeCreationFailed: formatter.append("Failed to create named pipe server"); break;
39 case FileError::NamedPipeConnectionFailed: formatter.append("Failed to connect named pipe"); break;
40 case FileError::NamedPipeAcceptFailed: formatter.append("Failed to accept named pipe connection"); break;
41 case FileError::EndpointCleanupFailed: formatter.append("Failed to remove named pipe endpoint"); break;
42 case FileError::BufferCapacityExceeded: formatter.append("Buffer capacity exceeded"); break;
43 case FileError::WouldBlock: formatter.append("File operation would block"); break;
44 case FileError::TimedOut: formatter.append("File operation timed out"); break;
45 case FileError::OperationCancelled: formatter.append("File operation was cancelled"); break;
46 case FileError::PipeDisconnected: formatter.append("Pipe is disconnected"); break;
47 default: return false;
48 }
49 return true;
50}
51
52inline bool appendFileErrorDetail(ResultErrorFormatter& formatter, FileErrorDetail detail)
53{
54 switch (detail)
55 {
56 case FileErrorDetail::None: return true;
57 case FileErrorDetail::ValidatePathEncoding: formatter.append("validate path encoding"); break;
58 case FileErrorDetail::NormalizePath: formatter.append("normalize path"); break;
59 case FileErrorDetail::ValidateAbsolutePath: formatter.append("validate absolute path"); break;
60 case FileErrorDetail::BuildTransportPath: formatter.append("build native transport path"); break;
61 case FileErrorDetail::OpenFile: formatter.append("open file"); break;
62 case FileErrorDetail::CloseDescriptor: formatter.append("close descriptor"); break;
63 case FileErrorDetail::ReadDescriptor: formatter.append("read descriptor"); break;
64 case FileErrorDetail::ReadDescriptorAtOffset: formatter.append("read descriptor at offset"); break;
65 case FileErrorDetail::GrowReadBuffer: formatter.append("grow read buffer"); break;
66 case FileErrorDetail::ResetReadBuffer: formatter.append("reset read buffer"); break;
67 case FileErrorDetail::WriteDescriptor: formatter.append("write descriptor"); break;
68 case FileErrorDetail::WriteDescriptorAtOffset: formatter.append("write descriptor at offset"); break;
69 case FileErrorDetail::SeekDescriptor: formatter.append("seek descriptor"); break;
70 case FileErrorDetail::QueryDescriptorPosition: formatter.append("query descriptor position"); break;
71 case FileErrorDetail::QueryDescriptorSize: formatter.append("query descriptor size"); break;
72 case FileErrorDetail::QueryDescriptorMetadata: formatter.append("query descriptor metadata"); break;
73 case FileErrorDetail::ChangeDescriptorPermissions: formatter.append("change descriptor permissions"); break;
74 case FileErrorDetail::ChangeDescriptorOwnership: formatter.append("change descriptor ownership"); break;
75 case FileErrorDetail::SynchronizeDescriptor: formatter.append("synchronize descriptor"); break;
76 case FileErrorDetail::SynchronizeDescriptorData: formatter.append("synchronize descriptor data"); break;
77 case FileErrorDetail::TruncateDescriptor: formatter.append("truncate descriptor"); break;
78 case FileErrorDetail::GetStandardHandle: formatter.append("get standard handle"); break;
79 case FileErrorDetail::DuplicateStandardHandle: formatter.append("duplicate standard handle"); break;
80 case FileErrorDetail::CreateAnonymousPipe: formatter.append("create anonymous pipe"); break;
81 case FileErrorDetail::DuplicatePipeDescriptor: formatter.append("duplicate pipe descriptor"); break;
82 case FileErrorDetail::AssignPipeDescriptor: formatter.append("assign pipe descriptor"); break;
83 case FileErrorDetail::QueryDescriptorFlags: formatter.append("query descriptor flags"); break;
84 case FileErrorDetail::ConfigureDescriptorFlags: formatter.append("configure descriptor flags"); break;
85 case FileErrorDetail::ValidateNamedPipeLogicalName: formatter.append("validate named pipe logical name"); break;
86 case FileErrorDetail::BuildNamedPipePath: formatter.append("build named pipe path"); break;
87 case FileErrorDetail::ValidateNamedPipePath: formatter.append("validate named pipe path"); break;
88 case FileErrorDetail::CreateNamedPipeServer: formatter.append("create named pipe server"); break;
89 case FileErrorDetail::RemoveNamedPipeEndpoint: formatter.append("remove named pipe endpoint"); break;
90 case FileErrorDetail::BindNamedPipeServer: formatter.append("bind named pipe server"); break;
91 case FileErrorDetail::ListenNamedPipeServer: formatter.append("listen on named pipe server"); break;
92 case FileErrorDetail::AcceptNamedPipeConnection: formatter.append("accept named pipe connection"); break;
93 case FileErrorDetail::WaitNamedPipeClient: formatter.append("wait for named pipe server"); break;
94 case FileErrorDetail::ConnectNamedPipeClient: formatter.append("connect named pipe client"); break;
95 case FileErrorDetail::DuplicateNamedPipeConnection: formatter.append("duplicate named pipe connection"); break;
96 default: return false;
97 }
98 return true;
99}
100
101inline ResultErrorFormat formatFileErrorWithContext(FileError error, FileErrorDetail detail,
102 FileErrorContextKind contextKind, FileErrorContext context,
103 Span<char> output)
104{
105 ResultErrorFormatter formatter(output);
106 if (not appendFileError(formatter, error))
107 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
108 if (detail != FileErrorDetail::None)
109 {
110 formatter.append(" (detail: ");
111 if (not appendFileErrorDetail(formatter, detail))
112 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
113 formatter.append(")");
114 }
115 switch (contextKind)
116 {
117 case FileErrorContextKind::None: break;
118 case FileErrorContextKind::NativeError:
119 formatter.append(" (native error: ");
120 formatter.append(static_cast<uint64_t>(context.nativeError));
121 formatter.append(")");
122 break;
123 case FileErrorContextKind::RequiredBytes:
124 formatter.append(" (required capacity: ");
125 formatter.append(static_cast<uint64_t>(context.requiredBytes));
126 formatter.append(" bytes)");
127 break;
128 case FileErrorContextKind::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 formatFileError(FileError error, Span<char> output)
140{
141 return detail::formatFileErrorWithContext(error, FileErrorDetail::None, FileErrorContextKind::None, {}, output);
142}
143
144inline ResultErrorFormat formatFileError(Result result, Span<char> output)
145{
146 if (result)
147 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
148 if (result.category() != FileResultCategory)
149 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
150 return formatFileError(static_cast<FileError>(result.errorValue()), output);
151}
152
153inline ResultErrorFormat formatFileError(ResultFile result, Span<char> output)
154{
155 if (result)
156 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
157 if (result.result.category() != FileResultCategory)
158 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
159 return detail::formatFileErrorWithContext(static_cast<FileError>(result.result.errorValue()), result.detail,
160 result.contextKind, result.context, output);
161}
162} // namespace SC
FileError
Stable portable failures returned by the File library.
Definition FileError.h:14
FileErrorContextKind
Kind of scalar diagnostic context stored in ResultFile.
Definition FileError.h:95
FileErrorDetail
Stable logical operation or native backend stage retained for a File failure.
Definition FileError.h:50