Skip to content

Commit 0b4d669

Browse files
committed
refactor(Error): error propagation uses Expected
1 parent c376277 commit 0b4d669

23 files changed

+189
-325
lines changed

include/mrdocs/Generator.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class MRDOCS_VISIBLE
102102
*/
103103
MRDOCS_DECL
104104
virtual
105-
Error
105+
Expected<void>
106106
build(
107107
std::string_view outputPath,
108108
Corpus const& corpus) const;
@@ -120,7 +120,7 @@ class MRDOCS_VISIBLE
120120
the object before returning.
121121
*/
122122
MRDOCS_DECL
123-
Error
123+
Expected<void>
124124
build(Corpus const& corpus) const;
125125

126126
/** Build reference documentation for the corpus.
@@ -141,7 +141,7 @@ class MRDOCS_VISIBLE
141141
*/
142142
MRDOCS_DECL
143143
virtual
144-
Error
144+
Expected<void>
145145
buildOne(
146146
std::ostream& os,
147147
Corpus const& corpus) const = 0;
@@ -160,7 +160,7 @@ class MRDOCS_VISIBLE
160160
@param corpus The metadata to emit.
161161
*/
162162
MRDOCS_DECL
163-
Error
163+
Expected<void>
164164
buildOne(
165165
std::string_view fileName,
166166
Corpus const& corpus) const;
@@ -176,7 +176,7 @@ class MRDOCS_VISIBLE
176176
@param corpus The metadata to emit.
177177
*/
178178
MRDOCS_DECL
179-
Error
179+
Expected<void>
180180
buildOneString(
181181
std::string& dest,
182182
Corpus const& corpus) const;

include/mrdocs/Support/Error.hpp

+1-61
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class MRDOCS_DECL
7777
A default constructed error is
7878
equivalent to success.
7979
*/
80-
Error() noexcept = default;
80+
Error() noexcept = delete;
8181

8282
/** Constructor.
8383
*/
@@ -209,24 +209,6 @@ class MRDOCS_DECL
209209
*/
210210
[[noreturn]] void Throw() &&;
211211

212-
/** Throw Exception(*this), or do nothing if no failure.
213-
*/
214-
void maybeThrow() const&
215-
{
216-
if(! failed())
217-
return;
218-
Throw();
219-
}
220-
221-
/** Throw Exception(std::move(*this)), or do nothing if no failure.
222-
*/
223-
void maybeThrow() &&
224-
{
225-
if(! failed())
226-
return;
227-
Throw();
228-
}
229-
230212
constexpr
231213
void
232214
swap(Error& rhs) noexcept
@@ -244,10 +226,6 @@ class MRDOCS_DECL
244226
{
245227
lhs.swap(rhs);
246228
}
247-
248-
/** Return a value indicating success.
249-
*/
250-
static Error success() noexcept;
251229
};
252230

253231
//------------------------------------------------
@@ -1934,36 +1912,6 @@ class Expected<T, E>
19341912
: unex_(std::move(u).error()), has_value_(false)
19351913
{ }
19361914

1937-
// The following constructors are extensions that allow
1938-
// Expected to be constructed directly from an error type
1939-
// if this is not ambiguous with the value type. This
1940-
// is not part of std::expected. MRDOCS_EXPECTED_FROM_ERROR
1941-
// can be defined to disable this behavior.
1942-
#ifndef MRDOCS_EXPECTED_FROM_ERROR
1943-
template <class G = E>
1944-
requires
1945-
std::is_constructible_v<E, const G&> &&
1946-
(!std::is_constructible_v<T, const G&>)
1947-
constexpr
1948-
explicit(!std::is_convertible_v<const G&, E>)
1949-
Expected(const G& u)
1950-
noexcept(std::is_nothrow_constructible_v<E, const G&>)
1951-
: unex_(u)
1952-
, has_value_(false)
1953-
{ }
1954-
1955-
template <class G = E>
1956-
requires
1957-
std::is_constructible_v<E, G> &&
1958-
(!std::is_constructible_v<T, G>)
1959-
constexpr
1960-
explicit(!std::is_convertible_v<G, E>)
1961-
Expected(G&& u)
1962-
noexcept(std::is_nothrow_constructible_v<E, G>)
1963-
: unex_(std::move(u)), has_value_(false)
1964-
{ }
1965-
#endif
1966-
19671915
constexpr explicit
19681916
Expected(std::in_place_t) noexcept
19691917
: Expected()
@@ -2677,14 +2625,6 @@ struct FormatString
26772625
source_location loc;
26782626
};
26792627

