30 auto displayArg = [colorize, &os](
const Typedef& td,
const bool correct) {
33 fmt::dynamic_format_arg_store<fmt::format_context> store;
34 store.push_back(td.variadic ?
"variadic " :
"");
40 ? fmt::fg(fmt::color::green)
41 : fmt::fg(fmt::color::magenta)));
43 store.push_back(td.name);
44 store.push_back(arg_str);
46 fmt::vprint(os,
" -> {}{} ({})", store);
49 for (std::size_t i = 0, end = contract.
arguments.size(); i < end; ++i)
56 std::size_t bad_type = 0;
57 for (std::size_t j = i, args_end = args.size(); j < args_end; ++j)
65 displayArg(td,
false);
67 fmt::dynamic_format_arg_store<fmt::format_context> store;
69 store.push_back(fmt::styled(bad_type, fmt::fg(fmt::color::red)));
71 store.push_back(bad_type);
72 store.push_back(bad_type > 1 ?
"s" :
"");
74 fmt::vprint(os,
" {} argument{} do not match", store);
84 displayArg(td,
false);
85 const auto type =
types_to_str[
static_cast<std::size_t
>(args[i].valueType())];
87 fmt::dynamic_format_arg_store<fmt::format_context> store;
89 store.push_back(fmt::styled(type, fmt::fg(fmt::color::red)));
91 store.push_back(type);
92 fmt::vprint(os,
" was of type {}", store);
95 else if (i >= args.size())
97 displayArg(td,
false);
99 fmt::print(os,
"{}", fmt::styled(
" was not provided", fmt::fg(fmt::color::red)));
101 fmt::print(os,
" was not provided");
104 displayArg(td,
true);
106 fmt::print(os,
"\n");
110 void generateError(
const std::string_view& funcname,
const std::vector<Contract>& contracts,
const std::vector<Value>& args, std::ostream& os,
bool colorize)
113 fmt::dynamic_format_arg_store<fmt::format_context> store;
115 store.push_back(fmt::styled(funcname, fmt::fg(fmt::color::cyan)));
117 store.push_back(funcname);
118 fmt::vprint(os,
"Function {} expected ", store);
121 std::vector<Value> sanitizedArgs;
122 std::ranges::copy_if(args, std::back_inserter(sanitizedArgs), [](
const Value& value) ->
bool {
127 std::size_t min_argc = std::numeric_limits<std::size_t>::max(), max_argc = 0;
128 bool variadic =
false;
129 for (
const auto& [arguments] : contracts)
131 if (arguments.size() < min_argc)
132 min_argc = arguments.size();
133 if (arguments.size() > max_argc)
134 max_argc = arguments.size();
136 if (!arguments.empty() && arguments.back().variadic)
140 bool correct_argcount =
true;
142 if (min_argc != max_argc)
144 fmt::dynamic_format_arg_store<fmt::format_context> store;
146 store.push_back(fmt::styled(min_argc, fmt::fg(fmt::color::yellow)));
148 store.push_back(min_argc);
149 store.push_back(min_argc > 1 ?
"s" :
"");
151 store.push_back(fmt::styled(max_argc, fmt::fg(fmt::color::yellow)));
153 store.push_back(max_argc);
154 store.push_back(max_argc > 1 ?
"s" :
"");
156 fmt::vprint(os,
"between {} argument{} and {} argument{}", store);
158 if (sanitizedArgs.size() < min_argc || sanitizedArgs.size() > max_argc)
159 correct_argcount =
false;
163 fmt::dynamic_format_arg_store<fmt::format_context> store;
164 store.push_back(variadic ?
"at least " :
"");
166 store.push_back(fmt::styled(min_argc, fmt::fg(fmt::color::yellow)));
168 store.push_back(min_argc);
169 store.push_back(min_argc > 1 ?
"s" :
"");
171 fmt::vprint(os,
"{}{} argument{}", store);
173 if (sanitizedArgs.size() != min_argc)
174 correct_argcount =
false;
177 if (!correct_argcount || variadic)
179 std::string preposition = (variadic && args.size() >= min_argc) ?
"and" :
"but";
181 fmt::print(os,
" {} got {}", preposition, fmt::styled(sanitizedArgs.size(), fmt::fg(fmt::color::red)));
183 fmt::print(os,
" {} got {}", preposition, sanitizedArgs.size());
186 fmt::print(os,
"\n");
189 for (std::size_t i = 1, end = contracts.size(); i < end; ++i)
191 fmt::print(os,
"Alternative {}:\n", i + 1);
ARK_API void generateError(const std::string_view &funcname, const std::vector< Contract > &contracts, const std::vector< Value > &args, std::ostream &os=std::cout, bool colorize=true)
Generate an error message based on a given set of types contracts provided argument list.