variadic args for hint format

This commit is contained in:
Ben Burdette 2020-04-03 08:48:20 -06:00
parent c6b3fcddb0
commit 7b7801d3f0
3 changed files with 30 additions and 16 deletions

View file

@ -7,6 +7,7 @@
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include "types.hh"
#include <boost/format.hpp> #include <boost/format.hpp>
namespace nix namespace nix
@ -234,7 +235,7 @@ protected:
// ---------------------------------------------------------------- // ----------------------------------------------------------------
// format for hints. same as boost format, except templated values // format for hints. same as fmt, except templated values
// are always in yellow. // are always in yellow.
template <class T> template <class T>
@ -251,20 +252,25 @@ std::ostream& operator<<(std::ostream &out, const yellowify<T> &y)
return out << ANSI_YELLOW << y.value << ANSI_NORMAL; return out << ANSI_YELLOW << y.value << ANSI_NORMAL;
} }
class hintfmt class hintformat
{ {
public: public:
hintfmt(string format) :fmt(format) hintformat(string format) :fmt(format)
{ {
fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit); fmt.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
} }
template<class T> template<class T>
hintfmt& operator%(const T &value) hintformat& operator%(const T &value)
{ {
fmt % yellowify(value); fmt % yellowify(value);
return *this; return *this;
} }
std::string str() const
{
return fmt.str();
}
template <typename U> template <typename U>
friend class AddHint; friend class AddHint;
private: private:
@ -272,14 +278,22 @@ private:
}; };
template<typename... Args>
inline hintformat hintfmt(const std::string & fs, const Args & ... args)
{
hintformat f(fs);
formatHelper(f, args...);
return f;
}
// the template layer for adding a hint. // the template layer for adding a hint.
template <class T> template <class T>
class AddHint : private T class AddHint : private T
{ {
public: public:
T& hint(hintfmt &hfmt) T& hint(const hintformat &hf)
{ {
GetEI().hint = std::optional(hfmt.fmt.str()); GetEI().hint = std::optional(hf.str());
return *this; return *this;
} }
T& nohint() T& nohint()

View file

@ -41,7 +41,8 @@ struct FormatOrString
{ {
string s; string s;
FormatOrString(const string & s) : s(s) { }; FormatOrString(const string & s) : s(s) { };
FormatOrString(const format & f) : s(f.str()) { }; template<class F>
FormatOrString(const F & f) : s(f.str()) { };
FormatOrString(const char * s) : s(s) { }; FormatOrString(const char * s) : s(s) { };
}; };
@ -51,12 +52,13 @@ struct FormatOrString
... a_n. However, fmt(s) is equivalent to s (so no %-expansion ... a_n. However, fmt(s) is equivalent to s (so no %-expansion
takes place). */ takes place). */
inline void formatHelper(boost::format & f) template<class F>
inline void formatHelper(F & f)
{ {
} }
template<typename T, typename... Args> template<class F, typename T, typename... Args>
inline void formatHelper(boost::format & f, const T & x, const Args & ... args) inline void formatHelper(F & f, const T & x, const Args & ... args)
{ {
formatHelper(f % x, args...); formatHelper(f % x, args...);
} }

View file

@ -33,8 +33,8 @@ int main()
printErrorInfo( ProgramWarning() printErrorInfo( ProgramWarning()
.name("warning name") .name("warning name")
.description("warning description") .description("warning description")
.hint(hintfmt("there was a %1%") % // the templated value, 'warning', is automatically colored yellow.
"warning") // 'warning' will be yellow. .hint(hintfmt("there was a %1%", "warning"))
); );
/* /*
@ -67,8 +67,7 @@ int main()
.linesOfCode(std::nullopt, .linesOfCode(std::nullopt,
"this is the problem line of code", "this is the problem line of code",
std::nullopt) std::nullopt)
.hint(hintfmt("this hint has %1% templated %2%!!") % .hint(hintfmt("this hint has %1% templated %2%!!", "yellow" , "values")));
"yellow" % "values"));
// NixLangError is just the same as NixLangWarning, except for the Error // NixLangError is just the same as NixLangWarning, except for the Error
// flag. // flag.
@ -81,8 +80,7 @@ int main()
.linesOfCode(std::optional("previous line of code"), .linesOfCode(std::optional("previous line of code"),
"this is the problem line of code", "this is the problem line of code",
std::optional("next line of code")) std::optional("next line of code"))
.hint(hintfmt("this hint has %1% templated %2%!!") % .hint(hintfmt("this hint has %1% templated %2%!!", "yellow", "values")));
"yellow" % "values"));
return 0; return 0;
} }