33#include < limits>
44#include < algorithm>
55#include < fmt/core.h>
6+ #include < fmt/args.h>
67#include < fmt/color.h>
8+ #include < fmt/ostream.h>
79
810#include < Ark/Exceptions.hpp>
911
@@ -25,20 +27,25 @@ namespace Ark::types
2527 return acc;
2628 }
2729
28- void displayContract (const Contract& contract, const std::vector<Value>& args)
30+ void displayContract (const Contract& contract, const std::vector<Value>& args, std::ostream& os, const bool colorize )
2931 {
30- auto displayArg = [](const Typedef& td, bool correct) {
32+ auto displayArg = [](const Typedef& td, const bool correct, std::ostream& os, const bool colorize ) {
3133 const std::string arg_str = typeListToString (td.types );
3234
33- fmt::print (
34- " -> {}{} ({}) " ,
35- td.variadic ? " variadic " : " " ,
36- fmt::styled (
37- td.name ,
38- correct
39- ? fmt::fg (fmt::color::green)
40- : fmt::fg (fmt::color::magenta)),
41- arg_str);
35+ fmt::dynamic_format_arg_store<fmt::format_context> store;
36+ store.push_back (td.variadic ? " variadic " : " " );
37+ if (colorize)
38+ store.push_back (
39+ fmt::styled (
40+ td.name ,
41+ correct
42+ ? fmt::fg (fmt::color::green)
43+ : fmt::fg (fmt::color::magenta)));
44+ else
45+ store.push_back (td.name );
46+ store.push_back (arg_str);
47+
48+ fmt::vprint (os, " -> {}{} ({})" , store);
4249 };
4350
4451 for (std::size_t i = 0 , end = contract.arguments .size (); i < end; ++i)
@@ -57,36 +64,61 @@ namespace Ark::types
5764
5865 if (bad_type)
5966 {
60- displayArg (td, false );
61- fmt::print (" {} argument{} do not match" , fmt::styled (bad_type, fmt::fg (fmt::color::red)), bad_type > 1 ? " s" : " " );
67+ displayArg (td, false , os, colorize);
68+
69+ fmt::dynamic_format_arg_store<fmt::format_context> store;
70+ if (colorize)
71+ store.push_back (fmt::styled (bad_type, fmt::fg (fmt::color::red)));
72+ else
73+ store.push_back (bad_type);
74+ store.push_back (bad_type > 1 ? " s" : " " );
75+
76+ fmt::vprint (os, " {} argument{} do not match" , store);
6277 }
6378 else
64- displayArg (td, true );
79+ displayArg (td, true , os, colorize );
6580 }
6681 else
6782 {
6883 // provided argument but wrong type
6984 if (i < args.size () && td.types [0 ] != ValueType::Any && std::ranges::find (td.types , args[i].valueType ()) == td.types .end ())
7085 {
71- displayArg (td, false );
72- fmt::print (" was of type {}" , fmt::styled (types_to_str[static_cast <std::size_t >(args[i].valueType ())], fmt::fg (fmt::color::red)));
86+ displayArg (td, false , os, colorize);
87+ const auto type = types_to_str[static_cast <std::size_t >(args[i].valueType ())];
88+
89+ fmt::dynamic_format_arg_store<fmt::format_context> store;
90+ if (colorize)
91+ store.push_back (fmt::styled (type, fmt::fg (fmt::color::red)));
92+ else
93+ store.push_back (type);
94+ fmt::vprint (os, " was of type {}" , store);
7395 }
7496 // non-provided argument
7597 else if (i >= args.size ())
7698 {
77- displayArg (td, false );
78- fmt::print (fmt::fg (fmt::color::red), " was not provided" );
99+ displayArg (td, false , os, colorize);
100+ if (colorize)
101+ fmt::print (os, " {}" , fmt::styled (" was not provided" , fmt::fg (fmt::color::red)));
102+ else
103+ fmt::print (os, " was not provided" );
79104 }
80105 else
81- displayArg (td, true );
106+ displayArg (td, true , os, colorize );
82107 }
83- fmt::print (" \n " );
108+ fmt::print (os, " \n " );
84109 }
85110 }
86111
87- [[noreturn]] void generateError (const std::string_view& funcname, const std::vector<Contract>& contracts, const std::vector<Value>& args)
112+ [[noreturn]] void generateError (const std::string_view& funcname, const std::vector<Contract>& contracts, const std::vector<Value>& args, std::ostream& os, bool colorize )
88113 {
89- fmt::print (" Function {} expected " , fmt::styled (funcname, fmt::fg (fmt::color::blue)));
114+ {
115+ fmt::dynamic_format_arg_store<fmt::format_context> store;
116+ if (colorize)
117+ store.push_back (fmt::styled (funcname, fmt::fg (fmt::color::blue)));
118+ else
119+ store.push_back (funcname);
120+ fmt::vprint (os, " Function {} expected " , store);
121+ }
90122
91123 std::vector<Value> sanitizedArgs;
92124 std::ranges::copy_if (args, std::back_inserter (sanitizedArgs), [](const Value& value) -> bool {
@@ -107,34 +139,53 @@ namespace Ark::types
107139
108140 if (min_argc != max_argc)
109141 {
110- fmt::print (
111- " between {} argument{} and {} argument{}" ,
112- fmt::styled (min_argc, fmt::fg (fmt::color::yellow)),
113- min_argc > 1 ? " s" : " " ,
114- fmt::styled (max_argc, fmt::fg (fmt::color::yellow)),
115- max_argc > 1 ? " s" : " " );
142+ fmt::dynamic_format_arg_store<fmt::format_context> store;
143+ if (colorize)
144+ store.push_back (fmt::styled (min_argc, fmt::fg (fmt::color::yellow)));
145+ else
146+ store.push_back (min_argc);
147+ store.push_back (min_argc > 1 ? " s" : " " );
148+ if (colorize)
149+ store.push_back (fmt::styled (max_argc, fmt::fg (fmt::color::yellow)));
150+ else
151+ store.push_back (max_argc);
152+ store.push_back (max_argc > 1 ? " s" : " " );
153+
154+ fmt::vprint (os, " between {} argument{} and {} argument{}" , store);
116155
117156 if (sanitizedArgs.size () < min_argc || sanitizedArgs.size () > max_argc)
118157 correct_argcount = false ;
119158 }
120159 else
121160 {
122- fmt::print (" {} argument{}" , fmt::styled (min_argc, fmt::fg (fmt::color::yellow)), min_argc > 1 ? " s" : " " );
161+ fmt::dynamic_format_arg_store<fmt::format_context> store;
162+ if (colorize)
163+ store.push_back (fmt::styled (min_argc, fmt::fg (fmt::color::yellow)));
164+ else
165+ store.push_back (min_argc);
166+ store.push_back (min_argc > 1 ? " s" : " " );
167+
168+ fmt::vprint (os, " {} argument{}" , store);
123169
124170 if (sanitizedArgs.size () != min_argc)
125171 correct_argcount = false ;
126172 }
127173
128174 if (!correct_argcount)
129- fmt::print (" but got {}" , fmt::styled (sanitizedArgs.size (), fmt::fg (fmt::color::red)));
175+ {
176+ if (colorize)
177+ fmt::print (os, " but got {}" , fmt::styled (sanitizedArgs.size (), fmt::fg (fmt::color::red)));
178+ else
179+ fmt::print (os, " but got {}" , sanitizedArgs.size ());
180+ }
130181
131- fmt::print (" \n " );
182+ fmt::print (os, " \n " );
132183
133- displayContract (contracts[0 ], sanitizedArgs);
184+ displayContract (contracts[0 ], sanitizedArgs, os, colorize );
134185 for (std::size_t i = 1 , end = contracts.size (); i < end; ++i)
135186 {
136- std::cout << " Alternative " << ( i + 1 ) << " : \n " ;
137- displayContract (contracts[i], sanitizedArgs);
187+ fmt::print (os, " Alternative {}: \n " , i + 1 );
188+ displayContract (contracts[i], sanitizedArgs, os, colorize );
138189 }
139190
140191 throw TypeError (" " );
0 commit comments