yourWaifu / sleepy-discord

C++ library for the Discord chat client. Please use Rust for new bots
https://yourWaifu.github.io/sleepy-discord/
MIT License
707 stars 92 forks source link

[C++17] Slash command endpoints and std::variant based ApplicationCommand Option/Choice #198

Closed MacDue closed 3 years ago

MacDue commented 3 years ago

Implementation of some slash command endpoints and std::varaint based Option/Choice.

Added endpoints:

I had to go with std::variant as storing a rapidjson::Value directly on a structure does not work. You need to use a rapidjson::Document and use CopyFrom within the copy ctor of Option or whatever (you can't copy rapdjson::Values around). I did try doing that but it's such a pain, and I could not get it working properly (kept getting linker errors).

I used std::variant instead; it can be copied and moved like normal. It's also pretty nice to work with:


std::string& string_val = std::get<std::string>(option.value); // get a string value

if (auto string_val = std::get_if<std::string>(&option.value)) { // get if the value is a string
  std::cout << *string_val << '\n';
}

// or more there's also stuff like std::holds_alternative<type>() and std::visit

The variants for slash commands only need to handle simple types (ints, bools, float, string) no objects or arrays. So I made a very simple SimpleVariantHelper that can parse (simple) JSON values into variants.

The isType stuff is not used & I think the code is added is fairly understandable.

This does all require C++17 but I don't really see why the library should limit it's self to a C++ version which is now a decade old!

MacDue commented 3 years ago

I've not deleted the isType() functions but they're currently unused.

MacDue commented 3 years ago

Note I'm using the JSON_SIMPLE_VARIANT_FIELD macro to generate the parser helper and the field.

JSON_SIMPLE_VARIANT_FIELD(value, int, std::string)

expands to

std::variant<int, std::string> value;
struct SimpleVariantHelper_value: public json::SimpleVariantHelper<int, std::string> {}

which can then be used in the json::pair<SimpleVariantHelper_value>

There might be a nicer way to do this (but I couldn't get another method working).

MacDue commented 3 years ago

Oh. I'll have to delete createFollowupFileUpload from this PR since that uses SleepyDiscord::Buffer which is still not merged.