mu: support json output directly
Allow for dumping json directly from the Sexp structures, so we don't need any external libs (i.e. json-glib) anymore.
This commit is contained in:
@ -33,7 +33,7 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
|
||||
if (!call.is_call()) {
|
||||
throw Mu::Error{Error::Code::Command,
|
||||
"expected call-sexpr but got %s",
|
||||
call.to_string().c_str()};
|
||||
call.to_sexp_string().c_str()};
|
||||
}
|
||||
|
||||
const auto& params{call.list()};
|
||||
@ -41,7 +41,7 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
|
||||
if (cmd_it == cmap.end())
|
||||
throw Mu::Error{Error::Code::Command,
|
||||
"unknown command in call %s",
|
||||
call.to_string().c_str()};
|
||||
call.to_sexp_string().c_str()};
|
||||
|
||||
const auto& cinfo{cmd_it->second};
|
||||
|
||||
@ -67,7 +67,7 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
|
||||
if (arginfo.required)
|
||||
throw Mu::Error{Error::Code::Command,
|
||||
"missing required parameter %s in call %s",
|
||||
argname.c_str(), call.to_string().c_str()};
|
||||
argname.c_str(), call.to_sexp_string().c_str()};
|
||||
continue; // not required
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
|
||||
"parameter %s expects type %s, but got %s in call %s",
|
||||
argname.c_str(), to_string(arginfo.type).c_str(),
|
||||
to_string(param_it->type()).c_str(),
|
||||
call.to_string().c_str()};
|
||||
call.to_sexp_string().c_str()};
|
||||
}
|
||||
|
||||
// all passed parameters must be known
|
||||
@ -87,7 +87,7 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
|
||||
[&](auto&& arg) {return params.at(i).value() == arg.first;}))
|
||||
throw Mu::Error{Error::Code::Command,
|
||||
"unknown parameter %s in call %s",
|
||||
params.at(i).value().c_str(), call.to_string().c_str()};
|
||||
params.at(i).value().c_str(), call.to_sexp_string().c_str()};
|
||||
}
|
||||
|
||||
if (cinfo.handler)
|
||||
|
||||
@ -179,7 +179,7 @@ Sexp::make_parse (const std::string& expr)
|
||||
|
||||
|
||||
std::string
|
||||
Sexp::to_string () const
|
||||
Sexp::to_sexp_string () const
|
||||
{
|
||||
std::stringstream sstrm;
|
||||
|
||||
@ -188,7 +188,7 @@ Sexp::to_string () const
|
||||
sstrm << '(';
|
||||
bool first{true};
|
||||
for (auto&& child : list()) {
|
||||
sstrm << (first ? "" : " ") << child.to_string();
|
||||
sstrm << (first ? "" : " ") << child.to_sexp_string();
|
||||
first = false;
|
||||
}
|
||||
sstrm << ')';
|
||||
@ -206,3 +206,55 @@ Sexp::to_string () const
|
||||
|
||||
return sstrm.str();
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Sexp::to_json_string () const
|
||||
{
|
||||
std::stringstream sstrm;
|
||||
|
||||
switch (type()) {
|
||||
case Type::List: {
|
||||
// property-lists become JSON objects
|
||||
if (is_prop_list()) {
|
||||
sstrm << "{";
|
||||
auto it{list().begin()};
|
||||
bool first{true};
|
||||
while (it != list().end()) {
|
||||
sstrm << (first?"":",") << quote(it->value()) << ":";
|
||||
++it;
|
||||
sstrm << it->to_json_string();
|
||||
++it;
|
||||
first = false;
|
||||
}
|
||||
sstrm << "}";
|
||||
} else { // other lists become arrays.
|
||||
sstrm << '[';
|
||||
bool first{true};
|
||||
for (auto&& child : list()) {
|
||||
sstrm << (first ? "" : ", ") << child.to_json_string();
|
||||
first = false;
|
||||
}
|
||||
sstrm << ']';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::String:
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
case Type::Symbol:
|
||||
if (is_nil())
|
||||
sstrm << "false";
|
||||
else if (is_t())
|
||||
sstrm << "true";
|
||||
else
|
||||
sstrm << quote(value());
|
||||
break;
|
||||
case Type::Number:
|
||||
case Type::Empty:
|
||||
default:
|
||||
sstrm << value();
|
||||
}
|
||||
|
||||
return sstrm.str();
|
||||
}
|
||||
|
||||
@ -104,11 +104,19 @@ struct Sexp {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Sexp::Node to its string representation
|
||||
* Convert a Sexp::Node to its S-expression string representation
|
||||
*
|
||||
* @return the string representation
|
||||
*/
|
||||
std::string to_string() const;
|
||||
std::string to_sexp_string() const;
|
||||
|
||||
|
||||
/**
|
||||
* Convert a Sexp::Node to its JSON string representation
|
||||
*
|
||||
* @return the string representation
|
||||
*/
|
||||
std::string to_json_string() const;
|
||||
|
||||
/**
|
||||
* Return the type of this Node.
|
||||
@ -341,7 +349,7 @@ operator<<(std::ostream& os, Sexp::Type id)
|
||||
static inline std::ostream&
|
||||
operator<<(std::ostream& os, const Sexp& sexp)
|
||||
{
|
||||
os << sexp.to_string();
|
||||
os << sexp.to_sexp_string();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -63,17 +63,17 @@ test_list()
|
||||
const auto nstr{Sexp::make_string("foo")};
|
||||
g_assert_true(nstr.value() == "foo");
|
||||
g_assert_true(nstr.type() == Sexp::Type::String);
|
||||
assert_equal(nstr.to_string(), "\"foo\"");
|
||||
assert_equal(nstr.to_sexp_string(), "\"foo\"");
|
||||
|
||||
const auto nnum{Sexp::make_number(123)};
|
||||
g_assert_true(nnum.value() == "123");
|
||||
g_assert_true(nnum.type() == Sexp::Type::Number);
|
||||
assert_equal(nnum.to_string(), "123");
|
||||
assert_equal(nnum.to_sexp_string(), "123");
|
||||
|
||||
const auto nsym{Sexp::make_symbol("blub")};
|
||||
g_assert_true(nsym.value() == "blub");
|
||||
g_assert_true(nsym.type() == Sexp::Type::Symbol);
|
||||
assert_equal(nsym.to_string(), "blub");
|
||||
assert_equal(nsym.to_sexp_string(), "blub");
|
||||
|
||||
Sexp::List list;
|
||||
list .add(Sexp::make_string("foo"))
|
||||
@ -85,7 +85,7 @@ test_list()
|
||||
g_assert_true(nlst.type() == Sexp::Type::List);
|
||||
g_assert_true(nlst.list().at(1).value() == "123");
|
||||
|
||||
assert_equal(nlst.to_string(),"(\"foo\" 123 blub)");
|
||||
assert_equal(nlst.to_sexp_string(),"(\"foo\" 123 blub)");
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ test_prop_list()
|
||||
Sexp::List l1;
|
||||
l1.add_prop(":foo", Sexp::make_string("bar"));
|
||||
Sexp s2{Sexp::make_list(std::move(l1))};
|
||||
assert_equal(s2.to_string(), "(:foo \"bar\")");
|
||||
assert_equal(s2.to_sexp_string(), "(:foo \"bar\")");
|
||||
|
||||
|
||||
Sexp::List l2;
|
||||
@ -105,7 +105,7 @@ test_prop_list()
|
||||
Sexp::List l3;
|
||||
l3.add_prop(":cuux", Sexp::make_list(std::move(l2)));
|
||||
Sexp s3{Sexp::make_list(std::move(l3))};
|
||||
assert_equal(s3.to_string(), "(:cuux (:foo \"bar\" :bar 77))");
|
||||
assert_equal(s3.to_sexp_string(), "(:cuux (:foo \"bar\" :bar 77))");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -122,7 +122,7 @@ test_props()
|
||||
":flub", Sexp::make_symbol("fnord"),
|
||||
":boo", std::move(sexp2));
|
||||
|
||||
assert_equal(sexp.to_string(),
|
||||
assert_equal(sexp.to_sexp_string(),
|
||||
"(:foo \"b\303\244r\" :cuux 123 :flub fnord :boo (\"foo\" 123 blub))");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user