2680-
inline
2681-
Error
2682-
Error::
2683-
success() noexcept
2684-
{
2685-
return Error();
2686-
}
2687-
26882628
/** Return a formatted error.
26892629
26902630
@param fs The format string. This

include/mrdocs/Support/Path.hpp

+18-48
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ namespace mrdocs {
2424
struct MRDOCS_VISIBLE
2525
AnyFileVisitor
2626
{
27-
virtual ~AnyFileVisitor() = 0;
28-
virtual Error visitFile(std::string_view fileName) = 0;
27+
virtual
28+
~AnyFileVisitor() = 0;
29+
30+
virtual
31+
Expected<void>
32+
visitFile(std::string_view fileName) = 0;
2933
};
3034

3135
/** Call a function for each file in a directory.
@@ -38,71 +42,37 @@ struct MRDOCS_VISIBLE
3842
also visited, recursively.
3943
*/
4044
MRDOCS_DECL
41-
Error
45+
Expected<void>
4246
forEachFile(
4347
std::string_view dirPath,
4448
bool recursive,
4549
AnyFileVisitor& visitor);
4650

4751
namespace detail {
4852
template <class Visitor>
49-
struct FileVisitor : AnyFileVisitor
53+
class FileVisitor : public AnyFileVisitor
5054
{
55+
using R = std::invoke_result_t<Visitor, std::string_view>;
56+
57+
public:
5158
Visitor& visitor_;
5259

5360
explicit FileVisitor(Visitor& v)
5461
: visitor_(v)
5562
{
5663
}
5764

58-
Error
65+
Expected<void>
5966
visitFile(std::string_view fileName) override
6067
{
61-
using R = std::invoke_result_t<Visitor, std::string_view>;
6268
if (std::same_as<R, void>)
6369
{
6470
visitor_(fileName);
65-
return Error::success();
66-
}
67-
else
68-
{
69-
return toError(visitor_(fileName));
70-
}
71-
}
72-
73-
static
74-
Error
75-
toError(Expected<void, Error> const& e)
76-
{
77-
return e ? Error::success() : e.error();
78-
}
79-
80-
template <class T>
81-
static
82-
Error
83-
toError(Expected<T, Error> const& e)
84-
{
85-
return e ? toError(e.value()) : e.error();
86-
}
87-
88-
template <class T>
89-
static
90-
Error
91-
toError(T const& e)
92-
{
93-
if constexpr (std::same_as<T, Error>)
94-
{
95-
return e;
96-
}
97-
else if constexpr (std::convertible_to<T, bool>)
98-
{
99-
if (e)
100-
return Error::success();
101-
return Error("visitor returned falsy");
71+
return {};
10272
}
10373
else
10474
{
105-
return Error::success();
75+
return visitor_(fileName);
10676
}
10777
}
10878
};
@@ -111,7 +81,7 @@ struct FileVisitor : AnyFileVisitor
11181
/** Visit each file in a directory.
11282
*/
11383
template<class Visitor>
114-
Error
84+
Expected<void>
11585
forEachFile(
11686
std::string_view dirPath,
11787
bool recursive,
@@ -154,7 +124,7 @@ isAbsolute(
154124
/** Return an error if pathName is not absolute.
155125
*/
156126
MRDOCS_DECL
157-
Error
127+
Expected<void>
158128
requireAbsolute(
159129
std::string_view pathName);
160130

@@ -320,7 +290,7 @@ appendPath(
320290
/** Return an error if the path is not a directory.
321291
*/
322292
MRDOCS_DECL
323-
Error
293+
Expected<void>
324294
requireDirectory(
325295
std::string_view pathName);
326296

@@ -354,7 +324,7 @@ getSourceFilename(
354324
to create.
355325
*/
356326
MRDOCS_DECL
357-
Error
327+
Expected<void>
358328
createDirectory(
359329
std::string_view pathName);
360330

src/lib/Gen/hbs/Builder.cpp

+22-17
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,18 @@ loadPartials(
3838
{
3939
return;
4040
}
41-
forEachFile(partialsPath, true,
42-
[&](std::string_view pathName) -> Error
41+
auto exp = forEachFile(partialsPath, true,
42+
[&](std::string_view pathName) -> Expected<void>
4343
{
4444
// Skip directories
45-
MRDOCS_CHECK_OR(!files::isDirectory(pathName), Error::success());
45+
MRDOCS_CHECK_OR(!files::isDirectory(pathName), {});
4646

4747
// Get template relative path
4848
std::filesystem::path relPath = pathName;
4949
relPath = relPath.lexically_relative(partialsPath);
5050

5151
// Skip non-handlebars files
52-
MRDOCS_CHECK_OR(relPath.extension() == ".hbs", Error::success());
52+
MRDOCS_CHECK_OR(relPath.extension() == ".hbs", {});
5353

5454
// Remove any file extensions
5555
while(relPath.has_extension())
@@ -58,13 +58,16 @@ loadPartials(
5858
}
5959

6060
// Load partial contents
61-
auto text = files::getFileText(pathName);
62-
MRDOCS_CHECK_OR(text, text.error());
61+
MRDOCS_TRY(std::string text, files::getFileText(pathName));
6362

6463
// Register partial
65-
hbs.registerPartial(relPath.generic_string(), *text);
66-
return Error::success();
67-
}).maybeThrow();
64+
hbs.registerPartial(relPath.generic_string(), text);
65+
return {};
66+
});
67+
if (!exp)
68+
{
69+
exp.error().Throw();
70+
}
6871
}
6972
}
7073

@@ -81,7 +84,7 @@ Builder(
8184

8285
// Load JavaScript helpers
8386
std::string helpersPath = templatesDir("helpers");
84-
forEachFile(helpersPath, true,
87+
auto exp = forEachFile(helpersPath, true,
8588
[&](std::string_view pathName)-> Expected<void>
8689
{
8790
// Register JS helper function in the global object
@@ -92,7 +95,11 @@ Builder(
9295
MRDOCS_TRY(auto script, files::getFileText(pathName));
9396
MRDOCS_TRY(js::registerHelper(hbs_, name, ctx_, script));
9497
return {};
95-
}).maybeThrow();
98+
});
99+
if (!exp)
100+
{
101+
exp.error().Throw();
102+
}
96103

97104
hbs_.registerHelper("primary_location",
98105
dom::makeInvocable([](dom::Value const& v) ->
@@ -260,19 +267,17 @@ operator()(OverloadSet const& OS)
260267

261268
Expected<void>
262269
Builder::
263-
renderWrapped(std::ostream& os, std::function<Error()> contentsCb)
270+
renderWrapped(
271+
std::ostream& os,
272+
std::function<Expected<void>()> contentsCb)
264273
{
265274
auto const wrapperFile = fmt::format(
266275
"wrapper.{}.hbs", domCorpus.fileExtension);
267276
dom::Object ctx;
268277
ctx.set("contents", dom::makeInvocable([&](
269278
dom::Value const& options) -> Expected<dom::Value>
270279
{
271-
Error e = contentsCb();
272-
if (e.failed())
273-
{
274-
return Unexpected(e);
275-
}
280+
MRDOCS_TRY(contentsCb());
276281
return {};
277282
}));
278283

src/lib/Gen/hbs/Builder.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ class Builder
7373
7474
*/
7575
Expected<void>
76-
renderWrapped(std::ostream& os, std::function<Error()> contentsCb);
76+
renderWrapped(
77+
std::ostream& os,
78+
std::function<Expected<void>()> contentsCb);
7779

7880
private:
7981
/** The directory with the all templates.

0 commit comments

Comments
 (0)