Skip to content

Commit

Permalink
refactor(Error): error propagation uses Expected
Browse files Browse the repository at this point in the history
  • Loading branch information
alandefreitas committed Nov 21, 2024
1 parent c376277 commit 0b4d669
Show file tree
Hide file tree
Showing 23 changed files with 189 additions and 325 deletions.
10 changes: 5 additions & 5 deletions include/mrdocs/Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class MRDOCS_VISIBLE
*/
MRDOCS_DECL
virtual
Error
Expected<void>
build(
std::string_view outputPath,
Corpus const& corpus) const;
Expand All @@ -120,7 +120,7 @@ class MRDOCS_VISIBLE
the object before returning.
*/
MRDOCS_DECL
Error
Expected<void>
build(Corpus const& corpus) const;

/** Build reference documentation for the corpus.
Expand All @@ -141,7 +141,7 @@ class MRDOCS_VISIBLE
*/
MRDOCS_DECL
virtual
Error
Expected<void>
buildOne(
std::ostream& os,
Corpus const& corpus) const = 0;
Expand All @@ -160,7 +160,7 @@ class MRDOCS_VISIBLE
@param corpus The metadata to emit.
*/
MRDOCS_DECL
Error
Expected<void>
buildOne(
std::string_view fileName,
Corpus const& corpus) const;
Expand All @@ -176,7 +176,7 @@ class MRDOCS_VISIBLE
@param corpus The metadata to emit.
*/
MRDOCS_DECL
Error
Expected<void>
buildOneString(
std::string& dest,
Corpus const& corpus) const;
Expand Down
62 changes: 1 addition & 61 deletions include/mrdocs/Support/Error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class MRDOCS_DECL
A default constructed error is
equivalent to success.
*/
Error() noexcept = default;
Error() noexcept = delete;

/** Constructor.
*/
Expand Down Expand Up @@ -209,24 +209,6 @@ class MRDOCS_DECL
*/
[[noreturn]] void Throw() &&;

/** Throw Exception(*this), or do nothing if no failure.
*/
void maybeThrow() const&
{
if(! failed())
return;
Throw();
}

/** Throw Exception(std::move(*this)), or do nothing if no failure.
*/
void maybeThrow() &&
{
if(! failed())
return;
Throw();
}

constexpr
void
swap(Error& rhs) noexcept
Expand All @@ -244,10 +226,6 @@ class MRDOCS_DECL
{
lhs.swap(rhs);
}

/** Return a value indicating success.
*/
static Error success() noexcept;
};

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

// The following constructors are extensions that allow
// Expected to be constructed directly from an error type
// if this is not ambiguous with the value type. This
// is not part of std::expected. MRDOCS_EXPECTED_FROM_ERROR
// can be defined to disable this behavior.
#ifndef MRDOCS_EXPECTED_FROM_ERROR
template <class G = E>
requires
std::is_constructible_v<E, const G&> &&
(!std::is_constructible_v<T, const G&>)
constexpr
explicit(!std::is_convertible_v<const G&, E>)
Expected(const G& u)
noexcept(std::is_nothrow_constructible_v<E, const G&>)
: unex_(u)
, has_value_(false)
{ }

template <class G = E>
requires
std::is_constructible_v<E, G> &&
(!std::is_constructible_v<T, G>)
constexpr
explicit(!std::is_convertible_v<G, E>)
Expected(G&& u)
noexcept(std::is_nothrow_constructible_v<E, G>)
: unex_(std::move(u)), has_value_(false)
{ }
#endif

constexpr explicit
Expected(std::in_place_t) noexcept
: Expected()
Expand Down Expand Up @@ -2677,14 +2625,6 @@ struct FormatString
source_location loc;
};

inline
Error
Error::
success() noexcept
{
return Error();
}

/** Return a formatted error.
@param fs The format string. This
Expand Down
66 changes: 18 additions & 48 deletions include/mrdocs/Support/Path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ namespace mrdocs {
struct MRDOCS_VISIBLE
AnyFileVisitor
{
virtual ~AnyFileVisitor() = 0;
virtual Error visitFile(std::string_view fileName) = 0;
virtual
~AnyFileVisitor() = 0;

virtual
Expected<void>
visitFile(std::string_view fileName) = 0;
};

/** Call a function for each file in a directory.
Expand All @@ -38,71 +42,37 @@ struct MRDOCS_VISIBLE
also visited, recursively.
*/
MRDOCS_DECL
Error
Expected<void>
forEachFile(
std::string_view dirPath,
bool recursive,
AnyFileVisitor& visitor);

