Skip to content

Instantly share code, notes, and snippets.

@etscrivner
Last active October 5, 2018 04:12
Show Gist options
  • Save etscrivner/ffac70de141c7b29441a3156fe1271d6 to your computer and use it in GitHub Desktop.
Save etscrivner/ffac70de141c7b29441a3156fe1271d6 to your computer and use it in GitHub Desktop.
Bitcoin RPC API documentation helper object prototype.
#include <iostream>
#include <string>
#include <vector>
class RPCArgument {
public:
RPCArgument(const std::string& name,
const std::string& type,
const std::string& description,
bool required=false,
const std::string& default_value="")
: m_name(name),
m_type(type),
m_description(description),
m_required(required),
m_default(default_value)
{
if(m_type == "string")
{
m_positional_name = "\"" + m_name + "\"";
}
else
{
m_positional_name = m_name;
}
}
const std::string& Name() const
{
return m_name;
}
const std::string& PositionalName() const
{
return m_positional_name;
}
const std::string& Type() const
{
return m_type;
}
const std::string& Description() const
{
return m_description;
}
const std::string& Default() const
{
return m_default;
}
bool HasDefault() const
{
return m_default != "";
}
bool IsRequired() const
{
return m_required;
}
private:
std::string m_name;
std::string m_type;
std::string m_description;
bool m_required;
std::string m_default;
std::string m_positional_name;
};
class RPCDocumentation {
public:
RPCDocumentation(std::string method_name)
: m_method_name(method_name)
{ }
RPCDocumentation& DescriptionLine(const std::string& description_line)
{
m_description.push_back(description_line);
return *this;
}
RPCDocumentation& Argument(const std::string& name,
const std::string& type,
const std::string& description,
bool required=false,
const std::string& default_value="")
{
m_arguments.push_back(
RPCArgument(name, type, description, required, default_value)
);
return *this;
}
std::string write()
{
std::string result;
// Add the method name
result += m_method_name;
// Add any argument names after the method name
if(!m_arguments.empty())
{
bool in_optional_brackets = false;
for(auto argument : m_arguments)
{
result += " ";
// Everything after the first optional argument is optional
if(!argument.IsRequired() || in_optional_brackets)
{
if(!in_optional_brackets)
{
result += "( ";
in_optional_brackets = true;
}
}
result += argument.PositionalName();
}
if(in_optional_brackets)
{
result += " )";
}
}
// Now print each description line
for(auto description_line : m_description)
{
result += "\n" + description_line + "\n";
}
// Add the argument details list if there are any
if(!m_arguments.empty())
{
result += "\nArguments:\n";
for(unsigned int i = 0; i < m_arguments.size(); ++i)
{
result += std::to_string(i + 1) + ". ";
result += m_arguments[i].Name() + " ";
result += "(" + m_arguments[i].Type();
if(!m_arguments[i].IsRequired())
{
result += ", optional";
}
if(m_arguments[i].HasDefault())
{
result += ", default=" + m_arguments[i].Default();
}
result += ") " + m_arguments[i].Description() + "\n";
}
}
return result;
}
private:
std::string m_method_name;
std::vector<std::string> m_description;
std::vector<RPCArgument> m_arguments;
};
int main(int argc, char* argv[])
{
auto docs = RPCDocumentation("getrawmempool")
.DescriptionLine("Returns all transaction ids in memory pool as a json array of string transaction ids.")
.DescriptionLine("Hint: use getmempoolentry to fetch a specific transaction from the mempool.")
.Argument("first", "integer", "The first argument is required", true)
.Argument("verbose", "boolean", "True for json object, false for array of transaction ids", false, "false")
.Argument("other", "string", "Another argument");
std::cout << docs.write();
/*
getrawmempool first ( verbose "other" )
Returns all transaction ids in memory pool as a json array of string transaction ids.
Hint: use getmempoolentry to fetch a specific transaction from the mempool.
Arguments:
1. first (integer) The first argument is required
2. verbose (boolean, optional, default=false) True for json object, false for array of transaction ids
3. other (string, optional) Another argument
*/
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment