6#ifndef GIMO_ALGORITHM_TRANSFORM_ERROR_HPP
7#define GIMO_ALGORITHM_TRANSFORM_ERROR_HPP
20namespace gimo::detail::transform_error
22 template <
typename Expected,
typename Action>
23 consteval Expected* print_diagnostics()
25 if constexpr (!expected_like<Expected>)
27 static_assert(always_false_v<Expected>,
"The transform_error algorithm requires an expected-like input.");
29 else if constexpr (!std::is_invocable_v<Action, error_result_t<Expected>>)
31 static_assert(always_false_v<Expected>,
"The transform_error algorithm requires an action invocable with the expected's error.");
33 else if constexpr (!rebindable_error_to<Expected, std::invoke_result_t<Action, error_result_t<Expected>>>)
35 static_assert(always_false_v<Expected>,
"The transform_error algorithm requires an expected-like whose error-type can be rebound.");
41 template <
typename Expected,
typename Action>
44 std::invoke_result_t<Action, error_result_t<Expected>>>;
46 template <
typename Action, expected_like Expected>
48 constexpr result_t<Expected, Action> on_value([[maybe_unused]] Action&& action, Expected&& closure)
50 return detail::rebind_value<result_t<Expected, Action>, Expected>(closure);
53 template <
typename Action, expected_like Expected,
typename Next,
typename... Steps>
55 constexpr auto on_value(
61 return std::forward<Next>(next).on_value(
62 transform_error::on_value(std::forward<Action>(action), std::forward<Expected>(closure)),
63 std::forward<Steps>(steps)...);
66 template <
typename Action, expected_like Expected>
68 constexpr result_t<Expected, Action> on_null(Action&& action, Expected&& closure)
70 return detail::construct_from_error<result_t<Expected, Action>>(
72 std::forward<Action>(action),
73 detail::forward_error<Expected>(closure)));
76 template <
typename Action, expected_like Expected,
typename Next,
typename... Steps>
78 constexpr auto on_null(Action&& action, Expected&& closure, Next&& next, Steps&&... steps)
80 return std::forward<Next>(next).on_null(
81 transform_error::on_null(std::forward<Action>(action), std::forward<Expected>(closure)),
82 std::forward<Steps>(steps)...);
87 template <nullable Expected,
typename Action>
88 static constexpr bool is_applicable_on =
requires {
89 requires rebindable_error_to<
91 std::invoke_result_t<Action, error_result_t<Expected>>>;
94 template <
typename Action, nullable Expected,
typename... Steps>
96 static constexpr auto on_value(Action&& action, Expected&& closure, Steps&&... steps)
98 if constexpr (is_applicable_on<Expected, Action>)
100 return transform_error::on_value(
101 std::forward<Action>(action),
102 std::forward<Expected>(closure),
103 std::forward<Steps>(steps)...);
107 return *transform_error::print_diagnostics<Expected, Action>();
111 template <
typename Action, nullable Expected,
typename... Steps>
113 static constexpr auto on_null(Action&& action, Expected&& closure, Steps&&... steps)
115 if constexpr (is_applicable_on<Expected, Action>)
117 return transform_error::on_null(
118 std::forward<Action>(action),
119 std::forward<Expected>(closure),
120 std::forward<Steps>(steps)...);
124 return *transform_error::print_diagnostics<Expected, Action>();
134 template <
typename Action>
135 using transform_error_t = BasicAlgorithm<transform_error::traits, std::remove_cvref_t<Action>>;
157 template <
typename Action>
161 using Algorithm = detail::transform_error_t<Action>;
163 return Pipeline{std::tuple<Algorithm>{std::forward<Action>(action)}};
A composite object representing a sequence of monadic operations.
Definition Pipeline.hpp:30
constexpr auto transform_error(Action &&action)
Creates a pipeline step that transforms the error of an expected-like type.
Definition TransformError.hpp:159
Definition AndThen.hpp:21
typename traits< std::remove_cvref_t< Expected > >::template rebind_error< std::remove_cvref_t< Error > > rebind_error_t
Helper alias to obtain the Expected type with the rebound Error type.
Definition Common.hpp:416