namespace detail {
template <class Visitor>
struct FileVisitor : AnyFileVisitor
class FileVisitor : public AnyFileVisitor
{
using R = std::invoke_result_t<Visitor, std::string_view>;

public:
Visitor& visitor_;

explicit FileVisitor(Visitor& v)
: visitor_(v)
{
}

Error
Expected<void>
visitFile(std::string_view fileName) override
{
using R = std::invoke_result_t<Visitor, std::string_view>;
if (std::same_as<R, void>)
{
visitor_(fileName);
return Error::success();
}
else
{
return toError(visitor_(fileName));
}
}

static
Error
toError(Expected<void, Error> const& e)
{
return e ? Error::success() : e.error();
}

template <class T>
static
Error
toError(Expected<T, Error> const& e)
{
return e ? toError(e.value()) : e.error();
}

template <class T>
static
Error
toError(T const& e)
{
if constexpr (std::same_as<T, Error>)
{
return e;
}
else if constexpr (std::convertible_to<T, bool>)
{
if (e)
return Error::success();
return Error("visitor returned falsy");
return {};
}
else
{
return Error::success();
return visitor_(fileName);
}
}
};
Expand All @@ -111,7 +81,7 @@ struct FileVisitor : AnyFileVisitor
/** Visit each file in a directory.
*/
template<class Visitor>
Error
Expected<void>
forEachFile(
std::string_view dirPath,
bool recursive,
Expand Down Expand Up @@ -154,7 +124,7 @@ isAbsolute(
/** Return an error if pathName is not absolute.
*/
MRDOCS_DECL
Error
Expected<void>
requireAbsolute(
std::string_view pathName);

Expand Down Expand Up @@ -320,7 +290,7 @@ appendPath(
/** Return an error if the path is not a directory.
*/
MRDOCS_DECL
Error
Expected<void>
requireDirectory(
std::string_view pathName);

Expand Down Expand Up @@ -354,7 +324,7 @@ getSourceFilename(
to create.
*/
MRDOCS_DECL
Error
Expected<void>
createDirectory(
std::string_view pathName);

Expand Down
39 changes: 22 additions & 17 deletions src/lib/Gen/hbs/Builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ loadPartials(
{
return;
}
forEachFile(partialsPath, true,
[&](std::string_view pathName) -> Error
auto exp = forEachFile(partialsPath, true,
[&](std::string_view pathName) -> Expected<void>
{
// Skip directories
MRDOCS_CHECK_OR(!files::isDirectory(pathName), Error::success());
MRDOCS_CHECK_OR(!files::isDirectory(pathName), {});

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

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

// Remove any file extensions
while(relPath.has_extension())
Expand All @@ -58,13 +58,16 @@ loadPartials(
}

// Load partial contents
auto text = files::getFileText(pathName);
MRDOCS_CHECK_OR(text, text.error());
MRDOCS_TRY(std::string text, files::getFileText(pathName));

// Register partial
hbs.registerPartial(relPath.generic_string(), *text);
return Error::success();
}).maybeThrow();
hbs.registerPartial(relPath.generic_string(), text);
return {};
});
if (!exp)
{
exp.error().Throw();
}
}
}

Expand All @@ -81,7 +84,7 @@ Builder(

// Load JavaScript helpers
std::string helpersPath = templatesDir("helpers");
forEachFile(helpersPath, true,
auto exp = forEachFile(helpersPath, true,
[&](std::string_view pathName)-> Expected<void>
{
// Register JS helper function in the global object
Expand All @@ -92,7 +95,11 @@ Builder(
MRDOCS_TRY(auto script, files::getFileText(pathName));
MRDOCS_TRY(js::registerHelper(hbs_, name, ctx_, script));
return {};
}).maybeThrow();
});
if (!exp)
{
exp.error().Throw();
}

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

Expected<void>
Builder::
renderWrapped(std::ostream& os, std::function<Error()> contentsCb)
renderWrapped(
std::ostream& os,
std::function<Expected<void>()> contentsCb)
{
auto const wrapperFile = fmt::format(
"wrapper.{}.hbs", domCorpus.fileExtension);
dom::Object ctx;
ctx.set("contents", dom::makeInvocable([&](
dom::Value const& options) -> Expected<dom::Value>
{
Error e = contentsCb();
if (e.failed())
{
return Unexpected(e);
}
MRDOCS_TRY(contentsCb());
return {};
}));

Expand Down
4 changes: 3 additions & 1 deletion src/lib/Gen/hbs/Builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ class Builder
*/
Expected<void>
renderWrapped(std::ostream& os, std::function<Error()> contentsCb);
renderWrapped(
std::ostream& os,
std::function<Expected<void>()> contentsCb);

private:
/** The directory with the all templates.
Expand Down
Loading

0 comments on commit 0b4d669

Please sign in to comment.